aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitaly Novichkov <admin@wohlnet.ru>2018-06-19 15:04:50 +0300
committerVitaly Novichkov <admin@wohlnet.ru>2018-06-19 15:04:50 +0300
commitc0873278718da57ff19194377a35601027926c5f (patch)
tree6fca461d067a1e615788cecf7a74c175f0033fc8
parent5a194eb263125e5505cca3ec0256c7efa348eaa4 (diff)
parent1026ecd3fd8dc865fb3a85ab4a130d9d1b494fd9 (diff)
downloadlibADLMIDI-c0873278718da57ff19194377a35601027926c5f.tar.gz
libADLMIDI-c0873278718da57ff19194377a35601027926c5f.tar.bz2
libADLMIDI-c0873278718da57ff19194377a35601027926c5f.zip
Merge branch 'master' into stable
-rw-r--r--.appveyor.yml106
-rw-r--r--CMakeLists.txt168
-rw-r--r--README.md43
-rw-r--r--fm_banks/adldata-cache.datbin556119 -> 576392 bytes
-rw-r--r--fm_banks/wopl_files/Apogee-IMF-90.woplbin16983 -> 16983 bytes
-rw-r--r--fm_banks/wopl_files/DMXOPL3-by-sneakernets-GS.woplbin118767 -> 118767 bytes
-rw-r--r--fm_banks/wopl_files/GM-By-J.A.Nguyen-and-Wohlstand.woplbin16983 -> 16983 bytes
-rw-r--r--include/adlmidi.h119
-rw-r--r--include/adlmidi.hpp21
-rw-r--r--libADLMIDI-test.pro2
-rw-r--r--libADLMIDI.pro55
-rw-r--r--projects/watcom/ADLMIDI-linux32.tgt475
-rw-r--r--projects/watcom/ADLMIDI-win32.tgt475
-rw-r--r--projects/watcom/ADLMIDI.tgt228
-rw-r--r--projects/watcom/libADLMIDI-linux32.wpj63
-rw-r--r--projects/watcom/libADLMIDI-win32.wpj63
-rw-r--r--projects/watcom/libADLMIDI.wpj20
-rw-r--r--projects/watcom/playmidi-debug-crashful.zipbin0 -> 243283 bytes
-rw-r--r--projects/watcom/playmidi-linux32.tgt322
-rw-r--r--projects/watcom/playmidi-win32.tgt306
-rw-r--r--projects/watcom/playmidi.tgt180
-rw-r--r--projects/watcom/pmidid32.tgt322
-rw-r--r--src/adldata.cpp10237
-rw-r--r--src/adldata.hh58
-rw-r--r--src/adlmidi.cpp191
-rw-r--r--src/adlmidi_bankmap.h127
-rw-r--r--src/adlmidi_bankmap.tcc283
-rw-r--r--src/adlmidi_load.cpp211
-rw-r--r--src/adlmidi_midiplay.cpp506
-rw-r--r--src/adlmidi_mus2mid.c2
-rw-r--r--src/adlmidi_opl3.cpp117
-rw-r--r--src/adlmidi_private.cpp64
-rw-r--r--src/adlmidi_private.hpp274
-rw-r--r--src/adlmidi_ptr.hpp217
-rw-r--r--src/chips/dosbox/dbopl.cpp3561
-rw-r--r--src/chips/dosbox/dbopl.h517
-rw-r--r--src/chips/dosbox_opl3.cpp90
-rw-r--r--src/chips/dosbox_opl3.h21
-rw-r--r--src/chips/nuked/nukedopl3.c176
-rw-r--r--src/chips/nuked/nukedopl3.h2
-rw-r--r--src/chips/nuked/nukedopl3_174.c206
-rw-r--r--src/chips/nuked/nukedopl3_174.h2
-rw-r--r--src/chips/nuked_opl3.cpp62
-rw-r--r--src/chips/nuked_opl3.h21
-rw-r--r--src/chips/nuked_opl3_v174.cpp62
-rw-r--r--src/chips/nuked_opl3_v174.h21
-rw-r--r--src/chips/opl_chip_base.cpp52
-rw-r--r--src/chips/opl_chip_base.h81
-rw-r--r--src/chips/opl_chip_base.tcc216
-rw-r--r--src/fraction.hpp9
-rw-r--r--src/wopl/wopl_file.h8
-rw-r--r--test/CMakeLists.txt7
-rw-r--r--test/bankmap/CMakeLists.txt12
-rw-r--r--test/bankmap/bank_map.cpp100
-rw-r--r--test/common/catch.hpp13050
-rw-r--r--test/common/catch_main.cpp2
-rw-r--r--utils/adlmidi-2/9x15.hpp10
-rw-r--r--utils/adlmidi-2/midiplay.cc3
-rw-r--r--utils/adlmidi-2/puzzlegame.cc2
-rwxr-xr-xutils/adlmidi-2/puzzlegame.hpp2
-rw-r--r--utils/dumpbank/dumpbank.cpp7
-rw-r--r--utils/dumpmiles/dumpmiles.cpp9
-rw-r--r--utils/gen_adldata/file_formats/load_ail.h1
-rw-r--r--utils/gen_adldata/file_formats/load_bisqwit.h1
-rw-r--r--utils/gen_adldata/file_formats/load_bnk.h4
-rw-r--r--utils/gen_adldata/file_formats/load_bnk2.h10
-rw-r--r--utils/gen_adldata/file_formats/load_ea.h5
-rw-r--r--utils/gen_adldata/file_formats/load_ibk.h1
-rw-r--r--utils/gen_adldata/file_formats/load_jv.h1
-rw-r--r--utils/gen_adldata/file_formats/load_op2.h3
-rw-r--r--utils/gen_adldata/file_formats/load_tmb.h1
-rw-r--r--utils/gen_adldata/file_formats/load_wopl.h9
-rw-r--r--utils/gen_adldata/gen_adldata.cc43
-rw-r--r--utils/gen_adldata/ini/ini_processing.cpp45
-rw-r--r--utils/gen_adldata/ini/ini_processing.h44
-rw-r--r--utils/gen_adldata/ini/ini_processing_variant.h50
-rw-r--r--utils/gen_adldata/measurer.cpp480
-rw-r--r--utils/gen_adldata/measurer.h3
-rw-r--r--utils/gen_adldata/progs_cache.cpp2
-rw-r--r--utils/gen_adldata/progs_cache.h4
-rw-r--r--utils/midiplay/adlmidiplay.cpp5
-rw-r--r--utils/vlc_codec/libadlmidi.c189
82 files changed, 25464 insertions, 9003 deletions
diff --git a/.appveyor.yml b/.appveyor.yml
new file mode 100644
index 0000000..490755b
--- /dev/null
+++ b/.appveyor.yml
@@ -0,0 +1,106 @@
+version: 1.3.{build}
+
+environment:
+ global:
+ PLATFORMTOOLSET: "v140"
+ matrix:
+ - BUILD_TYPE: Debug
+ COMPILER: MinGW
+ COMPILER_FAMILY: MinGW
+ GENERATOR: "MinGW Makefiles"
+ PLATFORM: Win32
+ - BUILD_TYPE: Release
+ COMPILER: MinGW
+ COMPILER_FAMILY: MinGW
+ GENERATOR: "MinGW Makefiles"
+ PLATFORM: Win32
+ - BUILD_TYPE: Debug
+ COMPILER: MinGW-w64
+ COMPILER_FAMILY: MinGW
+ GENERATOR: "MinGW Makefiles"
+ PLATFORM: x64
+ - BUILD_TYPE: Release
+ COMPILER: MinGW-w64
+ COMPILER_FAMILY: MinGW
+ GENERATOR: "MinGW Makefiles"
+ PLATFORM: x64
+ - BUILD_TYPE: Debug
+ COMPILER: MSVC15
+ COMPILER_FAMILY: MSVC
+ GENERATOR: "Visual Studio 14 2015 Win64"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
+ PLATFORM: x64
+ PLATFORMTOOLSET: "v140_xp"
+ - BUILD_TYPE: Release
+ COMPILER: MSVC15
+ COMPILER_FAMILY: MSVC
+ GENERATOR: "Visual Studio 14 2015 Win64"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
+ PLATFORM: x64
+ PLATFORMTOOLSET: "v140_xp"
+ - BUILD_TYPE: Debug
+ COMPILER: MSVC15
+ COMPILER_FAMILY: MSVC
+ GENERATOR: "Visual Studio 14 2015"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
+ PLATFORM: Win32
+ PLATFORMTOOLSET: "v140_xp"
+ - BUILD_TYPE: Release
+ COMPILER: MSVC15
+ COMPILER_FAMILY: MSVC
+ GENERATOR: "Visual Studio 14 2015"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
+ PLATFORM: Win32
+ PLATFORMTOOLSET: "v140_xp"
+ - BUILD_TYPE: Debug
+ COMPILER: MSVC17
+ COMPILER_FAMILY: MSVC
+ GENERATOR: "Visual Studio 15 2017 Win64"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017"
+ PLATFORM: x64
+ PLATFORMTOOLSET: "v141_xp"
+ - BUILD_TYPE: Release
+ COMPILER: MSVC17
+ COMPILER_FAMILY: MSVC
+ GENERATOR: "Visual Studio 15 2017 Win64"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017"
+ PLATFORM: x64
+ PLATFORMTOOLSET: "v141_xp"
+ - BUILD_TYPE: Debug
+ COMPILER: MSVC17
+ COMPILER_FAMILY: MSVC
+ GENERATOR: "Visual Studio 15 2017"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017"
+ PLATFORM: Win32
+ PLATFORMTOOLSET: "v141_xp"
+ - BUILD_TYPE: Release
+ COMPILER: MSVC17
+ COMPILER_FAMILY: MSVC
+ GENERATOR: "Visual Studio 15 2017"
+ APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017"
+ PLATFORM: Win32
+ PLATFORMTOOLSET: "v141_xp"
+
+build_script:
+ - md build-%COMPILER%-%BUILD_TYPE%-%PLATFORM%
+ - cd build-%COMPILER%-%BUILD_TYPE%-%PLATFORM%
+ - if [%COMPILER%]==[MinGW] set PATH=C:\MinGW\bin;%PATH:C:\Program Files\Git\usr\bin;=%
+ - if [%COMPILER%]==[MinGW-w32] set PATH=C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32\bin;%PATH:C:\Program Files\Git\usr\bin;=%
+ - if [%COMPILER%]==[MinGW-w64] set PATH=C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin;%PATH:C:\Program Files\Git\usr\bin;=%
+ - cmake -G "%GENERATOR%" -DCMAKE_BUILD_TYPE=%BUILD_TYPE% -DCMAKE_PREFIX_PATH=. -DCMAKE_INSTALL_PREFIX=libADLMIDI -DWITH_OLD_UTILS=ON -DWITH_GENADLDATA=OFF -DlibADLMIDI_STATIC=ON -DlibADLMIDI_SHARED=ON ..
+ - if [%COMPILER_FAMILY%]==[MinGW] cmake --build . --config %BUILD_TYPE% -- -j 2
+ - if [%COMPILER_FAMILY%]==[MinGW] mingw32-make install
+ - if [%COMPILER_FAMILY%]==[MSVC] cmake --build . --config %BUILD_TYPE% --target install
+ - 7z a -t7z -mx9 "libADLMIDI-%COMPILER%-%BUILD_TYPE%-%PLATFORM%.7z" "libADLMIDI"
+ - move libADLMIDI-%COMPILER%-%BUILD_TYPE%-%PLATFORM%.7z ..
+
+artifacts:
+ - path: 'libADLMIDI-$(COMPILER)-$(BUILD_TYPE)-$(PLATFORM).7z'
+
+deploy:
+ - provider: Environment
+ name: WohlnetFTP
+
+#on_finish:
+# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
index bda3e0b..c26d5ee 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,5 +1,5 @@
cmake_minimum_required (VERSION 3.2)
-project (libADLMIDI)
+project (libADLMIDI C CXX)
#===========================================================================================
# Strip garbage
@@ -11,13 +11,21 @@ ELSEIF(NOT MSVC AND NOT MSDOS)
set(LINK_FLAGS_RELEASE "${LINK_FLAGS_RELEASE} -Wl,--gc-sections -Wl,-s")
ENDIF()
-# Global optimization flags
IF(NOT MSVC AND NOT MSDOS)
+# Global optimization flags
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fno-omit-frame-pointer")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-omit-frame-pointer")
+# Turn on all warnings
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
ENDIF()
-if (CMAKE_BUILD_TYPE EQUAL "RELEASE")
+if(NOT CMAKE_BUILD_TYPE)
+ set(CMAKE_BUILD_TYPE "Release")
+endif()
+
+string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_LOWER)
+if(CMAKE_BUILD_TYPE_LOWER EQUAL "release")
add_definitions(-DNDEBUG)
ENDIF()
@@ -45,7 +53,7 @@ function(set_legacy_standard destTarget)
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
# Turn on warnings and legacy C/C++ standards to support more compilers
target_compile_options(${destTarget} PRIVATE
- $<$<COMPILE_LANGUAGE:C>:-Wall -pedantic -std=c90>
+ $<$<COMPILE_LANGUAGE:C>:-Wall -pedantic -std=c90 -Wno-long-long>
$<$<COMPILE_LANGUAGE:CXX>:-Wall -pedantic -std=gnu++98>
)
endif()
@@ -53,26 +61,29 @@ function(set_legacy_standard destTarget)
endfunction()
#===========================================================================================
-option(WITH_MIDIPLAY "Build also demo MIDI player" OFF)
-option(MIDIPLAY_WAVE_ONLY "Build Demo MIDI player without support of real time playing. It will output into WAV only." OFF)
-option(WITH_ADLMIDI2 "Build also classic ADLMIDI player [EXPERIMENTAL]" OFF)
-option(WITH_VLC_PLUGIN "Build also a plugin for VLC Media Player" OFF)
-option(WITH_OLD_UTILS "Build also old utilities" OFF)
-option(WITH_EMBEDDED_BANKS "Use embedded banks" ON)
-option(WITH_GENADLDATA "Build and run full rebuild of embedded banks cache" OFF)
-option(WITH_GENADLDATA_COMMENTS "Enable comments in generated ADLDATA cache file" OFF)
-option(USE_DOSBOX_EMULATOR "Use DosBox 0.74 OPL3 emulator (semi-accurate, suggested for slow or mobile platforms)" ON)
-option(USE_NUKED_EMULATOR "Use Nuked OPL3 emulator (most accurate, powerful)" ON)
+option(libADLMIDI_STATIC "Build static library of libADLMIDI" ON)
+option(libADLMIDI_SHARED "Build shared library of libADLMIDI" OFF)
+
option(WITH_CPP_EXTRAS "Build with support for C++ extras (features are can be found in 'adlmidi.hpp' header)" OFF)
option(WITH_MIDI_SEQUENCER "Build with embedded MIDI sequencer. Disable this if you want use library in real-time MIDI drivers or plugins.)" ON)
+option(WITH_EMBEDDED_BANKS "Use embedded banks" ON)
+option(WITH_HQ_RESAMPLER "Build with support for high quality resampling" OFF)
option(WITH_MUS_SUPPORT "Build with support for DMX MUS files)" ON)
option(WITH_XMI_SUPPORT "Build with support for AIL XMI files)" ON)
+option(USE_DOSBOX_EMULATOR "Use DosBox 0.74 OPL3 emulator (semi-accurate, suggested for slow or mobile platforms)" ON)
+option(USE_NUKED_EMULATOR "Use Nuked OPL3 emulator (most accurate, powerful)" ON)
-option(libADLMIDI_STATIC "Build static library of libADLMIDI" ON)
-option(libADLMIDI_SHARED "Build shared library of libADLMIDI" OFF)
+option(WITH_GENADLDATA "Build and run full rebuild of embedded banks cache" OFF)
+option(WITH_GENADLDATA_COMMENTS "Enable comments in generated ADLDATA cache file" OFF)
+option(WITH_MIDIPLAY "Build also demo MIDI player" OFF)
+option(MIDIPLAY_WAVE_ONLY "Build Demo MIDI player without support of real time playing. It will output into WAV only." OFF)
+option(WITH_ADLMIDI2 "Build also classic ADLMIDI player [EXPERIMENTAL]" OFF)
+option(WITH_VLC_PLUGIN "Build also a plugin for VLC Media Player" OFF)
+option(WITH_OLD_UTILS "Build also old utilities" OFF)
option(EXAMPLE_SDL2_AUDIO "Build also a simple SDL2 demo MIDI player" OFF)
+
if(CMAKE_VERSION VERSION_EQUAL "3.1" OR CMAKE_VERSION VERSION_GREATER "3.1")
set(CMAKE_CXX_STANDARD 11)
endif()
@@ -97,6 +108,14 @@ if(WITH_OLD_UTILS)
list(APPEND libADLMIDI_INSTALLS adldumpmiles)
endif()
+if(WITH_ADLMIDI2 OR (WITH_EMBEDDED_BANKS AND WITH_GENADLDATA))
+ find_package(OpenMP)
+endif()
+
+if(WITH_HQ_RESAMPLER)
+ find_library(ZITA_RESAMPLER_LIBRARY "zita-resampler" REQUIRED)
+endif()
+
if(WITH_EMBEDDED_BANKS)
if(WITH_GENADLDATA)
set(GEN_ADLDATA_SRC)
@@ -107,10 +126,6 @@ if(WITH_EMBEDDED_BANKS)
${libADLMIDI_SOURCE_DIR}/utils/gen_adldata/ini/ini_processing.cpp
)
- list(APPEND GEN_ADLDATA_SRC
- ${libADLMIDI_SOURCE_DIR}/src/chips/opl_chip_base.cpp
- )
-
if(USE_DOSBOX_EMULATOR)
set(HAS_EMULATOR TRUE)
list(APPEND GEN_ADLDATA_SRC
@@ -139,12 +154,20 @@ if(WITH_EMBEDDED_BANKS)
if(NOT MSVC)
target_link_libraries(gen_adldata pthread m stdc++)
endif()
- if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR
- CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR
- "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
- if(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 3.2)
- message("Turned on C++11 on GCC/CLang/Intel")
- target_compile_options(gen_adldata PUBLIC $<$<COMPILE_LANGUAGE:CXX>:-std=c++11>)
+ if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR
+ "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR
+ "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel" OR
+ "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MinGW" OR
+ CMAKE_COMPILER_IS_MINGW)
+ if(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} VERSION_GREATER 3.2)
+ message("Turned on C++11 on GCC/CLang/Intel/MinGW")
+ set_target_properties(gen_adldata PROPERTIES
+ CXX_STANDARD 11
+ CXX_STANDARD_REQUIRED YES)
+ if(OPENMP_FOUND)
+ target_compile_options(gen_adldata PUBLIC "-fopenmp")
+ target_link_libraries(gen_adldata "-fopenmp")
+ endif()
endif()
else(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
message("Turned on C++11 on MSVC")
@@ -155,12 +178,16 @@ if(WITH_EMBEDDED_BANKS)
target_compile_options(gen_adldata PUBLIC "-DADLDATA_WITH_COMMENTS")
endif()
- add_custom_target(
- gen-adldata-run
- COMMAND gen_adldata ${libADLMIDI_SOURCE_DIR}/src/adldata.cpp
+ set(ADLDATA_DATABASE
+ "${libADLMIDI_SOURCE_DIR}/src/adldata.cpp"
+ )
+ add_custom_target(gen-adldata-run #OUTPUT ${ADLDATA_DATABASE}
+ COMMAND gen_adldata "${ADLDATA_DATABASE}"
WORKING_DIRECTORY ${libADLMIDI_SOURCE_DIR}
+ DEPENDS gen_adldata "${libADLMIDI_SOURCE_DIR}/banks.ini"
+ COMMENT "Running Embedded FM banks database generation"
+ VERBATIM
)
- add_dependencies(gen-adldata-run gen_adldata)
endif()
endif()
@@ -193,10 +220,6 @@ else()
endif()
if(NOT DJGPP AND NOT MSDOS)
- list(APPEND libADLMIDI_SOURCES
- ${libADLMIDI_SOURCE_DIR}/src/chips/opl_chip_base.cpp
- )
-
if(USE_DOSBOX_EMULATOR)
set(HAS_EMULATOR TRUE)
list(APPEND libADLMIDI_SOURCES
@@ -269,9 +292,9 @@ endif()
add_library(ADLMIDI INTERFACE)
if(libADLMIDI_SHARED)
- target_link_libraries(ADLMIDI INTERFACE ADLMIDI_shared)
+ target_link_libraries(ADLMIDI INTERFACE ADLMIDI_shared)
else()
- target_link_libraries(ADLMIDI INTERFACE ADLMIDI_static)
+ target_link_libraries(ADLMIDI INTERFACE ADLMIDI_static)
endif()
if(WITH_MIDIPLAY)
@@ -342,6 +365,7 @@ if(WITH_ADLMIDI2)
set(ADLMIDI2_VIDEO_OUT_SUPPORT "TRUE")
endif()
+
set(adlmidi2_src)
list(APPEND adlmidi2_src
${libADLMIDI_SOURCE_DIR}/utils/adlmidi-2/midiplay.cc
@@ -354,11 +378,11 @@ if(WITH_ADLMIDI2)
add_executable(adlmidi2 ${adlmidi2_src})
if(ADLMIDI2_HAS_PUZZLE_GAME)
- target_compile_options(adlmidi2 PUBLIC "-DSUPPORT_PUZZLE_GAME")
+ target_compile_definitions(adlmidi2 PUBLIC "-DSUPPORT_PUZZLE_GAME")
endif()
if(ADLMIDI2_VIDEO_OUT_SUPPORT)
- target_compile_options(adlmidi2 PUBLIC "-DSUPPORT_VIDEO_OUTPUT")
+ target_compile_definitions(adlmidi2 PUBLIC "-DSUPPORT_VIDEO_OUTPUT")
endif()
if(WIN32)
@@ -373,12 +397,20 @@ if(WITH_ADLMIDI2)
message(FATAL_ERROR "ADLMIDI2 Requires C++ Extras. Please enable WITH_CPP_EXTRAS option!")
endif()
- if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR
- CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR
- "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
- if(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 3.2)
+ if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR
+ "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR
+ "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel" OR
+ "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MinGW" OR
+ CMAKE_COMPILER_IS_MINGW)
+ if(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} VERSION_GREATER 3.2)
message("Turned on C++11 on GCC/CLang/Intel")
- target_compile_options(adlmidi2 PUBLIC $<$<COMPILE_LANGUAGE:CXX>:-std=c++11>)
+ set_target_properties(adlmidi2 PROPERTIES
+ CXX_STANDARD 11
+ CXX_STANDARD_REQUIRED YES)
+ endif()
+ if(OPENMP_FOUND)
+ target_compile_options(adlmidi2 PUBLIC "-fopenmp")
+ target_link_libraries(adlmidi2 "-fopenmp")
endif()
else(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
message("Turned on C++11 on MSVC")
@@ -388,7 +420,7 @@ if(WITH_ADLMIDI2)
if(libADLMIDI_SHARED)
add_dependencies(adlmidi2 ADLMIDI_shared)
# ========= WIP =========
- # set_target_properties(adlmidiplay PROPERTIES COMPILE_FLAGS "-Wl,-rpath='$$ORIGIN/../lib'")
+ set_target_properties(adlmidi2 PROPERTIES COMPILE_FLAGS "-Wl,-rpath='$$ORIGIN/../lib'")
else()
if(NOT libADLMIDI_STATIC)
message(FATAL_ERROR "libADLMIDI is required to be built!")
@@ -469,6 +501,17 @@ if(WITH_VLC_PLUGIN)
endif()
+if(WITH_HQ_RESAMPLER)
+ if(libADLMIDI_SHARED)
+ target_compile_definitions(ADLMIDI_shared PRIVATE -DADLMIDI_ENABLE_HQ_RESAMPLER)
+ target_link_libraries(ADLMIDI_shared PUBLIC "${ZITA_RESAMPLER_LIBRARY}")
+ endif()
+ if(libADLMIDI_STATIC)
+ target_compile_definitions(ADLMIDI_static PRIVATE -DADLMIDI_ENABLE_HQ_RESAMPLER)
+ target_link_libraries(ADLMIDI_static PUBLIC "${ZITA_RESAMPLER_LIBRARY}")
+ endif()
+endif()
+
install(TARGETS ${libADLMIDI_INSTALLS}
RUNTIME DESTINATION "bin"
LIBRARY DESTINATION "lib"
@@ -480,22 +523,33 @@ install(FILES
include/adlmidi.hpp
DESTINATION include/)
+option(WITH_UNIT_TESTS "Enable unit testing" OFF)
+if(WITH_UNIT_TESTS)
+ enable_testing()
+ add_subdirectory(test)
+endif()
+
message("==== libADLMIDI options ====")
+message("libADLMIDI_STATIC = ${libADLMIDI_STATIC}")
+message("libADLMIDI_SHARED = ${libADLMIDI_SHARED}")
+message("WITH_UNIT_TESTS = ${WITH_UNIT_TESTS}")
+
+message("WITH_CPP_EXTRAS = ${WITH_CPP_EXTRAS}")
+message("WITH_MIDI_SEQUENCER = ${WITH_MIDI_SEQUENCER}")
+message("WITH_EMBEDDED_BANKS = ${WITH_EMBEDDED_BANKS}")
+message("WITH_HQ_RESAMPLER = ${WITH_HQ_RESAMPLER}")
+message("WITH_MUS_SUPPORT = ${WITH_MUS_SUPPORT}")
+message("WITH_XMI_SUPPORT = ${WITH_XMI_SUPPORT}")
+message("USE_DOSBOX_EMULATOR = ${USE_DOSBOX_EMULATOR}")
+message("USE_NUKED_EMULATOR = ${USE_NUKED_EMULATOR}")
+
+message("===== Utils and extras =====")
+message("WITH_GENADLDATA = ${WITH_GENADLDATA}")
+message("WITH_GENADLDATA_COMMENTS = ${WITH_GENADLDATA_COMMENTS}")
+
message("WITH_MIDIPLAY = ${WITH_MIDIPLAY}")
-message("WITH_VLC_PLUGIN = ${WITH_VLC_PLUGIN}")
message("MIDIPLAY_WAVE_ONLY = ${MIDIPLAY_WAVE_ONLY}")
message("WITH_ADLMIDI2 = ${WITH_ADLMIDI2}")
+message("WITH_VLC_PLUGIN = ${WITH_VLC_PLUGIN}")
message("WITH_OLD_UTILS = ${WITH_OLD_UTILS}")
-message("WITH_EMBEDDED_BANKS = ${WITH_EMBEDDED_BANKS}")
-message("WITH_GENADLDATA = ${WITH_GENADLDATA}")
-message("WITH_GENADLDATA_COMMENTS = ${WITH_GENADLDATA_COMMENTS}")
-message("USE_DOSBOX_EMULATOR = ${USE_DOSBOX_EMULATOR}")
-message("USE_NUKED_EMULATOR = ${USE_NUKED_EMULATOR}")
-message("WITH_MIDI_SEQUENCER = ${WITH_MIDI_SEQUENCER}")
-message("WITH_CPP_EXTRAS = ${WITH_CPP_EXTRAS}")
-message("WITH_MUS_SUPPORT = ${WITH_MUS_SUPPORT}")
-message("WITH_XMI_SUPPORT = ${WITH_XMI_SUPPORT}")
-message("libADLMIDI_STATIC = ${libADLMIDI_STATIC}")
-message("libADLMIDI_SHARED = ${libADLMIDI_SHARED}")
message("EXAMPLE_SDL2_AUDIO = ${EXAMPLE_SDL2_AUDIO}")
-
diff --git a/README.md b/README.md
index 9fdfd22..c2953d9 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,8 @@ Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 e
[http://iki.fi/bisqwit/source/adlmidi.html](http://iki.fi/bisqwit/source/adlmidi.html)
-[![Build Status](https://semaphoreci.com/api/v1/wohlstand/libadlmidi/branches/master/badge.svg)](https://semaphoreci.com/wohlstand/libadlmidi)
+* Semaphore-CI: [![Build Status](https://semaphoreci.com/api/v1/wohlstand/libadlmidi/branches/master/shields_badge.svg)](https://semaphoreci.com/wohlstand/libadlmidi)
+* AppVeyor CI: [![Build status](https://ci.appveyor.com/api/projects/status/bfhwdsm13s17rn49?svg=true)](https://ci.appveyor.com/project/Wohlstand/libadlmidi)
# Differences with original tool
* Reverb code has been removed.
@@ -56,20 +57,35 @@ sudo make install
## Available CMake options
+
+### Library options
* **CMAKE_PREFIX_PATH** - destinition folder where libADLMIDI will be installed. On Linux it is /usr/local/ by default.
* **CMAKE_BUILD_TYPE** - Build types: **Debug** or **Release**
-* **WITH_MIDIPLAY** - (ON/OFF, default OFF) Build demo MIDI player (Requires SDL2 and also pthread on Windows with MinGW)
-* **WITH_VLC_PLUGIN** - (ON/OFF, default OFF) Compile VLC plugin. For now, works on Linux and VLC version 2.2.2. Support for newer VLC versions and other platforms comming soon!
-* **WITH_ADLMIDI2** - (ON/OFF, default OFF) Build Classic ADLMIDI MIDI player (Requires SDL2 on Linux and macOS, requires pthread on Windows with MinGW, SDL doesn't required on Windows. Also, the **WITH_CPP_EXTRAS** flag must be enabled)
+
+* **libADLMIDI_STATIC** - (ON/OFF, default ON) Build static library
+* **libADLMIDI_SHARED** - (ON/OFF, default OFF) Build shared library
+* **WITH_UNIT_TESTS** - (ON/OFF, default OFF) Enable unit testing
+
* **WITH_CPP_EXTRAS** - (ON/OFF, default OFF) Build libADLMIDI with some extra public features for C++ language (for example, instrument testing API is available for C++ only).
-* **WITH_OLD_UTILS** - (ON/OFF, default OFF) Build old utilities to dump some bank formats, made by original creator of ADLMIDI
+* **WITH_MIDI_SEQUENCER** - (ON/OFF, default ON) Build with embedded MIDI sequencer. Disable this if you want use library in real-time MIDI drivers or plugins.)
* **WITH_EMBEDDED_BANKS** - (ON/OFF, default ON) Enable or disable embedded banks (Original ADLMIDI and older versions of libADLMIDI are had embedded-only banks with no ability to load custom banks in runtime).
-* **WITH_GENADLDATA** - (ON/OFF, default OFF) Build and execute the utility which will rebuild the embedded banks database (which is an adldata.cpp file).
+* **WITH_HQ_RESAMPLER** - (ON/OFF, default OFF) Build with support for high quality resampling (requires zita-resampler to be installed)
+* **WITH_MUS_SUPPORT** - (ON/OFF, default ON) Build with support for DMX MUS files)
+* **WITH_XMI_SUPPORT** - (ON/OFF, default ON) Build with support for AIL XMI files)
* **USE_DOSBOX_EMULATOR** - (ON/OFF, default ON) Enable support for DosBox 0.74 emulator. (Well-accurate and fast)
* **USE_NUKED_EMULATOR** - (ON/OFF, default ON) Enable support for Nuked OPL3 emulator. (Very-accurate, needs more CPU power)
-* **libADLMIDI_STATIC** - (ON/OFF, default ON) Build static library
-* **libADLMIDI_SHARED** - (ON/OFF, default OFF) Build shared library
+
+### Utils and extras
+* **WITH_GENADLDATA** - (ON/OFF, default OFF) Build and execute the utility which will rebuild the embedded banks database (which is an adldata.cpp file).
+* **WITH_GENADLDATA_COMMENTS** - (ON/OFF, default OFF) Enable comments in generated ADLDATA cache file
+
+* **WITH_MIDIPLAY** - (ON/OFF, default OFF) Build demo MIDI player (Requires SDL2 and also pthread on Windows with MinGW)
+* **MIDIPLAY_WAVE_ONLY** - (ON/OFF, default OFF) Build Demo MIDI player without support of real time playing. It will output into WAV only.
+* **WITH_ADLMIDI2** - (ON/OFF, default OFF) Build Classic ADLMIDI MIDI player (Requires SDL2 on Linux and macOS, requires pthread on Windows with MinGW, SDL doesn't required on Windows. Also, the **WITH_CPP_EXTRAS** flag must be enabled)
+* **WITH_VLC_PLUGIN** - (ON/OFF, default OFF) Compile VLC plugin. For now, works on Linux and VLC. Support for other platforms comming soon!
+* **WITH_OLD_UTILS** - (ON/OFF, default OFF) Build old utilities to dump some bank formats, made by original creator of ADLMIDI
+* **EXAMPLE_SDL2_AUDIO** - (ON/OFF, default OFF) Build also a simple SDL2 demo MIDI player
## You also can build library manually:
@@ -135,6 +151,17 @@ To build that example you will need to have installed SDL2 library.
* Add support of MIDI Format 2 files (FL Studio made MIDI-files are wired and opening of those files making lossy of tempo and some meta-information events)
# Changelog
+## 1.3.3 2018-06-19
+ * Fixed an inability to load another custom bank without of library re-initialization
+ * Optimizing the MIDI banks management system for MultiBanks (Thanks to [Jean Pierre Cimalando](https://github.com/jpcima) for a work!)
+ * Fixed incorrect 4-op counter which is still catch 4-op instruments on 2-op banks
+ * Fixed an incorrect processing of auto-flags
+ * Fixed incorrect initial MIDI tempo when MIDI file doesn't includes the tempo event
+ * Channel and Note Aftertouch features are now supported correctly! Aftertouch is the tremolo / vibrato, NOT A VOLUME!
+ * Updated DosBox OPL3 emulator up to r4111 of official DosBox trunk (Thanks to [Jean Pierre Cimalando](https://github.com/jpcima) for a work!)
+ * The automatical choosing of 4 operator channels count has been improved (Thanks to [Jean Pierre Cimalando](https://github.com/jpcima) for a work!)
+ * Added optional HQ resampler for Nuked OPL3 emulators which does usage of Zita-Resampler library (Thanks to [Jean Pierre Cimalando](https://github.com/jpcima) for a work!)
+
## 1.3.2 2018-04-24
* Added ability to disable MUS and XMI converters
* Added ability to disable embedded MIDI sequencer to use library as RealTime synthesizer only or use any custom MIDI sequencer plugins.
diff --git a/fm_banks/adldata-cache.dat b/fm_banks/adldata-cache.dat
index bee5302..53f19dc 100644
--- a/fm_banks/adldata-cache.dat
+++ b/fm_banks/adldata-cache.dat
Binary files differ
diff --git a/fm_banks/wopl_files/Apogee-IMF-90.wopl b/fm_banks/wopl_files/Apogee-IMF-90.wopl
index 1a808b2..89b8c77 100644
--- a/fm_banks/wopl_files/Apogee-IMF-90.wopl
+++ b/fm_banks/wopl_files/Apogee-IMF-90.wopl
Binary files differ
diff --git a/fm_banks/wopl_files/DMXOPL3-by-sneakernets-GS.wopl b/fm_banks/wopl_files/DMXOPL3-by-sneakernets-GS.wopl
index 58362a5..957f950 100644
--- a/fm_banks/wopl_files/DMXOPL3-by-sneakernets-GS.wopl
+++ b/fm_banks/wopl_files/DMXOPL3-by-sneakernets-GS.wopl
Binary files differ
diff --git a/fm_banks/wopl_files/GM-By-J.A.Nguyen-and-Wohlstand.wopl b/fm_banks/wopl_files/GM-By-J.A.Nguyen-and-Wohlstand.wopl
index 6ec13ea..5512a07 100644
--- a/fm_banks/wopl_files/GM-By-J.A.Nguyen-and-Wohlstand.wopl
+++ b/fm_banks/wopl_files/GM-By-J.A.Nguyen-and-Wohlstand.wopl
Binary files differ
diff --git a/include/adlmidi.h b/include/adlmidi.h
index 56626bb..c64f55c 100644
--- a/include/adlmidi.h
+++ b/include/adlmidi.h
@@ -30,7 +30,7 @@ extern "C" {
#define ADLMIDI_VERSION_MAJOR 1
#define ADLMIDI_VERSION_MINOR 3
-#define ADLMIDI_VERSION_PATCHLEVEL 2
+#define ADLMIDI_VERSION_PATCHLEVEL 3
#define ADLMIDI_TOSTR_I(s) #s
#define ADLMIDI_TOSTR(s) ADLMIDI_TOSTR_I(s)
@@ -58,11 +58,12 @@ typedef short ADL_SInt16;
enum ADLMIDI_VolumeModels
{
ADLMIDI_VolumeModel_AUTO = 0,
- ADLMIDI_VolumeModel_Generic,
- ADLMIDI_VolumeModel_CMF,
- ADLMIDI_VolumeModel_DMX,
- ADLMIDI_VolumeModel_APOGEE,
- ADLMIDI_VolumeModel_9X
+ ADLMIDI_VolumeModel_Generic = 1,
+ ADLMIDI_VolumeModel_NativeOPL3 = 2,
+ ADLMIDI_VolumeModel_CMF = ADLMIDI_VolumeModel_NativeOPL3,
+ ADLMIDI_VolumeModel_DMX = 3,
+ ADLMIDI_VolumeModel_APOGEE = 4,
+ ADLMIDI_VolumeModel_9X = 5
};
enum ADLMIDI_SampleType
@@ -110,6 +111,46 @@ extern int adl_getBanksCount();
/* Returns pointer to array of names of every bank */
extern const char *const *adl_getBankNames();
+/* Reference to dynamic bank */
+typedef struct ADL_Bank
+{
+ void *pointer[3];
+} ADL_Bank;
+
+/* Identifier of dynamic bank */
+typedef struct ADL_BankId
+{
+ ADL_UInt8 percussive, msb, lsb;
+} ADL_BankId;
+
+/* Flags for dynamic bank access */
+enum ADL_BankAccessFlags
+{
+ ADLMIDI_Bank_Create = 1, /* create bank, allocating memory as needed */
+ ADLMIDI_Bank_CreateRt = 1|2, /* create bank, never allocating memory */
+};
+
+typedef struct ADL_Instrument ADL_Instrument;
+
+#if defined(ADLMIDI_UNSTABLE_API)
+/* Preallocates a minimum number of bank slots. Returns the actual capacity. */
+extern int adl_reserveBanks(struct ADL_MIDIPlayer *device, unsigned banks);
+/* Gets the bank designated by the identifier, optionally creating if it does not exist. */
+extern int adl_getBank(struct ADL_MIDIPlayer *device, const ADL_BankId *id, int flags, ADL_Bank *bank);
+/* Gets the identifier of a bank. */
+extern int adl_getBankId(struct ADL_MIDIPlayer *device, const ADL_Bank *bank, ADL_BankId *id);
+/* Removes a bank. */
+extern int adl_removeBank(struct ADL_MIDIPlayer *device, ADL_Bank *bank);
+/* Gets the first bank. */
+extern int adl_getFirstBank(struct ADL_MIDIPlayer *device, ADL_Bank *bank);
+/* Iterates to the next bank. */
+extern int adl_getNextBank(struct ADL_MIDIPlayer *device, ADL_Bank *bank);
+/* Gets the nth intrument in the bank [0..127]. */
+extern int adl_getInstrument(struct ADL_MIDIPlayer *device, const ADL_Bank *bank, unsigned index, ADL_Instrument *ins);
+/* Sets the nth intrument in the bank [0..127]. */
+extern int adl_setInstrument(struct ADL_MIDIPlayer *device, ADL_Bank *bank, unsigned index, const ADL_Instrument *ins);
+#endif /* defined(ADLMIDI_UNSTABLE_API) */
+
/*Sets number of 4-operator channels between all chips.
By default, it is automatically re-calculating every bank change.
If you want to specify custom number of four operator channels,
@@ -141,7 +182,7 @@ extern void adl_setFullRangeBrightness(struct ADL_MIDIPlayer *device, int fr_bri
/*Enable or disable built-in loop (built-in loop supports 'loopStart' and 'loopEnd' tags to loop specific part)*/
extern void adl_setLoopEnabled(struct ADL_MIDIPlayer *device, int loopEn);
-/*Enable or disable Logariphmic volume changer */
+/* !!!DEPRECATED!!! Enable or disable Logariphmic volume changer */
extern void adl_setLogarithmicVolumes(struct ADL_MIDIPlayer *device, int logvol);
/*Set different volume range model */
@@ -336,6 +377,70 @@ extern void adl_setNoteHook(struct ADL_MIDIPlayer *device, ADL_NoteHook noteHook
/* Set debug message hook */
extern void adl_setDebugMessageHook(struct ADL_MIDIPlayer *device, ADL_DebugMessageHook debugMessageHook, void *userData);
+
+/**Instrument structures**/
+
+enum
+{
+ ADLMIDI_InstrumentVersion = 0,
+};
+
+typedef enum ADL_InstrumentFlags
+{
+ /* Is two-operator single-voice instrument (no flags) */
+ ADLMIDI_Ins_2op = 0x00,
+ /* Is true four-operator instrument */
+ ADLMIDI_Ins_4op = 0x01,
+ /* Is pseudo four-operator (two 2-operator voices) instrument */
+ ADLMIDI_Ins_Pseudo4op = 0x02,
+ /* Is a blank instrument entry */
+ ADLMIDI_Ins_IsBlank = 0x04,
+ /* Mask of the flags range */
+ ADLMIDI_Ins_ALL_MASK = 0x07,
+} ADL_InstrumentFlags;
+
+typedef struct ADL_Operator
+{
+ /* AM/Vib/Env/Ksr/FMult characteristics */
+ ADL_UInt8 avekf_20;
+ /* Key Scale Level / Total level register data */
+ ADL_UInt8 ksl_l_40;
+ /* Attack / Decay */
+ ADL_UInt8 atdec_60;
+ /* Systain and Release register data */
+ ADL_UInt8 susrel_80;
+ /* Wave form */
+ ADL_UInt8 waveform_E0;
+} ADL_Operator;
+
+typedef struct ADL_Instrument
+{
+ /* Version of the instrument object */
+ int version;
+ /* MIDI note key (half-tone) offset for an instrument (or a first voice in pseudo-4-op mode) */
+ ADL_SInt16 note_offset1;
+ /* MIDI note key (half-tone) offset for a second voice in pseudo-4-op mode */
+ ADL_SInt16 note_offset2;
+ /* MIDI note velocity offset (taken from Apogee TMB format) */
+ ADL_SInt8 midi_velocity_offset;
+ /* Second voice detune level (taken from DMX OP2) */
+ ADL_SInt8 second_voice_detune;
+ /* Percussion MIDI base tone number at which this drum will be played */
+ ADL_UInt8 percussion_key_number;
+ /* Enum ADL_InstrumentFlags */
+ ADL_UInt8 inst_flags;
+ /* Feedback&Connection register for first and second operators */
+ ADL_UInt8 fb_conn1_C0;
+ /* Feedback&Connection register for third and fourth operators */
+ ADL_UInt8 fb_conn2_C0;
+ /* Operators register data */
+ ADL_Operator operators[4];
+ /* Millisecond delay of sounding while key is on */
+ ADL_UInt16 delay_on_ms;
+ /* Millisecond delay of sounding after key off */
+ ADL_UInt16 delay_off_ms;
+} ADL_Instrument;
+
#ifdef __cplusplus
}
#endif
diff --git a/include/adlmidi.hpp b/include/adlmidi.hpp
index 63f2abd..6d01b8d 100644
--- a/include/adlmidi.hpp
+++ b/include/adlmidi.hpp
@@ -24,24 +24,15 @@
#ifndef ADLMIDI_HPP
#define ADLMIDI_HPP
-#include "adlmidi.h"
-
-#include <stdint.h>
-#include <vector>
-
-class OPL3;
-class MIDIplay;
+struct ADL_MIDIPlayer;
class AdlInstrumentTester
{
- uint32_t cur_gm;
- uint32_t ins_idx;
- std::vector<uint32_t> adl_ins_list;
- OPL3 *opl;
- MIDIplay * play;
+ struct Impl;
+ Impl *P;
public:
- AdlInstrumentTester(ADL_MIDIPlayer *device);
+ explicit AdlInstrumentTester(ADL_MIDIPlayer *device);
virtual ~AdlInstrumentTester();
// Find list of adlib instruments that supposedly implement this GM
@@ -51,6 +42,10 @@ public:
void NextGM(int offset);
void NextAdl(int offset);
bool HandleInputChar(char ch);
+
+private:
+ AdlInstrumentTester(const AdlInstrumentTester &);
+ AdlInstrumentTester &operator=(const AdlInstrumentTester &);
};
#endif //ADLMIDI_HPP
diff --git a/libADLMIDI-test.pro b/libADLMIDI-test.pro
index bf11c1a..982a9a2 100644
--- a/libADLMIDI-test.pro
+++ b/libADLMIDI-test.pro
@@ -37,6 +37,7 @@ HEADERS += \
src/chips/nuked_opl3.h \
src/chips/nuked_opl3_v174.h \
src/chips/opl_chip_base.h \
+ src/chips/opl_chip_base.tcc \
src/fraction.hpp \
src/midiplay/wave_writer.h
@@ -57,7 +58,6 @@ SOURCES += \
src/chips/nuked/nukedopl3.c \
src/chips/nuked_opl3.cpp \
src/chips/nuked_opl3_v174.cpp \
- src/chips/opl_chip_base.cpp \
utils/midiplay/adlmidiplay.cpp \
utils/midiplay/wave_writer.c
diff --git a/libADLMIDI.pro b/libADLMIDI.pro
new file mode 100644
index 0000000..64c9aa1
--- /dev/null
+++ b/libADLMIDI.pro
@@ -0,0 +1,55 @@
+#
+# Project file for the Qt Creator IDE
+#
+
+TEMPLATE = lib
+CONFIG -= qt
+CONFIG += staticlib
+
+TARGET = ADLMIDI
+INSTALLINCLUDES = $$PWD/include/*
+INSTALLINCLUDESTO = ADLMIDI
+include($$PWD/../audio_codec_common.pri)
+
+DEFINES += ADLMIDI_DISABLE_CPP_EXTRAS
+
+macx: QMAKE_CXXFLAGS_WARN_ON += -Wno-absolute-value
+
+INCLUDEPATH += $$PWD $$PWD/include
+
+HEADERS += \
+ include/adlmidi.h \
+ src/adlbank.h \
+ src/adldata.hh \
+ src/adlmidi_mus2mid.h \
+ src/adlmidi_private.hpp \
+ src/adlmidi_xmi2mid.h \
+ src/wopl/wopl_file.h \
+ src/chips/dosbox/dbopl.h \
+ src/chips/dosbox_opl3.h \
+ src/chips/nuked/nukedopl3_174.h \
+ src/chips/nuked/nukedopl3.h \
+ src/chips/nuked_opl3.h \
+ src/chips/nuked_opl3_v174.h \
+ src/chips/opl_chip_base.h \
+ src/chips/opl_chip_base.tcc \
+ src/fraction.hpp
+
+SOURCES += \
+ src/adldata.cpp \
+ \
+ src/adlmidi.cpp \
+ src/adlmidi_load.cpp \
+ src/adlmidi_midiplay.cpp \
+ src/adlmidi_mus2mid.c \
+ src/adlmidi_opl3.cpp \
+ src/adlmidi_private.cpp \
+ src/adlmidi_xmi2mid.c \
+ src/wopl/wopl_file.c \
+ src/chips/dosbox/dbopl.cpp \
+ src/chips/dosbox_opl3.cpp \
+ src/chips/nuked/nukedopl3_174.c \
+ src/chips/nuked/nukedopl3.c \
+ src/chips/nuked_opl3.cpp \
+ src/chips/nuked_opl3_v174.cpp
+
diff --git a/projects/watcom/ADLMIDI-linux32.tgt b/projects/watcom/ADLMIDI-linux32.tgt
new file mode 100644
index 0000000..98a1799
--- /dev/null
+++ b/projects/watcom/ADLMIDI-linux32.tgt
@@ -0,0 +1,475 @@
+40
+targetIdent
+0
+MProject
+1
+MComponent
+0
+2
+WString
+3
+LIB
+3
+WString
+5
+x_2sn
+1
+0
+1
+4
+MCommand
+0
+5
+MCommand
+0
+6
+MItem
+19
+ADLMIDI-linux32.lib
+7
+WString
+3
+LIB
+8
+WVList
+2
+9
+MCState
+10
+WString
+4
+WLIB
+11
+WString
+25
+???s?Strip LINNUM records
+1
+1
+12
+MVState
+13
+WString
+4
+WLIB
+14
+WString
+16
+???s?Page bound:
+1
+15
+WString
+4
+1024
+0
+16
+WVList
+1
+17
+ActionStates
+18
+WString
+5
+&Make
+19
+WVList
+0
+-1
+1
+1
+0
+20
+WPickList
+16
+21
+MItem
+3
+*.c
+22
+WString
+4
+COBJ
+23
+WVList
+3
+24
+MVState
+25
+WString
+3
+WCC
+26
+WString
+25
+x????Include directories:
+1
+27
+WString
+31
+"$(%watcom)/lh" "../../include"
+0
+28
+MRState
+29
+WString
+3
+WCC
+30
+WString
+33
+??2??80386 register-based calling
+1
+1
+31
+MRState
+32
+WString
+3
+WCC
+33
+WString
+39
+??2??Pentium Pro register-based calling
+1
+0
+34
+WVList
+1
+35
+ActionStates
+36
+WString
+5
+&Make
+37
+WVList
+0
+-1
+1
+1
+0
+38
+MItem
+27
+..\..\src\adlmidi_mus2mid.c
+39
+WString
+4
+COBJ
+40
+WVList
+0
+41
+WVList
+0
+21
+1
+1
+0
+42
+MItem
+27
+..\..\src\adlmidi_xmi2mid.c
+43
+WString
+4
+COBJ
+44
+WVList
+0
+45
+WVList
+0
+21
+1
+1
+0
+46
+MItem
+33
+..\..\src\chips\nuked\nukedopl3.c
+47
+WString
+4
+COBJ
+48
+WVList
+0
+49
+WVList
+0
+21
+1
+1
+0
+50
+MItem
+37
+..\..\src\chips\nuked\nukedopl3_174.c
+51
+WString
+4
+COBJ
+52
+WVList
+0
+53
+WVList
+0
+21
+1
+1
+0
+54
+MItem
+26
+..\..\src\wopl\wopl_file.c
+55
+WString
+4
+COBJ
+56
+WVList
+0
+57
+WVList
+0
+21
+1
+1
+0
+58
+MItem
+5
+*.cpp
+59
+WString
+6
+CPPOBJ
+60
+WVList
+4
+61
+MVState
+62
+WString
+3
+WPP
+63
+WString
+25
+x????Include directories:
+1
+64
+WString
+31
+"$(%watcom)/lh" "../../include"
+0
+65
+MVState
+66
+WString
+3
+WPP
+67
+WString
+23
+?????Macro definitions:
+1
+68
+WString
+31
+ADLMIDI_DISABLE_DOSBOX_EMULATOR
+0
+69
+MRState
+70
+WString
+3
+WPP
+71
+WString
+21
+?????Default rounding
+1
+0
+72
+MRState
+73
+WString
+3
+WPP
+74
+WString
+18
+?????Omit rounding
+1
+1
+75
+WVList
+0
+-1
+1
+1
+0
+76
+MItem
+21
+..\..\src\adldata.cpp
+77
+WString
+6
+CPPOBJ
+78
+WVList
+0
+79
+WVList
+0
+58
+1
+1
+0
+80
+MItem
+21
+..\..\src\adlmidi.cpp
+81
+WString
+6
+CPPOBJ
+82
+WVList
+0
+83
+WVList
+0
+58
+1
+1
+0
+84
+MItem
+26
+..\..\src\adlmidi_load.cpp
+85
+WString
+6
+CPPOBJ
+86
+WVList
+0
+87
+WVList
+0
+58
+1
+1
+0
+88
+MItem
+30
+..\..\src\adlmidi_midiplay.cpp
+89
+WString
+6
+CPPOBJ
+90
+WVList
+0
+91
+WVList
+0
+58
+1
+1
+0
+92
+MItem
+26
+..\..\src\adlmidi_opl3.cpp
+93
+WString
+6
+CPPOBJ
+94
+WVList
+0
+95
+WVList
+0
+58
+1
+1
+0
+96
+MItem
+29
+..\..\src\adlmidi_private.cpp
+97
+WString
+6
+CPPOBJ
+98
+WVList
+0
+99
+WVList
+0
+58
+1
+1
+0
+100
+MItem
+30
+..\..\src\chips\nuked_opl3.cpp
+101
+WString
+6
+CPPOBJ
+102
+WVList
+0
+103
+WVList
+0
+58
+1
+1
+0
+104
+MItem
+35
+..\..\src\chips\nuked_opl3_v174.cpp
+105
+WString
+6
+CPPOBJ
+106
+WVList
+0
+107
+WVList
+0
+58
+1
+1
+0
+108
+MItem
+33
+..\..\src\chips\opl_chip_base.cpp
+109
+WString
+6
+CPPOBJ
+110
+WVList
+0
+111
+WVList
+0
+58
+1
+1
+0
diff --git a/projects/watcom/ADLMIDI-win32.tgt b/projects/watcom/ADLMIDI-win32.tgt
new file mode 100644
index 0000000..379bf30
--- /dev/null
+++ b/projects/watcom/ADLMIDI-win32.tgt
@@ -0,0 +1,475 @@
+40
+targetIdent
+0
+MProject
+1
+MComponent
+0
+2
+WString
+4
+NDLL
+3
+WString
+5
+n_2dn
+1
+0
+1
+4
+MCommand
+0
+5
+MCommand
+0
+6
+MItem
+17
+ADLMIDI-win32.dll
+7
+WString
+4
+NDLL
+8
+WVList
+2
+9
+MCState
+10
+WString
+4
+WLIB
+11
+WString
+25
+???s?Strip LINNUM records
+1
+1
+12
+MVState
+13
+WString
+4
+WLIB
+14
+WString
+16
+???s?Page bound:
+1
+15
+WString
+4
+1024
+0
+16
+WVList
+1
+17
+ActionStates
+18
+WString
+5
+&Make
+19
+WVList
+0
+-1
+1
+1
+0
+20
+WPickList
+16
+21
+MItem
+3
+*.c
+22
+WString
+4
+COBJ
+23
+WVList
+3
+24
+MVState
+25
+WString
+3
+WCC
+26
+WString
+25
+n????Include directories:
+1
+27
+WString
+47
+"$(%watcom)/h;$(%watcom)/h/nt" "../../include"
+0
+28
+MRState
+29
+WString
+3
+WCC
+30
+WString
+33
+??2??80386 register-based calling
+1
+1
+31
+MRState
+32
+WString
+3
+WCC
+33
+WString
+39
+??2??Pentium Pro register-based calling
+1
+0
+34
+WVList
+1
+35
+ActionStates
+36
+WString
+5
+&Make
+37
+WVList
+0
+-1
+1
+1
+0
+38
+MItem
+27
+..\..\src\adlmidi_mus2mid.c
+39
+WString
+4
+COBJ
+40
+WVList
+0
+41
+WVList
+0
+21
+1
+1
+0
+42
+MItem
+27
+..\..\src\adlmidi_xmi2mid.c
+43
+WString
+4
+COBJ
+44
+WVList
+0
+45
+WVList
+0
+21
+1
+1
+0
+46
+MItem
+33
+..\..\src\chips\nuked\nukedopl3.c
+47
+WString
+4
+COBJ
+48
+WVList
+0
+49
+WVList
+0
+21
+1
+1
+0
+50
+MItem
+37
+..\..\src\chips\nuked\nukedopl3_174.c
+51
+WString
+4
+COBJ
+52
+WVList
+0
+53
+WVList
+0
+21
+1
+1
+0
+54
+MItem
+26
+..\..\src\wopl\wopl_file.c
+55
+WString
+4
+COBJ
+56
+WVList
+0
+57
+WVList
+0
+21
+1
+1
+0
+58
+MItem
+5
+*.cpp
+59
+WString
+6
+CPPOBJ
+60
+WVList
+4
+61
+MVState
+62
+WString
+3
+WPP
+63
+WString
+25
+n????Include directories:
+1
+64
+WString
+47
+"$(%watcom)/h;$(%watcom)/h/nt" "../../include"
+0
+65
+MVState
+66
+WString
+3
+WPP
+67
+WString
+23
+?????Macro definitions:
+1
+68
+WString
+31
+ADLMIDI_DISABLE_DOSBOX_EMULATOR
+0
+69
+MRState
+70
+WString
+3
+WPP
+71
+WString
+21
+?????Default rounding
+1
+0
+72
+MRState
+73
+WString
+3
+WPP
+74
+WString
+18
+?????Omit rounding
+1
+1
+75
+WVList
+0
+-1
+1
+1
+0
+76
+MItem
+21
+..\..\src\adldata.cpp
+77
+WString
+6
+CPPOBJ
+78
+WVList
+0
+79
+WVList
+0
+58
+1
+1
+0
+80
+MItem
+21
+..\..\src\adlmidi.cpp
+81
+WString
+6
+CPPOBJ
+82
+WVList
+0
+83
+WVList
+0
+58
+1
+1
+0
+84
+MItem
+26
+..\..\src\adlmidi_load.cpp
+85
+WString
+6
+CPPOBJ
+86
+WVList
+0
+87
+WVList
+0
+58
+1
+1
+0
+88
+MItem
+30
+..\..\src\adlmidi_midiplay.cpp
+89
+WString
+6
+CPPOBJ
+90
+WVList
+0
+91
+WVList
+0
+58
+1
+1
+0
+92
+MItem
+26
+..\..\src\adlmidi_opl3.cpp
+93
+WString
+6
+CPPOBJ
+94
+WVList
+0
+95
+WVList
+0
+58
+1
+1
+0
+96
+MItem
+29
+..\..\src\adlmidi_private.cpp
+97
+WString
+6
+CPPOBJ
+98
+WVList
+0
+99
+WVList
+0
+58
+1
+1
+0
+100
+MItem
+30
+..\..\src\chips\nuked_opl3.cpp
+101
+WString
+6
+CPPOBJ
+102
+WVList
+0
+103
+WVList
+0
+58
+1
+1
+0
+104
+MItem
+35
+..\..\src\chips\nuked_opl3_v174.cpp
+105
+WString
+6
+CPPOBJ
+106
+WVList
+0
+107
+WVList
+0
+58
+1
+1
+0
+108
+MItem
+33
+..\..\src\chips\opl_chip_base.cpp
+109
+WString
+6
+CPPOBJ
+110
+WVList
+0
+111
+WVList
+0
+58
+1
+1
+0
diff --git a/projects/watcom/ADLMIDI.tgt b/projects/watcom/ADLMIDI.tgt
index 4c3e335..5e8def9 100644
--- a/projects/watcom/ADLMIDI.tgt
+++ b/projects/watcom/ADLMIDI.tgt
@@ -12,7 +12,7 @@ LIB
3
WString
5
-n_2sn
+d_2sn
1
0
1
@@ -59,7 +59,7 @@ WString
15
WString
4
-1024
+4096
0
16
WVList
@@ -79,7 +79,7 @@ WVList
0
20
WPickList
-11
+16
21
MItem
3
@@ -100,12 +100,12 @@ WCC
26
WString
25
-n????Include directories:
+d????Include directories:
1
27
WString
-46
-"$(%watcom)/h;$(%watcom)/h/nt" "../../include"
+30
+"$(%watcom)/h" "../../include"
0
28
MRState
@@ -185,8 +185,8 @@ WVList
0
46
MItem
-21
-..\..\src\nukedopl3.c
+33
+..\..\src\chips\nuked\nukedopl3.c
47
WString
4
@@ -203,143 +203,273 @@ WVList
0
50
MItem
+37
+..\..\src\chips\nuked\nukedopl3_174.c
+51
+WString
+4
+COBJ
+52
+WVList
+0
+53
+WVList
+0
+21
+1
+1
+0
+54
+MItem
+26
+..\..\src\wopl\wopl_file.c
+55
+WString
+4
+COBJ
+56
+WVList
+0
+57
+WVList
+0
+21
+1
+1
+0
+58
+MItem
5
*.cpp
-51
+59
WString
6
CPPOBJ
-52
+60
WVList
-1
-53
+4
+61
MVState
-54
+62
WString
3
WPP
-55
+63
WString
25
-n????Include directories:
+d????Include directories:
1
-56
+64
WString
-47
-"$(%watcom)/h;$(%watcom)/h/nt" "../../include"
+30
+"$(%watcom)/h" "../../include"
0
-57
+65
+MVState
+66
+WString
+3
+WPP
+67
+WString
+23
+?????Macro definitions:
+1
+68
+WString
+31
+ADLMIDI_DISABLE_DOSBOX_EMULATOR
+0
+69
+MRState
+70
+WString
+3
+WPP
+71
+WString
+21
+?????Default rounding
+1
+0
+72
+MRState
+73
+WString
+3
+WPP
+74
+WString
+18
+?????Omit rounding
+1
+1
+75
WVList
0
-1
1
1
0
-58
+76
MItem
21
..\..\src\adldata.cpp
-59
+77
WString
6
CPPOBJ
-60
+78
WVList
0
-61
+79
WVList
0
-50
+58
1
1
0
-62
+80
MItem
21
..\..\src\adlmidi.cpp
-63
+81
WString
6
CPPOBJ
-64
+82
WVList
0
-65
+83
WVList
0
-50
+58
1
1
0
-66
+84
MItem
26
..\..\src\adlmidi_load.cpp
-67
+85
WString
6
CPPOBJ
-68
+86
WVList
0
-69
+87
WVList
0
-50
+58
1
1
0
-70
+88
MItem
30
..\..\src\adlmidi_midiplay.cpp
-71
+89
WString
6
CPPOBJ
-72
+90
WVList
0
-73
+91
WVList
0
-50
+58
1
1
0
-74
+92
MItem
26
..\..\src\adlmidi_opl3.cpp
-75
+93
WString
6
CPPOBJ
-76
+94
WVList
0
-77
+95
WVList
0
-50
+58
1
1
0
-78
+96
MItem
29
..\..\src\adlmidi_private.cpp
-79
+97
WString
6
CPPOBJ
-80
+98
WVList
0
-81
+99
WVList
0
-50
+58
+1
+1
+0
+100
+MItem
+30
+..\..\src\chips\nuked_opl3.cpp
+101
+WString
+6
+CPPOBJ
+102
+WVList
+0
+103
+WVList
+0
+58
+1
+1
+0
+104
+MItem
+35
+..\..\src\chips\nuked_opl3_v174.cpp
+105
+WString
+6
+CPPOBJ
+106
+WVList
+0
+107
+WVList
+0
+58
+1
+1
+0
+108
+MItem
+33
+..\..\src\chips\opl_chip_base.cpp
+109
+WString
+6
+CPPOBJ
+110
+WVList
+0
+111
+WVList
+0
+58
1
1
0
diff --git a/projects/watcom/libADLMIDI-linux32.wpj b/projects/watcom/libADLMIDI-linux32.wpj
new file mode 100644
index 0000000..e3262c6
--- /dev/null
+++ b/projects/watcom/libADLMIDI-linux32.wpj
@@ -0,0 +1,63 @@
+40
+projectIdent
+0
+VpeMain
+1
+WRect
+-32
+260
+10304
+9710
+2
+MProject
+3
+MCommand
+0
+4
+MCommand
+0
+2
+5
+WFileName
+19
+ADLMIDI-linux32.tgt
+6
+WFileName
+20
+playmidi-linux32.tgt
+7
+WVList
+2
+8
+VComponent
+9
+WRect
+232
+380
+5712
+4360
+0
+0
+10
+WFileName
+19
+ADLMIDI-linux32.tgt
+0
+15
+11
+VComponent
+12
+WRect
+3896
+1440
+5712
+4360
+0
+0
+13
+WFileName
+20
+playmidi-linux32.tgt
+0
+3
+11
diff --git a/projects/watcom/libADLMIDI-win32.wpj b/projects/watcom/libADLMIDI-win32.wpj
new file mode 100644
index 0000000..9a7684d
--- /dev/null
+++ b/projects/watcom/libADLMIDI-win32.wpj
@@ -0,0 +1,63 @@
+40
+projectIdent
+0
+VpeMain
+1
+WRect
+-32
+260
+10304
+9710
+2
+MProject
+3
+MCommand
+0
+4
+MCommand
+0
+2
+5
+WFileName
+17
+ADLMIDI-win32.tgt
+6
+WFileName
+18
+playmidi-win32.tgt
+7
+WVList
+2
+8
+VComponent
+9
+WRect
+560
+450
+5712
+4360
+0
+0
+10
+WFileName
+17
+ADLMIDI-win32.tgt
+0
+15
+11
+VComponent
+12
+WRect
+3392
+1430
+5712
+4360
+0
+0
+13
+WFileName
+18
+playmidi-win32.tgt
+0
+3
+11
diff --git a/projects/watcom/libADLMIDI.wpj b/projects/watcom/libADLMIDI.wpj
index b7bfc41..7bdefd1 100644
--- a/projects/watcom/libADLMIDI.wpj
+++ b/projects/watcom/libADLMIDI.wpj
@@ -4,10 +4,10 @@ projectIdent
VpeMain
1
WRect
--24
-270
-10288
-9680
+-32
+260
+10304
+9710
2
MProject
3
@@ -24,7 +24,7 @@ ADLMIDI.tgt
6
WFileName
12
-playmidi.tgt
+pmidid32.tgt
7
WVList
2
@@ -32,8 +32,8 @@ WVList
VComponent
9
WRect
-160
-270
+328
+240
5712
4360
0
@@ -48,8 +48,8 @@ ADLMIDI.tgt
VComponent
12
WRect
-1712
-810
+3760
+680
5712
4360
0
@@ -57,7 +57,7 @@ WRect
13
WFileName
12
-playmidi.tgt
+pmidid32.tgt
0
3
11
diff --git a/projects/watcom/playmidi-debug-crashful.zip b/projects/watcom/playmidi-debug-crashful.zip
new file mode 100644
index 0000000..e202403
--- /dev/null
+++ b/projects/watcom/playmidi-debug-crashful.zip
Binary files differ
diff --git a/projects/watcom/playmidi-linux32.tgt b/projects/watcom/playmidi-linux32.tgt
new file mode 100644
index 0000000..e12f4e4
--- /dev/null
+++ b/projects/watcom/playmidi-linux32.tgt
@@ -0,0 +1,322 @@
+40
+targetIdent
+0
+MProject
+1
+MComponent
+0
+2
+WString
+3
+LNX
+3
+WString
+5
+x_2en
+1
+0
+1
+4
+MCommand
+0
+5
+MCommand
+0
+6
+MItem
+20
+playmidi-linux32.elf
+7
+WString
+3
+LNX
+8
+WVList
+1
+9
+MVState
+10
+WString
+5
+WLINK
+11
+WString
+18
+?????Libraries(,):
+1
+12
+WString
+15
+ADLMIDI-linux32
+0
+13
+WVList
+5
+14
+ActionStates
+15
+WString
+7
+Sam&ple
+16
+WVList
+0
+17
+ActionStates
+18
+WString
+13
+Remote D&ebug
+19
+WVList
+2
+20
+MRState
+21
+WString
+6
+RDEBUG
+22
+WString
+13
+????9Windowed
+1
+0
+23
+MRState
+24
+WString
+6
+RDEBUG
+25
+WString
+19
+????9Character mode
+1
+1
+26
+ActionStates
+27
+WString
+12
+Local &Debug
+28
+WVList
+1
+29
+MVState
+30
+WString
+6
+WDEBUG
+31
+WString
+28
+?????Application parameters:
+1
+32
+WString
+9
+ttd10.mid
+0
+33
+ActionStates
+34
+WString
+5
+&Make
+35
+WVList
+0
+36
+ActionStates
+37
+WString
+4
+&Run
+38
+WVList
+1
+39
+MVState
+40
+WString
+3
+RUN
+41
+WString
+28
+?????Application parameters:
+1
+42
+WString
+9
+ttd10.mid
+0
+-1
+1
+1
+0
+43
+WPickList
+4
+44
+MItem
+3
+*.c
+45
+WString
+4
+COBJ
+46
+WVList
+2
+47
+MVState
+48
+WString
+3
+WCC
+49
+WString
+25
+x????Include directories:
+1
+50
+WString
+31
+"$(%watcom)/lh" "../../include"
+0
+51
+MVState
+52
+WString
+3
+WCC
+53
+WString
+23
+?????Macro definitions:
+1
+54
+WString
+16
+OUTPUT_WAVE_ONLY
+0
+55
+WVList
+0
+-1
+1
+1
+0
+56
+MItem
+34
+..\..\utils\midiplay\wave_writer.c
+57
+WString
+4
+COBJ
+58
+WVList
+0
+59
+WVList
+0
+44
+1
+1
+0
+60
+MItem
+5
+*.cpp
+61
+WString
+6
+CPPOBJ
+62
+WVList
+2
+63
+MVState
+64
+WString
+3
+WPP
+65
+WString
+25
+x????Include directories:
+1
+66
+WString
+31
+"$(%watcom)/lh" "../../include"
+0
+67
+MVState
+68
+WString
+3
+WPP
+69
+WString
+23
+?????Macro definitions:
+1
+70
+WString
+16
+OUTPUT_WAVE_ONLY
+0
+71
+WVList
+0
+-1
+1
+1
+0
+72
+MItem
+36
+..\..\utils\midiplay\adlmidiplay.cpp
+73
+WString
+6
+CPPOBJ
+74
+WVList
+2
+75
+MRState
+76
+WString
+3
+WPP
+77
+WString
+33
+??2??80386 register-based calling
+1
+1
+78
+MRState
+79
+WString
+3
+WPP
+80
+WString
+39
+??2??Pentium Pro register-based calling
+1
+0
+81
+WVList
+0
+60
+1
+1
+0
diff --git a/projects/watcom/playmidi-win32.tgt b/projects/watcom/playmidi-win32.tgt
new file mode 100644
index 0000000..7a2b220
--- /dev/null
+++ b/projects/watcom/playmidi-win32.tgt
@@ -0,0 +1,306 @@
+40
+targetIdent
+0
+MProject
+1
+MComponent
+0
+2
+WString
+4
+NEXE
+3
+WString
+5
+nc2en
+1
+0
+1
+4
+MCommand
+0
+5
+MCommand
+0
+6
+MItem
+18
+playmidi-win32.exe
+7
+WString
+4
+NEXE
+8
+WVList
+1
+9
+MVState
+10
+WString
+7
+WINLINK
+11
+WString
+18
+?????Libraries(,):
+1
+12
+WString
+13
+ADLMIDI-win32
+0
+13
+WVList
+5
+14
+ActionStates
+15
+WString
+7
+Sam&ple
+16
+WVList
+0
+17
+ActionStates
+18
+WString
+13
+Remote D&ebug
+19
+WVList
+2
+20
+MRState
+21
+WString
+6
+RDEBUG
+22
+WString
+13
+????9Windowed
+1
+0
+23
+MRState
+24
+WString
+6
+RDEBUG
+25
+WString
+19
+????9Character mode
+1
+1
+26
+ActionStates
+27
+WString
+12
+Local &Debug
+28
+WVList
+1
+29
+MVState
+30
+WString
+6
+WDEBUG
+31
+WString
+28
+?????Application parameters:
+1
+32
+WString
+9
+ttd10.mid
+0
+33
+ActionStates
+34
+WString
+5
+&Make
+35
+WVList
+0
+36
+ActionStates
+37
+WString
+4
+&Run
+38
+WVList
+1
+39
+MVState
+40
+WString
+3
+RUN
+41
+WString
+28
+?????Application parameters:
+1
+42
+WString
+9
+ttd10.mid
+0
+-1
+1
+1
+0
+43
+WPickList
+4
+44
+MItem
+3
+*.c
+45
+WString
+4
+COBJ
+46
+WVList
+1
+47
+MVState
+48
+WString
+3
+WCC
+49
+WString
+25
+d????Include directories:
+1
+50
+WString
+31
+"$(%watcom)/h" "../../include"
+0
+51
+WVList
+0
+-1
+1
+1
+0
+52
+MItem
+34
+..\..\utils\midiplay\wave_writer.c
+53
+WString
+4
+COBJ
+54
+WVList
+0
+55
+WVList
+0
+44
+1
+1
+0
+56
+MItem
+5
+*.cpp
+57
+WString
+6
+CPPOBJ
+58
+WVList
+2
+59
+MVState
+60
+WString
+3
+WPP
+61
+WString
+25
+n????Include directories:
+1
+62
+WString
+46
+"$(%watcom)/h;$(%watcom)/h/nt" "../../include"
+0
+63
+MVState
+64
+WString
+3
+WPP
+65
+WString
+23
+?????Macro definitions:
+1
+66
+WString
+16
+OUTPUT_WAVE_ONLY
+0
+67
+WVList
+0
+-1
+1
+1
+0
+68
+MItem
+36
+..\..\utils\midiplay\adlmidiplay.cpp
+69
+WString
+6
+CPPOBJ
+70
+WVList
+2
+71
+MRState
+72
+WString
+3
+WPP
+73
+WString
+33
+??2??80386 register-based calling
+1
+1
+74
+MRState
+75
+WString
+3
+WPP
+76
+WString
+39
+??2??Pentium Pro register-based calling
+1
+0
+77
+WVList
+0
+56
+1
+1
+0
diff --git a/projects/watcom/playmidi.tgt b/projects/watcom/playmidi.tgt
index d1c5b42..1d66c1b 100644
--- a/projects/watcom/playmidi.tgt
+++ b/projects/watcom/playmidi.tgt
@@ -7,12 +7,12 @@ MComponent
0
2
WString
-4
-NEXE
+3
+EXE
3
WString
5
-nc2en
+dr2en
1
0
1
@@ -28,143 +28,127 @@ MItem
playmidi.exe
7
WString
-4
-NEXE
+3
+EXE
8
WVList
-2
+1
9
MVState
10
WString
-7
-WINLINK
+5
+WLINK
11
WString
-22
-?????Other options(,):
-1
-12
-WString
-12
-commit st=1m
-0
-13
-MVState
-14
-WString
-7
-WINLINK
-15
-WString
18
?????Libraries(,):
1
-16
+12
WString
7
ADLMIDI
0
-17
+13
WVList
5
-18
+14
ActionStates
-19
+15
WString
7
Sam&ple
-20
+16
WVList
0
-21
+17
ActionStates
-22
+18
WString
13
Remote D&ebug
-23
+19
WVList
2
-24
+20
MRState
-25
+21
WString
6
RDEBUG
-26
+22
WString
13
????9Windowed
1
0
-27
+23
MRState
-28
+24
WString
6
RDEBUG
-29
+25
WString
19
????9Character mode
1
1
-30
+26
ActionStates
-31
+27
WString
12
Local &Debug
-32
+28
WVList
1
-33
+29
MVState
-34
+30
WString
6
WDEBUG
-35
+31
WString
28
?????Application parameters:
1
-36
+32
WString
9
ttd10.mid
0
-37
+33
ActionStates
-38
+34
WString
5
&Make
-39
+35
WVList
0
-40
+36
ActionStates
-41
+37
WString
4
&Run
-42
+38
WVList
1
-43
+39
MVState
-44
+40
WString
3
RUN
-45
+41
WString
28
?????Application parameters:
1
-46
+42
WString
9
ttd10.mid
@@ -173,150 +157,150 @@ ttd10.mid
1
1
0
-47
+43
WPickList
4
-48
+44
MItem
3
*.c
-49
+45
WString
4
COBJ
-50
+46
WVList
1
-51
+47
MVState
-52
+48
WString
3
WCC
-53
+49
WString
25
-n????Include directories:
+d????Include directories:
1
-54
+50
WString
-47
-"$(%watcom)/h;$(%watcom)/h/nt" "../../include"
+31
+"$(%watcom)/h" "../../include"
0
-55
+51
WVList
0
-1
1
1
0
-56
+52
MItem
34
..\..\utils\midiplay\wave_writer.c
-57
+53
WString
4
COBJ
-58
+54
WVList
0
-59
+55
WVList
0
-48
+44
1
1
0
-60
+56
MItem
5
*.cpp
-61
+57
WString
6
CPPOBJ
-62
+58
WVList
2
-63
+59
MVState
-64
+60
WString
3
WPP
-65
+61
WString
25
-n????Include directories:
+d????Include directories:
1
-66
+62
WString
-47
-"$(%watcom)/h;$(%watcom)/h/nt" "../../include"
+30
+"$(%watcom)/h" "../../include"
0
-67
+63
MVState
-68
+64
WString
3
WPP
-69
+65
WString
23
?????Macro definitions:
1
-70
+66
WString
16
OUTPUT_WAVE_ONLY
0
-71
+67
WVList
0
-1
1
1
0
-72
+68
MItem
36
..\..\utils\midiplay\adlmidiplay.cpp
-73
+69
WString
6
CPPOBJ
-74
+70
WVList
2
-75
+71
MRState
-76
+72
WString
3
WPP
-77
+73
WString
33
??2??80386 register-based calling
1
1
-78
+74
MRState
-79
+75
WString
3
WPP
-80
+76
WString
39
??2??Pentium Pro register-based calling
1
0
-81
+77
WVList
0
-60
+56
1
1
0
diff --git a/projects/watcom/pmidid32.tgt b/projects/watcom/pmidid32.tgt
new file mode 100644
index 0000000..e77f59e
--- /dev/null
+++ b/projects/watcom/pmidid32.tgt
@@ -0,0 +1,322 @@
+40
+targetIdent
+0
+MProject
+1
+MComponent
+0
+2
+WString
+3
+EXE
+3
+WString
+5
+dr2en
+1
+0
+1
+4
+MCommand
+0
+5
+MCommand
+0
+6
+MItem
+12
+pmidid32.exe
+7
+WString
+3
+EXE
+8
+WVList
+2
+9
+MVState
+10
+WString
+5
+WLINK
+11
+WString
+11
+?????Stack:
+1
+12
+WString
+3
+10m
+0
+13
+MVState
+14
+WString
+5
+WLINK
+15
+WString
+18
+?????Libraries(,):
+1
+16
+WString
+7
+ADLMIDI
+0
+17
+WVList
+5
+18
+ActionStates
+19
+WString
+7
+Sam&ple
+20
+WVList
+0
+21
+ActionStates
+22
+WString
+13
+Remote D&ebug
+23
+WVList
+2
+24
+MRState
+25
+WString
+6
+RDEBUG
+26
+WString
+13
+????9Windowed
+1
+0
+27
+MRState
+28
+WString
+6
+RDEBUG
+29
+WString
+19
+????9Character mode
+1
+1
+30
+ActionStates
+31
+WString
+12
+Local &Debug
+32
+WVList
+1
+33
+MVState
+34
+WString
+6
+WDEBUG
+35
+WString
+28
+?????Application parameters:
+1
+36
+WString
+9
+ttd10.mid
+0
+37
+ActionStates
+38
+WString
+5
+&Make
+39
+WVList
+0
+40
+ActionStates
+41
+WString
+4
+&Run
+42
+WVList
+1
+43
+MVState
+44
+WString
+3
+RUN
+45
+WString
+28
+?????Application parameters:
+1
+46
+WString
+9
+ttd10.mid
+0
+-1
+1
+1
+0
+47
+WPickList
+4
+48
+MItem
+3
+*.c
+49
+WString
+4
+COBJ
+50
+WVList
+1
+51
+MVState
+52
+WString
+3
+WCC
+53
+WString
+25
+d????Include directories:
+1
+54
+WString
+31
+"$(%watcom)/h" "../../include"
+0
+55
+WVList
+0
+-1
+1
+1
+0
+56
+MItem
+34
+..\..\utils\midiplay\wave_writer.c
+57
+WString
+4
+COBJ
+58
+WVList
+0
+59
+WVList
+0
+48
+1
+1
+0
+60
+MItem
+5
+*.cpp
+61
+WString
+6
+CPPOBJ
+62
+WVList
+2
+63
+MVState
+64
+WString
+3
+WPP
+65
+WString
+25
+d????Include directories:
+1
+66
+WString
+30
+"$(%watcom)/h" "../../include"
+0
+67
+MVState
+68
+WString
+3
+WPP
+69
+WString
+23
+?????Macro definitions:
+1
+70
+WString
+16
+OUTPUT_WAVE_ONLY
+0
+71
+WVList
+0
+-1
+1
+1
+0
+72
+MItem
+36
+..\..\utils\midiplay\adlmidiplay.cpp
+73
+WString
+6
+CPPOBJ
+74
+WVList
+2
+75
+MRState
+76
+WString
+3
+WPP
+77
+WString
+33
+??2??80386 register-based calling
+1
+1
+78
+MRState
+79
+WString
+3
+WPP
+80
+WString
+39
+??2??Pentium Pro register-based calling
+1
+0
+81
+WVList
+0
+60
+1
+1
+0
diff --git a/src/adldata.cpp b/src/adldata.cpp
index 4105934..49eb36c 100644
--- a/src/adldata.cpp
+++ b/src/adldata.cpp
@@ -4,7 +4,7 @@
* FROM A NUMBER OF SOURCES, MOSTLY PC GAMES.
* PREPROCESSED, CONVERTED, AND POSTPROCESSED OFF-SCREEN.
*/
-const adldata adl[4532] =
+const adldata adl[4535] =
{ // ,---------+-------- Wave select settings
// | ,-------ч-+------ Sustain/release rates
// | | ,-----ч-ч-+---- Attack/decay rates
@@ -4172,10 +4172,10 @@ const adldata adl[4532] =
{ 0x332ED12,0x1E7D211, 0x80,0x45, 0x2, +0 },
{ 0x0F4E431,0x0F5F331, 0x97,0x86, 0x8, +0 },
{ 0x3F0F701,0x1F8F900, 0x00,0x0D, 0xE, +0 },
- { 0x0F78111,0x3F7F054, 0x40,0x45, 0x8, +0 },
- { 0x0F78140,0x3F7F040, 0x40,0x01, 0xC, +14 },
- { 0x0F78111,0x2F7F054, 0x40,0x45, 0xA, +0 },
- { 0x0F78140,0x3F7F040, 0x40,0x05, 0xC, +14 },
+ { 0x0F77111,0x3F7F011, 0x48,0x87, 0xA, +0 },
+ { 0x0F78140,0x3F7F040, 0x86,0x00, 0xC, +14 },
+ { 0x0F78140,0x3F7F040, 0x07,0x40, 0xC, +12 },
+ { 0x0F78100,0x3F7F000, 0x86,0x03, 0xC, +14 },
{ 0x6F78AE8,0x649B1F4, 0x03,0x0A, 0xA, +0 },
{ 0x6F78AE8,0x649B1F4, 0x43,0x4B, 0xA, +0 },
{ 0x0609533,0x4E5C131, 0x63,0x05, 0x0, +0 },
@@ -4213,8 +4213,8 @@ const adldata adl[4532] =
{ 0x4109033,0x2044520, 0xA8,0x85, 0xA, +0 },
{ 0x2034170,0x0043671, 0x08,0x20, 0x9, +0 },
{ 0x1022171,0x0042671, 0x0C,0x17, 0xB, +0 },
- { 0x0055021,0x0F55022, 0x1C,0x0F, 0x7, +0 },
- { 0x0F54066,0x0F55024, 0x5A,0x0F, 0x7, -12 },
+ { 0x005A061,0x0F55022, 0x69,0x06, 0x0, +0 },
+ { 0x0008060,0x0F55021, 0x33,0x08, 0x0, +12 },
{ 0x239B420,0x0076121, 0x50,0x05, 0x6, +0 },
{ 0x139B462,0x00D7161, 0x91,0x14, 0x0, +0 },
{ 0x05470F1,0x07460B1, 0x5A,0x80, 0x0, +0 },
@@ -4241,11 +4241,11 @@ const adldata adl[4532] =
{ 0x10B8020,0x11B6330, 0x87,0x00, 0x8, +12 },
{ 0x1235031,0x0077C24, 0xC0,0x08, 0x2, +0 },
{ 0x045D933,0x4076C35, 0xD0,0x26, 0x4, +0 },
- { 0x2077830,0x2076331, 0x9F,0x00, 0xA, +0 },
+ { 0x6077831,0x2076331, 0x1E,0x00, 0x6, +0 },
{ 0x0199031,0x01B6134, 0x95,0x80, 0xA, +0 },
{ 0x0177532,0x0174531, 0x93,0x03, 0xC, +0 },
{ 0x0277530,0x0174536, 0x14,0x9C, 0xE, +12 },
- { 0x08D6EF1,0x02A3571, 0xC0,0x00, 0xE, +0 },
+ { 0x08B8EF1,0x0285571, 0xC0,0x00, 0xE, +0 },
{ 0x08860A1,0x01A6561, 0x5C,0x00, 0x8, +0 },
{ 0x2176522,0x0277421, 0x5A,0x00, 0x6, +0 },
{ 0x1267532,0x0166531, 0x8D,0x05, 0x4, +0 },
@@ -4267,12 +4267,12 @@ const adldata adl[4532] =
{ 0x32B7420,0x12BF134, 0x46,0x00, 0x8, +0 },
{ 0x5029072,0x0069061, 0x96,0x0C, 0x8, +0 },
{ 0x1019031,0x0069061, 0x1A,0x0C, 0x6, +0 },
- { 0x245C224,0x2550133, 0x81,0x80, 0xB, -36 },
- { 0x2459224,0x2556133, 0x81,0x80, 0xB, -36 },
+ { 0x245C224,0x2550133, 0x81,0x80, 0x9, -36 },
+ { 0x2459224,0x2556133, 0x81,0x80, 0x9, -36 },
{ 0x132ED10,0x3E7D010, 0x87,0x0D, 0x6, +12 },
{ 0x132ED30,0x3E7D010, 0x87,0x12, 0x6, +12 },
- { 0x033513A,0x013C121, 0xA4,0x06, 0x2, +0 },
- { 0x273F325,0x0228231, 0x20,0x06, 0x4, +0 },
+ { 0x073513A,0x013C121, 0xA4,0x0A, 0x2, +0 },
+ { 0x273F325,0x0228231, 0x20,0x0A, 0x4, +0 },
{ 0x0031131,0x0054361, 0xD4,0x08, 0x4, +0 },
{ 0x20311B0,0x00543E1, 0xD9,0x08, 0x4, +0 },
{ 0x245A121,0x126A121, 0x98,0x05, 0xC, +0 },
@@ -4370,16 +4370,19 @@ const adldata adl[4532] =
{ 0x001F312,0x047BB05, 0x03,0x07, 0xC, +12 },
{ 0x0015500,0x007C71B, 0x0C,0x00, 0x0, +0 },
{ 0x201F312,0x047BB09, 0x03,0x07, 0xC, +12 },
+ { 0x291F108,0x333F401, 0x00,0x00, 0x8, +12 },
+ { 0x291F108,0x333F501, 0x00,0x00, 0x8, +12 },
{ 0x0015500,0x007C71F, 0x0C,0x00, 0x0, +0 },
- { 0x210F509,0x605FE05, 0x8A,0x8A, 0xE, +12 },
- { 0x400F509,0x605FE05, 0x07,0x8A, 0xA, +12 },
+ { 0x300F50C,0x605FE05, 0x07,0x8A, 0x0, +12 },
+ { 0x310F508,0x604FE05, 0x86,0x8A, 0x0, +11 },
{ 0x2E1F11E,0x3F3F318, 0x04,0x00, 0x8, +0 },
{ 0x2777603,0x3679601, 0x87,0x08, 0x6, +12 },
{ 0x277C643,0x3679601, 0x87,0x08, 0xE, +12 },
{ 0x366F905,0x099F701, 0x00,0x00, 0xC, +12 },
+ { 0x291F108,0x334F401, 0x00,0x00, 0x8, +12 },
{ 0x431A000,0x085B41A, 0x81,0x05, 0xA, +12 },
{ 0x459F640,0x185B418, 0x00,0x20, 0xB, +12 },
- { 0x212FD08,0x305FD03, 0x01,0x03, 0x8, +12 },
+ { 0x300F50C,0x605FE04, 0x07,0x8A, 0x0, +12 },
{ 0x2A8F9E3,0x0779643, 0x1E,0x08, 0x2, +6 },
{ 0x0A5F7E8,0x0D89949, 0xDE,0x00, 0x0, +0 },
{ 0x2A8F9E3,0x0779643, 0x1E,0x00, 0xE, +12 },
@@ -4549,4681 +4552,4811 @@ const adldata adl[4532] =
{ 0x07BF003,0x07BF502, 0x8A,0x80, 0x8, +0 },
{ 0x07BF003,0x07BF402, 0x8A,0x80, 0x8, +0 },
};
-const struct adlinsdata adlins[4673] =
+const struct adlinsdata adlins[4803] =
{
- { 0, 0, 0, 0, 1660, 1660,0.000000 },
- { 1, 1, 0, 0, 1746, 1746,0.000000 },
- { 2, 2, 0, 0, 1980, 1980,0.000000 },
- { 3, 3, 0, 0, 1553, 1553,0.000000 },
- { 4, 4, 0, 0, 1233, 1233,0.000000 },
- { 5, 5, 0, 0, 1980, 1980,0.000000 },
- { 6, 6, 0, 0, 1100, 1100,0.000000 },
- { 7, 7, 0, 0, 1233, 1233,0.000000 },
- { 8, 8, 0, 0, 940, 940,0.000000 },
- { 9, 9, 0, 0, 1100, 1100,0.000000 },
- { 10, 10, 0, 0, 460, 460,0.000000 },
- { 11, 11, 0, 0, 1740, 1740,0.000000 },
- { 12, 12, 0, 0, 66, 66,0.000000 },
- { 13, 13, 0, 0, 140, 140,0.000000 },
- { 14, 14, 0, 0, 940, 940,0.000000 },
- { 15, 15, 0, 0, 266, 266,0.000000 },
- { 16, 16, 0, 0, 40000, 33,0.000000 },
- { 17, 17, 0, 0, 40000, 6,0.000000 },
- { 18, 18, 0, 0, 40000, 13,0.000000 },
- { 19, 19, 0, 0, 40000, 193,0.000000 },
- { 20, 20, 0, 0, 40000, 193,0.000000 },
- { 21, 21, 0, 0, 40000, 6,0.000000 },
- { 22, 22, 0, 0, 40000, 66,0.000000 },
- { 23, 23, 0, 0, 40000, 66,0.000000 },
- { 24, 24, 0, 0, 1026, 1026,0.000000 },
- { 25, 25, 0, 0, 1826, 1826,0.000000 },
- { 26, 26, 0, 0, 1813, 1813,0.000000 },
- { 27, 27, 0, 0, 1080, 1080,0.000000 },
- { 28, 28, 0, 0, 40000, 0,0.000000 },
- { 29, 29, 0, 0, 40000, 13,0.000000 },
- { 30, 30, 0, 0, 40000, 13,0.000000 },
- { 31, 31, 0, 0, 4200, 4200,0.000000 },
- { 32, 32, 0, 0, 940, 940,0.000000 },
- { 33, 33, 0, 0, 40000, 20,0.000000 },
- { 34, 34, 0, 0, 1746, 1746,0.000000 },
- { 35, 35, 0, 0, 40000, 0,0.000000 },
- { 36, 36, 0, 0, 2400, 2400,0.000000 },
- { 37, 37, 0, 0, 4166, 4166,0.000000 },
- { 38, 38, 0, 0, 1740, 1740,0.000000 },
- { 39, 39, 0, 0, 40000, 26,0.000000 },
- { 40, 40, 0, 0, 40000, 86,0.000000 },
- { 41, 41, 0, 0, 40000, 6,0.000000 },
- { 42, 42, 0, 0, 40000, 133,0.000000 },
- { 43, 43, 0, 0, 40000, 126,0.000000 },
- { 44, 44, 0, 0, 333, 333,0.000000 },
- { 45, 45, 0, 0, 940, 940,0.000000 },
- { 46, 46, 0, 0, 1046, 1046,0.000000 },
- { 47, 47, 0, 0, 40000, 33,0.000000 },
- { 48, 48, 0, 0, 1766, 13,0.000000 },
- { 49, 49, 0, 0, 40000, 220,0.000000 },
- { 50, 50, 0, 0, 40000, 153,0.000000 },
- { 51, 51, 0, 0, 40000, 146,0.000000 },
- { 52, 52, 0, 0, 2300, 2300,0.000000 },
- { 53, 53, 0, 0, 40000, 140,0.000000 },
- { 54, 54, 0, 0, 233, 233,0.000000 },
- { 55, 55, 0, 0, 40000, 6,0.000000 },
- { 56, 56, 0, 0, 40000, 6,0.000000 },
- { 57, 57, 0, 0, 40000, 6,0.000000 },
- { 58, 58, 0, 0, 40000, 6,0.000000 },
- { 59, 59, 0, 0, 40000, 6,0.000000 },
- { 60, 60, 0, 0, 40000, 0,0.000000 },
- { 61, 61, 0, 0, 40000, 26,0.000000 },
- { 62, 62, 0, 0, 40000, 0,0.000000 },
- { 63, 63, 0, 0, 40000, 6,0.000000 },
- { 64, 64, 0, 0, 40000, 20,0.000000 },
- { 65, 65, 0, 0, 40000, 20,0.000000 },
- { 66, 66, 0, 0, 40000, 0,0.000000 },
- { 67, 67, 0, 0, 40000, 6,0.000000 },
- { 68, 68, 0, 0, 3940, 3940,0.000000 },
- { 69, 69, 0, 0, 40000, 6,0.000000 },
- { 70, 70, 0, 0, 40000, 60,0.000000 },
- { 71, 71, 0, 0, 40000, 6,0.000000 },
- { 72, 72, 0, 0, 40000, 6,0.000000 },
- { 73, 73, 0, 0, 40000, 13,0.000000 },
- { 74, 74, 0, 0, 40000, 0,0.000000 },
- { 75, 75, 0, 0, 40000, 73,0.000000 },
- { 76, 76, 0, 0, 40000, 53,0.000000 },
- { 77, 77, 0, 0, 40000, 53,0.000000 },
- { 78, 78, 0, 0, 40000, 53,0.000000 },
- { 79, 79, 0, 0, 40000, 0,0.000000 },
- { 80, 80, 0, 0, 40000, 0,0.000000 },
- { 81, 81, 0, 0, 40000, 33,0.000000 },
- { 82, 82, 0, 0, 40000, 6,0.000000 },
- { 83, 83, 0, 0, 40000, 6,0.000000 },
- { 84, 84, 0, 0, 40000, 73,0.000000 },
- { 85, 85, 0, 0, 40000, 133,0.000000 },
- { 86, 86, 0, 0, 40000, 20,0.000000 },
- { 87, 87, 0, 0, 40000, 233,0.000000 },
- { 88, 88, 0, 0, 40000, 413,0.000000 },
- { 89, 89, 0, 0, 1660, 86,0.000000 },
- { 90, 90, 0, 0, 40000, 553,0.000000 },
- { 91, 91, 0, 0, 40000, 100,0.000000 },
- { 92, 92, 0, 0, 613, 13,0.000000 },
- { 93, 93, 0, 0, 40000, 126,0.000000 },
- { 94, 94, 0, 0, 40000, 53,0.000000 },
- { 95, 95, 0, 0, 993, 993,0.000000 },
- { 96, 96, 0, 0, 40000, 513,0.000000 },
- { 97, 97, 0, 0, 280, 280,0.000000 },
- { 98, 98, 0, 0, 40000, 73,0.000000 },
- { 99, 99, 0, 0, 2113, 2113,0.000000 },
- { 100, 100, 0, 0, 40000, 886,0.000000 },
- { 101, 101, 0, 0, 40000, 773,0.000000 },
- { 102, 102, 0, 0, 40000, 426,0.000000 },
- { 103, 103, 0, 0, 2413, 2413,0.000000 },
- { 104, 104, 0, 0, 1126, 1126,0.000000 },
- { 105, 105, 0, 0, 1046, 1046,0.000000 },
- { 106, 106, 0, 0, 866, 866,0.000000 },
- { 107, 107, 0, 0, 280, 280,0.000000 },
- { 108, 108, 0, 0, 40000, 6,0.000000 },
- { 109, 109, 0, 0, 40000, 113,0.000000 },
- { 110, 110, 0, 0, 40000, 6,0.000000 },
- { 111, 111, 0, 0, 1126, 1126,0.000000 },
- { 112, 112, 0, 0, 140, 140,0.000000 },
- { 113, 113, 0, 0, 246, 246,0.000000 },
- { 114, 114, 0, 0, 20, 20,0.000000 },
- { 115, 115, 0, 0, 146, 146,0.000000 },
- { 116, 116, 0, 0, 146, 146,0.000000 },
- { 117, 117, 0, 0, 340, 340,0.000000 },
- { 118, 118, 0, 0, 2280, 2280,0.000000 },
- { 119, 119, 0, 0, 286, 286,0.000000 },
- { 120, 120, 0, 0, 586, 586,0.000000 },
- { 121, 121, 0, 0, 4486, 4486,0.000000 },
- { 122, 122, 0, 0, 133, 133,0.000000 },
- { 123, 123, 0, 0, 186, 186,0.000000 },
- { 124, 124, 0, 0, 146, 146,0.000000 },
- { 125, 125, 0, 0, 40000, 113,0.000000 },
- { 126, 126, 0, 0, 140, 140,0.000000 },
- { 127, 127, 35, 0, 26, 26,0.000000 },
- { 128, 128, 52, 0, 20, 20,0.000000 },
- { 129, 129, 48, 0, 73, 73,0.000000 },
- { 130, 130, 58, 0, 40, 40,0.000000 },
- { 129, 129, 60, 0, 80, 80,0.000000 },
- { 131, 131, 47, 0, 106, 106,0.000000 },
- { 132, 132, 43, 0, 20, 20,0.000000 },
- { 131, 131, 49, 0, 146, 146,0.000000 },
- { 133, 133, 43, 0, 26, 26,0.000000 },
- { 131, 131, 51, 0, 160, 160,0.000000 },
- { 134, 134, 43, 0, 160, 160,0.000000 },
- { 131, 131, 54, 0, 140, 140,0.000000 },
- { 131, 131, 57, 0, 153, 153,0.000000 },
- { 135, 135, 72, 0, 600, 600,0.000000 },
- { 131, 131, 60, 0, 160, 160,0.000000 },
- { 136, 136, 76, 0, 513, 513,0.000000 },
- { 137, 137, 84, 0, 393, 393,0.000000 },
- { 138, 138, 36, 0, 400, 400,0.000000 },
- { 139, 139, 65, 0, 86, 86,0.000000 },
- { 140, 140, 84, 0, 406, 406,0.000000 },
- { 141, 141, 83, 0, 60, 60,0.000000 },
- { 135, 135, 84, 0, 406, 406,0.000000 },
- { 142, 142, 24, 0, 46, 46,0.000000 },
- { 136, 136, 77, 0, 500, 500,0.000000 },
- { 143, 143, 60, 0, 40, 40,0.000000 },
- { 144, 144, 65, 0, 40, 40,0.000000 },
- { 145, 145, 59, 0, 13, 13,0.000000 },
- { 146, 146, 51, 0, 46, 46,0.000000 },
- { 147, 147, 45, 0, 40, 40,0.000000 },
- { 148, 148, 71, 0, 140, 140,0.000000 },
- { 149, 149, 60, 0, 160, 160,0.000000 },
- { 150, 150, 58, 0, 153, 153,0.000000 },
- { 151, 151, 53, 0, 153, 153,0.000000 },
- { 152, 152, 64, 0, 86, 86,0.000000 },
- { 153, 153, 71, 0, 13, 13,0.000000 },
- { 154, 154, 61, 0, 313, 313,0.000000 },
- { 155, 155, 61, 0, 606, 606,0.000000 },
- { 156, 156, 44, 0, 80, 80,0.000000 },
- { 157, 157, 40, 0, 320, 320,0.000000 },
- { 158, 158, 69, 0, 20, 20,0.000000 },
- { 159, 159, 68, 0, 20, 20,0.000000 },
- { 160, 160, 63, 0, 33, 33,0.000000 },
- { 161, 161, 74, 0, 93, 93,0.000000 },
- { 162, 162, 60, 0, 353, 353,0.000000 },
- { 163, 163, 80, 0, 60, 60,0.000000 },
- { 164, 164, 64, 0, 873, 873,0.000000 },
- { 165, 165, 72, 0, 33, 33,0.000000 },
- { 166, 166, 73, 0, 286, 286,0.000000 },
- { 167, 167, 70, 0, 133, 133,0.000000 },
- { 168, 168, 68, 0, 20, 20,0.000000 },
- { 169, 169, 48, 0, 40, 40,0.000000 },
- { 131, 131, 53, 0, 126, 126,0.000000 },
- { 170, 170, 0, 0, 1020, 1020,0.000000 },
- { 171, 171, 0, 0, 40000, 0,0.000000 },
- { 172, 173, 0, 0, 1740, 1740,0.000000 },
- { 174, 175, 0, 0, 1260, 1260,0.000000 },
- { 176, 177, 0, 0, 1100, 1100,0.000000 },
- { 178, 178, 0, 0, 1100, 1100,0.000000 },
- { 179, 180, 0, 0, 726, 726,0.000000 },
- { 181, 181, 0, 0, 460, 460,0.000000 },
- { 182, 182, 0, 0, 246, 246,0.000000 },
- { 183, 184, 0, 0, 120, 120,0.000000 },
- { 185, 186, 0, 0, 840, 840,0.000000 },
- { 187, 187, 0, 0, 293, 293,0.000000 },
- { 188, 189, 0, 0, 1320, 1320,0.000000 },
- { 190, 191, 0, 0, 646, 6,0.000000 },
- { 192, 193, 0, 0, 40000, 6,0.000000 },
- { 194, 194, 0, 0, 40000, 6,0.000000 },
- { 195, 196, 0, 0, 40000, 0,0.000000 },
- { 197, 198, 0, 0, 40000, 20,0.000000 },
- { 199, 200, 0, 0, 2573, 6,0.000000 },
- { 201, 202, 0, 0, 953, 953,0.000000 },
- { 203, 204, 0, 0, 1740, 1740,0.000000 },
- { 205, 206, 0, 0, 1900, 1900,0.000000 },
- { 207, 208, 0, 0, 1986, 1986,0.000000 },
- { 209, 210, 0, 0, 760, 760,0.000000 },
- { 211, 212, 0, 0, 40000, 6,0.000000 },
- { 213, 213, 0, 0, 1613, 0,0.000000 },
- { 214, 215, 0, 0, 3260, 3260,0.000000 },
- { 216, 217, 0, 0, 360, 360,0.000000 },
- { 218, 219, 0, 0, 1020, 1020,0.000000 },
- { 220, 221, 0, 0, 2126, 2126,0.000000 },
- { 222, 223, 0, 0, 300, 13,0.000000 },
- { 224, 224, 0, 0, 1740, 1740,0.000000 },
- { 225, 226, 0, 0, 1720, 1720,0.000000 },
- { 227, 227, 0, 0, 146, 146,0.000000 },
- { 228, 228, 0, 0, 186, 40,0.000000 },
- { 229, 230, 0, 0, 40000, 46,0.000000 },
- { 231, 232, 0, 0, 40000, 66,0.000000 },
- { 233, 234, 0, 0, 40000, 266,0.000000 },
- { 235, 236, 0, 0, 160, 160,0.000000 },
- { 235, 237, 0, 0, 386, 386,0.000000 },
- { 46, 238, 0, 0, 1046, 1046,0.000000 },
- { 239, 240, 0, 0, 40000, 66,0.000000 },
- { 241, 242, 0, 0, 720, 46,0.000000 },
- { 243, 243, 0, 0, 40000, 33,0.000000 },
- { 244, 244, 0, 0, 40000, 6,0.000000 },
- { 245, 245, 0, 0, 40000, 13,0.000000 },
- { 246, 247, 0, 0, 466, 466,0.000000 },
- { 248, 249, 0, 0, 1213, 13,0.000000 },
- { 250, 250, 0, 0, 60, 6,0.000000 },
- { 251, 251, 0, 0, 40000, 66,0.000000 },
- { 252, 253, 0, 0, 40000, 6,0.000000 },
- { 254, 255, 0, 0, 40000, 26,0.000000 },
- { 256, 257, 0, 0, 166, 0,0.000000 },
- { 258, 259, 0, 0, 40000, 6,0.000000 },
- { 260, 261, 0, 0, 40000, 20,0.000000 },
- { 262, 263, 0, 0, 40000, 26,0.000000 },
- { 264, 265, 0, 0, 40000, 40,0.000000 },
- { 266, 267, 0, 0, 40000, 6,0.000000 },
- { 268, 269, 0, 0, 40000, 20,0.000000 },
- { 270, 271, 0, 0, 40000, 13,0.000000 },
- { 272, 273, 0, 0, 40000, 60,0.000000 },
- { 274, 275, 0, 0, 40000, 33,0.000000 },
- { 276, 276, 0, 0, 40000, 20,0.000000 },
- { 277, 278, 0, 0, 40000, 73,0.000000 },
- { 279, 280, 0, 0, 40000, 33,0.000000 },
- { 281, 282, 0, 0, 40000, 73,0.000000 },
- { 283, 283, 0, 0, 40000, 13,0.000000 },
- { 284, 285, 0, 0, 40000, 6,0.000000 },
- { 286, 287, 0, 0, 40000, 20,0.000000 },
- { 288, 288, 0, 0, 40000, 33,0.000000 },
- { 289, 290, 0, 0, 40000, 6,0.000000 },
- { 291, 292, 0, 0, 40000, 73,0.000000 },
- { 293, 294, 0, 0, 40000, 106,0.000000 },
- { 295, 296, 0, 0, 40000, 180,0.000000 },
- { 88, 297, 0, 0, 40000, 500,0.000000 },
- { 298, 299, 0, 0, 40000, 26,0.000000 },
- { 300, 301, 0, 0, 40000, 553,0.000000 },
- { 302, 302, 0, 0, 40000, 126,0.000000 },
- { 303, 303, 0, 0, 40000, 53,0.000000 },
- { 304, 304, 0, 0, 1793, 1793,0.000000 },
- { 305, 306, 0, 0, 40000, 300,0.000000 },
- { 307, 307, 0, 0, 1900, 1900,0.000000 },
- { 308, 308, 0, 0, 146, 146,0.000000 },
- { 309, 309, 0, 0, 40000, 580,0.000000 },
- { 310, 310, 0, 0, 40000, 480,0.000000 },
- { 311, 312, 0, 0, 2273, 2273,0.000000 },
- { 313, 314, 0, 0, 1140, 1140,0.000000 },
- { 315, 316, 0, 0, 560, 560,0.000000 },
- { 317, 318, 0, 0, 1080, 1080,0.000000 },
- { 107, 319, 0, 0, 280, 280,0.000000 },
- { 108, 320, 0, 0, 40000, 6,0.000000 },
- { 109, 321, 0, 0, 40000, 46,0.000000 },
- { 322, 323, 0, 0, 40000, 6,0.000000 },
- { 324, 325, 0, 0, 146, 146,0.000000 },
- { 326, 327, 0, 0, 246, 246,0.000000 },
- { 328, 328, 0, 0, 26, 26,0.000000 },
- { 329, 329, 0, 0, 140, 140,0.000000 },
- { 330, 331, 0, 0, 40, 40,0.000000 },
- { 332, 332, 0, 0, 2313, 2313,0.000000 },
- { 333, 333, 0, 0, 86, 86,0.000000 },
- { 334, 334, 0, 0, 3440, 3440,0.000000 },
- { 335, 335, 0, 0, 146, 146,0.000000 },
- { 336, 336, 0, 0, 2406, 2406,0.000000 },
- { 337, 337, 0, 0, 40000, 146,0.000000 },
- { 338, 339, 0, 0, 40000, 113,0.000000 },
- { 340, 341, 0, 0, 40000, 0,0.000000 },
- { 342, 342, 35, 0, 446, 446,0.000000 },
- { 343, 343, 0, 0, 20, 20,0.000000 },
- { 344, 344, 35, 0, 86, 86,0.000000 },
- { 345, 345, 35, 0, 26, 26,0.000000 },
- { 346, 346, 50, 0, 153, 153,0.000000 },
- { 347, 347, 18, 0, 53, 53,0.000000 },
- { 348, 348, 72, 0, 53, 53,0.000000 },
- { 349, 349, 74, 0, 33, 33,0.000000 },
- { 350, 350, 35, 0, 66, 66,0.000000 },
- { 351, 351, 16, 0, 86, 86,0.000000 },
- { 352, 352, 0, 0, 1513, 13,0.000000 },
- { 353, 353, 38, 0, 53, 53,0.000000 },
- { 354, 354, 38, 0, 100, 100,0.000000 },
- { 355, 355, 31, 0, 33, 33,0.000000 },
- { 355, 355, 35, 0, 33, 33,0.000000 },
- { 355, 355, 38, 0, 193, 193,0.000000 },
- { 355, 355, 41, 0, 166, 166,0.000000 },
- { 355, 355, 45, 0, 126, 126,0.000000 },
- { 355, 355, 50, 0, 146, 146,0.000000 },
- { 356, 356, 36, 0, 100, 100,0.000000 },
- { 357, 357, 36, 0, 26, 26,0.000000 },
- { 358, 358, 48, 0, 73, 73,0.000000 },
- { 358, 358, 36, 0, 100, 100,0.000000 },
- { 359, 359, 36, 0, 20, 20,0.000000 },
- { 360, 360, 0, 0, 33, 33,0.000000 },
- { 361, 361, 61, 0, 60, 60,0.000000 },
- { 362, 362, 96, 0, 233, 233,0.000000 },
- { 363, 363, 38, 0, 60, 60,0.000000 },
- { 127, 127, 16, 0, 66, 66,0.000000 },
- { 364, 365, 18, 0, 13, 13,0.000000 },
- { 366, 366, 30, 0, 106, 106,0.000000 },
- { 367, 368, 35, 0, 73, 73,0.000000 },
- { 129, 129, 0, 0, 73, 73,0.000000 },
- { 369, 369, 0, 0, 66, 66,0.000000 },
- { 370, 370, 88, 0, 86, 86,0.000000 },
- { 371, 371, 88, 0, 60, 60,0.000000 },
- { 372, 372, 79, 0, 380, 380,0.000000 },
- { 135, 135, 14, 0, 860, 860,0.000000 },
- { 373, 373, 46, 0, 313, 313,0.000000 },
- { 374, 375,129, 0, 1613, 60,0.000000 },
- { 376, 376, 58, 0, 140, 140,0.000000 },
- { 377, 377,164, 0, 106, 106,0.000000 },
- { 378, 378,142, 0, 2300, 2300,0.000000 },
- { 379, 379, 9, 0, 40, 40,0.000000 },
- { 380, 381, 35, 0, 3306, 0,0.000000 },
- { 382, 382, 28, 0, 26, 26,0.000000 },
- { 383, 383, 46, 0, 320, 320,0.000000 },
- { 384, 384, 60, 0, 93, 93,0.000000 },
- { 384, 384, 54, 0, 100, 100,0.000000 },
- { 385, 385, 72, 0, 60, 60,0.000000 },
- { 385, 385, 67, 0, 60, 60,0.000000 },
- { 385, 385, 60, 0, 53, 53,0.000000 },
- { 386, 386, 1, 0, 46, 46,0.000000 },
- { 387, 387, 77, 0, 133, 133,0.000000 },
- { 387, 387, 72, 0, 133, 133,0.000000 },
- { 388, 388, 90, 0, 46, 46,0.000000 },
- { 389, 389, 39, 0, 180, 180,0.000000 },
- { 390, 390, 36, 0, 506, 506,0.000000 },
- { 391, 392, 35, 0, 20, 20,0.000000 },
- { 391, 393, 35, 0, 20, 20,0.000000 },
- { 394, 394, 60, 0, 40, 40,0.000000 },
- { 328, 328, 7, 0, 26, 26,0.000000 },
- { 395, 395, 90, 0, 80, 80,0.000000 },
- { 396, 396, 90, 0, 306, 306,0.000000 },
- { 397, 397, 35, 0, 106, 106,0.000000 },
- { 398, 399, 5, 0, 506, 506,0.000000 },
- { 400, 400,103, 0, 220, 220,0.000000 },
- { 401, 401, 3, 0, 6, 6,0.000000 },
- { 169, 169, 1, 0, 40, 40,0.000000 },
- { 131, 131, 0, 0, 40, 40,0.000000 },
- { 402, 402, 36, 0, 180, 180,0.000000 },
- { 403, 403, 60, 0, 40000, 0,0.000000 },
- { 404, 404, 37, 0, 60, 60,0.000000 },
- { 405, 405, 36, 0, 46, 46,0.000000 },
- { 406, 406, 32, 0, 40, 40,0.000000 },
- { 407, 407, 50, 0, 306, 306,0.000000 },
- { 408, 408, 50, 0, 93, 93,0.000000 },
- { 409, 409, 83, 0, 26, 26,0.000000 },
- { 410, 410, 72, 0, 93, 93,0.000000 },
- { 148, 148, 59, 0, 153, 153,0.000000 },
- { 411, 411, 64, 0, 40, 40,0.000000 },
- { 411, 411, 60, 0, 40, 40,0.000000 },
- { 412, 412, 72, 0, 26, 26,0.000000 },
- { 412, 412, 62, 0, 33, 33,0.000000 },
- { 413, 413, 83, 0, 273, 273,0.000000 },
- { 414, 414, 0, 0, 40000, 13,0.000000 },
- { 415, 415, 0, 0, 1126, 1126,0.000000 },
- { 416, 416, 0, 0, 40000, 20,0.000000 },
- { 417, 417, 0, 0, 2940, 20,0.000000 },
- { 418, 418, 0, 0, 2233, 2233,0.000000 },
- { 419, 419, 0, 0, 1233, 1233,0.000000 },
- { 420, 420, 0, 0, 940, 940,0.000000 },
- { 421, 421, 0, 0, 1580, 1580,0.000000 },
- { 422, 422, 0, 0, 1740, 1740,0.000000 },
- { 423, 423, 0, 0, 140, 140,0.000000 },
- { 424, 424, 0, 0, 940, 940,0.000000 },
- { 425, 425, 0, 0, 1080, 1080,0.000000 },
- { 426, 426, 0, 0, 2086, 2086,0.000000 },
- { 427, 427, 0, 0, 40000, 26,0.000000 },
- { 428, 428, 60, 0, 40000, 0,0.000000 },
- { 429, 429, 73, 0, 473, 473,0.000000 },
- { 429, 429, 74, 0, 473, 473,0.000000 },
- { 429, 429, 80, 0, 473, 473,0.000000 },
- { 429, 429, 84, 0, 473, 473,0.000000 },
- { 429, 429, 92, 0, 400, 400,0.000000 },
- { 430, 430, 81, 0, 280, 280,0.000000 },
- { 430, 430, 83, 0, 280, 280,0.000000 },
- { 430, 430, 95, 0, 220, 220,0.000000 },
- { 431, 431, 35, 0, 46, 46,0.000000 },
- { 432, 432, 60, 0, 40, 40,0.000000 },
- { 357, 357, 59, 0, 13, 13,0.000000 },
- { 432, 432, 44, 0, 40, 40,0.000000 },
- { 433, 433, 41, 0, 166, 166,0.000000 },
- { 434, 434, 97, 0, 26, 26,0.000000 },
- { 433, 433, 44, 0, 140, 140,0.000000 },
- { 433, 433, 48, 0, 153, 153,0.000000 },
- { 435, 435, 96, 0, 233, 233,0.000000 },
- { 433, 433, 51, 0, 160, 160,0.000000 },
- { 433, 433, 54, 0, 160, 160,0.000000 },
- { 436, 436, 40, 0, 386, 386,0.000000 },
- { 433, 433, 57, 0, 113, 113,0.000000 },
- { 437, 437, 58, 0, 120, 120,0.000000 },
- { 438, 438, 97, 0, 73, 73,0.000000 },
- { 439, 439, 50, 0, 60, 60,0.000000 },
- { 437, 437, 60, 0, 153, 153,0.000000 },
- { 440, 440, 53, 0, 53, 53,0.000000 },
- { 441, 441, 46, 0, 46, 46,0.000000 },
- { 440, 440, 57, 0, 53, 53,0.000000 },
- { 442, 442, 42, 0, 206, 206,0.000000 },
- { 442, 442, 37, 0, 206, 206,0.000000 },
- { 443, 443, 41, 0, 193, 193,0.000000 },
- { 443, 443, 37, 0, 193, 193,0.000000 },
- { 444, 444, 77, 0, 46, 46,0.000000 },
- { 444, 444, 72, 0, 46, 46,0.000000 },
- { 445, 445, 70, 0, 60, 60,0.000000 },
- { 445, 445, 90, 0, 60, 60,0.000000 },
- { 446, 446, 46, 0, 46, 46,0.000000 },
- { 447, 447, 48, 0, 246, 246,0.000000 },
- { 448, 448, 85, 0, 20, 20,0.000000 },
- { 449, 449, 66, 0, 60, 60,0.000000 },
- { 449, 449, 61, 0, 60, 60,0.000000 },
- { 450, 450, 41, 0, 106, 106,0.000000 },
- { 451, 451, 41, 0, 140, 140,0.000000 },
- { 452, 452, 81, 0, 66, 66,0.000000 },
- { 400, 400, 81, 0, 266, 266,0.000000 },
- { 400, 400, 76, 0, 266, 266,0.000000 },
- { 359, 359, 60, 0, 13, 13,0.000000 },
- { 453, 453, 53, 0, 120, 120,0.000000 },
- { 454, 454, 0, 0, 40000, 0,0.000000 },
- { 455, 455, 0, 0, 40, 40,0.000000 },
- { 456, 456, 0, 0, 1080, 1080,0.000000 },
- { 457, 457, 0, 0, 126, 126,0.000000 },
- { 458, 458, 0, 0, 40000, 26,0.000000 },
- { 459, 459, 0, 0, 40000, 6,0.000000 },
- { 460, 460, 0, 0, 700, 700,0.000000 },
- { 461, 461, 0, 0, 280, 280,0.000000 },
- { 462, 462, 0, 0, 360, 360,0.000000 },
- { 463, 463, 0, 0, 40000, 20,0.000000 },
- { 464, 464, 0, 0, 1466, 13,0.000000 },
- { 465, 465, 0, 0, 40000, 33,0.000000 },
- { 466, 466, 0, 0, 40000, 33,0.000000 },
- { 467, 467, 0, 0, 1953, 1953,0.000000 },
- { 468, 468, 0, 0, 1580, 1580,0.000000 },
- { 469, 469, 0, 0, 1340, 1340,0.000000 },
- { 470, 470, 0, 0, 40000, 0,0.000000 },
- { 471, 471, 0, 0, 40000, 53,0.000000 },
- { 472, 472, 0, 0, 1386, 1386,0.000000 },
- { 473, 473, 0, 0, 560, 13,0.000000 },
- { 474, 474, 0, 0, 40000, 66,0.000000 },
- { 475, 475, 0, 0, 593, 593,0.000000 },
- { 476, 476, 0, 0, 40000, 2446,0.000000 },
- { 477, 477, 0, 0, 60, 60,0.000000 },
- { 478, 478, 0, 0, 220, 220,0.000000 },
- { 479, 479, 0, 0, 153, 153,0.000000 },
- { 480, 480, 0, 0, 20, 20,0.000000 },
- { 481, 481, 0, 0, 40000, 0,0.000000 },
- { 482, 482, 0, 0, 753, 753,0.000000 },
- { 483, 483, 0, 0, 100, 100,0.000000 },
- { 484, 484, 0, 0, 40000, 73,0.000000 },
- { 485, 485, 0, 0, 2600, 320,0.000000 },
- { 486, 486, 0, 0, 293, 293,0.000000 },
- { 487, 487, 0, 0, 1400, 1400,0.000000 },
- { 488, 488, 0, 0, 2073, 2073,0.000000 },
- { 489, 489, 0, 0, 80, 80,0.000000 },
- { 490, 490, 0, 0, 40000, 33,0.000000 },
- { 491, 491, 50, 0, 446, 446,0.000000 },
- { 492, 492, 37, 0, 46, 46,0.000000 },
- { 493, 493, 39, 0, 180, 180,0.000000 },
- { 494, 494, 39, 0, 33, 33,0.000000 },
- { 495, 495, 86, 0, 1800, 1800,0.000000 },
- { 496, 496, 43, 0, 33, 33,0.000000 },
- { 127, 127, 24, 0, 46, 46,0.000000 },
- { 127, 127, 29, 0, 33, 33,0.000000 },
- { 497, 497, 50, 0, 153, 153,0.000000 },
- { 498, 498, 30, 0, 100, 100,0.000000 },
- { 498, 498, 33, 0, 413, 413,0.000000 },
- { 498, 498, 38, 0, 1633, 1633,0.000000 },
- { 498, 498, 42, 0, 26, 26,0.000000 },
- { 499, 499, 24, 0, 46, 46,0.000000 },
- { 499, 499, 27, 0, 66, 66,0.000000 },
- { 499, 499, 29, 0, 66, 66,0.000000 },
- { 499, 499, 32, 0, 53, 53,0.000000 },
- { 500, 500, 32, 0, 13, 13,0.000000 },
- { 501, 501, 53, 0, 86, 86,0.000000 },
- { 501, 501, 57, 0, 86, 86,0.000000 },
- { 502, 502, 60, 0, 80, 80,0.000000 },
- { 503, 503, 55, 0, 160, 160,0.000000 },
- { 486, 486, 85, 0, 266, 266,0.000000 },
- { 504, 504, 90, 0, 453, 453,0.000000 },
- { 505, 505, 84, 0, 73, 73,0.000000 },
- { 506, 506, 48, 0, 160, 160,0.000000 },
- { 507, 507, 48, 0, 40, 40,0.000000 },
- { 132, 132, 72, 0, 13, 13,0.000000 },
- { 508, 508, 72, 0, 13, 13,0.000000 },
- { 509, 509, 72, 0, 13, 13,0.000000 },
- { 510, 510, 63, 0, 533, 533,0.000000 },
- { 510, 510, 65, 0, 526, 526,0.000000 },
- { 511, 511, 79, 0, 506, 506,0.000000 },
- { 512, 512, 38, 0, 113, 113,0.000000 },
- { 513, 513, 94, 0, 100, 100,0.000000 },
- { 514, 514, 87, 0, 113, 113,0.000000 },
- { 514, 514, 94, 0, 100, 100,0.000000 },
- { 515, 515, 80, 0, 66, 66,0.000000 },
- { 516, 516, 47, 0, 140, 140,0.000000 },
- { 517, 517, 61, 0, 80, 80,0.000000 },
- { 517, 517, 68, 0, 66, 66,0.000000 },
- { 518, 518, 61, 0, 160, 160,0.000000 },
- { 518, 518, 68, 0, 126, 126,0.000000 },
- { 499, 499, 60, 0, 46, 46,0.000000 },
- { 519, 519, 60, 0, 60, 60,0.000000 },
- { 520, 520, 36, 0, 53, 53,0.000000 },
- { 520, 520, 60, 0, 40, 40,0.000000 },
- { 521, 521, 60, 0, 40, 40,0.000000 },
- { 522, 522, 68, 0, 20, 20,0.000000 },
- { 523, 523, 71, 0, 33, 33,0.000000 },
- { 523, 523, 72, 0, 33, 33,0.000000 },
- { 524, 524,101, 0, 320, 320,0.000000 },
- { 525, 525, 36, 0, 1680, 1680,0.000000 },
- { 526, 526, 25, 0, 40000, 2286,0.000000 },
- { 527, 527, 37, 0, 400, 400,0.000000 },
- { 528, 528, 36, 0, 146, 146,0.000000 },
- { 528, 528, 41, 0, 166, 166,0.000000 },
- { 529, 529, 84, 0, 73, 73,0.000000 },
- { 530, 530, 54, 0, 1326, 1326,0.000000 },
- { 481, 481, 48, 0, 40000, 0,0.000000 },
- { 531, 531, 0, 0, 2266, 2266,0.000000 },
- { 532, 532, 0, 0, 833, 833,0.000000 },
- { 533, 533, 0, 0, 246, 13,0.000000 },
- { 534, 534, 0, 0, 40000, 6,0.000000 },
- { 535, 535, 0, 0, 4140, 26,0.000000 },
- { 536, 536, 0, 0, 3886, 13,0.000000 },
- { 537, 537, 0, 0, 4886, 4886,0.000000 },
- { 538, 538, 0, 0, 1780, 1780,0.000000 },
- { 539, 539, 0, 0, 4140, 26,0.000000 },
- { 540, 540, 0, 0, 40000, 6,0.000000 },
- { 541, 541, 0, 0, 3946, 13,0.000000 },
- { 542, 542, 0, 0, 40, 40,0.000000 },
- { 543, 543, 0, 0, 40000, 13,0.000000 },
- { 544, 544, 0, 0, 4426, 4426,0.000000 },
- { 545, 545, 0, 0, 40000, 493,0.000000 },
- { 546, 546, 0, 0, 40000, 846,0.000000 },
- { 547, 547, 0, 0, 40000, 53,0.000000 },
- { 135, 135, 49, 0, 1146, 1146,0.000000 },
- { 548, 548, 35, 0, 40, 40,0.000000 },
- { 549, 549, 41, 0, 6, 6,0.000000 },
- { 366, 366, 38, 0, 106, 106,0.000000 },
- { 550, 550, 39, 0, 26, 26,0.000000 },
- { 551, 551, 49, 0, 46, 46,0.000000 },
- { 408, 408, 59, 0, 93, 93,0.000000 },
- { 552, 552, 24, 0, 26, 26,0.000000 },
- { 552, 552, 27, 0, 40, 20,0.000000 },
- { 552, 552, 29, 0, 20, 20,0.000000 },
- { 552, 552, 32, 0, 40, 13,0.000000 },
- { 553, 553, 84, 0, 113, 113,0.000000 },
- { 512, 512, 79, 0, 73, 73,0.000000 },
- { 554, 554, 61, 0, 173, 173,0.000000 },
- { 554, 554, 68, 0, 133, 133,0.000000 },
- { 555, 555, 36, 0, 33, 33,0.000000 },
- { 555, 555, 60, 0, 20, 20,0.000000 },
- { 556, 556, 36, 0, 180, 180,0.000000 },
- { 115, 115, 37, 0, 46, 46,0.000000 },
- { 557, 557, 0, 0, 1066, 1066,0.000000 },
- { 558, 558, 0, 0, 273, 273,0.000000 },
- { 559, 559, 0, 0, 186, 186,0.000000 },
- { 560, 560, 0, 0, 966, 966,0.000000 },
- { 561, 561, 0, 0, 80, 80,0.000000 },
- { 562, 562, 0, 0, 326, 326,0.000000 },
- { 563, 563, 0, 0, 40000, 33,0.000000 },
- { 564, 564, 0, 0, 380, 380,0.000000 },
- { 565, 565, 0, 0, 40, 40,0.000000 },
- { 566, 566, 0, 0, 4586, 4586,0.000000 },
- { 567, 567, 0, 0, 2680, 2680,0.000000 },
- { 568, 568, 0, 0, 40000, 6,0.000000 },
- { 569, 569, 0, 0, 80, 80,0.000000 },
- { 570, 570, 0, 0, 1206, 1206,0.000000 },
- { 571, 571, 0, 0, 593, 593,0.000000 },
- { 572, 572, 0, 0, 680, 680,0.000000 },
- { 356, 356, 0, 0, 246, 246,0.000000 },
- { 573, 573, 0, 0, 40000, 20,0.000000 },
- { 574, 574, 0, 0, 40000, 20,0.000000 },
- { 575, 575, 0, 0, 40000, 73,0.000000 },
- { 576, 576, 0, 0, 40000, 53,0.000000 },
- { 577, 577, 0, 0, 40000, 33,0.000000 },
- { 578, 578, 0, 0, 40000, 140,0.000000 },
- { 579, 579, 0, 0, 40000, 93,0.000000 },
- { 580, 580, 0, 0, 40000, 126,0.000000 },
- { 581, 581, 0, 0, 40000, 26,0.000000 },
- { 582, 582, 0, 0, 40000, 53,0.000000 },
- { 583, 583, 0, 0, 513, 513,0.000000 },
- { 584, 584, 0, 0, 40000, 66,0.000000 },
- { 585, 585, 0, 0, 313, 313,0.000000 },
- { 516, 516, 0, 0, 140, 140,0.000000 },
- { 586, 586, 0, 0, 40000, 0,0.000000 },
- { 587, 587, 0, 0, 40000, 0,0.000000 },
- { 588, 588, 0, 0, 40000, 6,0.000000 },
- { 498, 498, 26, 0, 86, 86,0.000000 },
- { 494, 494, 35, 0, 53, 53,0.000000 },
- { 350, 350, 41, 0, 80, 80,0.000000 },
- { 353, 353, 48, 0, 40, 40,0.000000 },
- { 354, 354, 67, 0, 73, 73,0.000000 },
- { 502, 502, 24, 0, 100, 100,0.000000 },
- { 346, 346, 36, 0, 46, 46,0.000000 },
- { 346, 346, 38, 0, 193, 193,0.000000 },
- { 346, 346, 40, 0, 140, 140,0.000000 },
- { 346, 346, 42, 0, 173, 173,0.000000 },
- { 346, 346, 44, 0, 140, 140,0.000000 },
- { 510, 510, 55, 0, 453, 453,0.000000 },
- { 346, 346, 46, 0, 146, 146,0.000000 },
- { 136, 136, 80, 0, 486, 486,0.000000 },
- { 486, 486, 24, 0, 346, 346,0.000000 },
- { 153, 153, 50, 0, 13, 13,0.000000 },
- { 346, 346, 24, 0, 66, 66,0.000000 },
- { 516, 516, 31, 0, 186, 186,0.000000 },
- { 498, 498, 35, 0, 40, 40,0.000000 },
- { 517, 517, 60, 0, 80, 80,0.000000 },
- { 530, 530, 36, 0, 1760, 1760,0.000000 },
- { 530, 530, 48, 0, 1360, 6,0.000000 },
- { 589, 589, 0, 0, 1660, 1660,0.000000 },
- { 139, 139, 76, 0, 73, 73,0.000000 },
- { 156, 156, 48, 0, 80, 80,0.000000 },
- { 157, 157, 48, 0, 226, 226,0.000000 },
- { 165, 165, 69, 0, 40, 40,0.000000 },
- { 167, 167, 75, 0, 133, 133,0.000000 },
- { 590, 590, 0, 0, 1226, 1226,0.000000 },
- { 591, 591, 0, 0, 2193, 2193,0.000000 },
- { 592, 592, 0, 0, 1900, 1900,0.000000 },
- { 593, 593, 0, 0, 626, 626,0.000000 },
- { 594, 594, 0, 0, 1213, 1213,0.000000 },
- { 595, 595, 0, 0, 1740, 1740,0.000000 },
- { 596, 596, 0, 0, 193, 193,0.000000 },
- { 597, 597, 0, 0, 300, 300,0.000000 },
- { 598, 598, 0, 0, 40000, 6,0.000000 },
- { 599, 599, 0, 0, 40000, 480,0.000000 },
- { 600, 600, 0, 0, 40000, 20,0.000000 },
- { 601, 601, 0, 0, 653, 653,0.000000 },
- { 602, 602, 0, 0, 126, 126,0.000000 },
- { 603, 603, 0, 0, 1080, 1080,0.000000 },
- { 604, 604, 0, 0, 4200, 4200,0.000000 },
- { 605, 605, 0, 0, 1020, 1020,0.000000 },
- { 606, 606, 0, 0, 593, 13,0.000000 },
- { 607, 607, 0, 0, 80, 60,0.000000 },
- { 608, 608, 0, 0, 40000, 113,0.000000 },
- { 609, 609, 0, 0, 120, 120,0.000000 },
- { 610, 610, 0, 0, 1580, 1580,0.000000 },
- { 611, 611, 0, 0, 460, 460,0.000000 },
- { 612, 612, 0, 0, 40000, 53,0.000000 },
- { 613, 613, 0, 0, 2320, 13,0.000000 },
- { 614, 614, 0, 0, 80, 60,0.000000 },
- { 615, 615, 0, 0, 80, 60,0.000000 },
- { 616, 616, 0, 0, 1020, 1020,0.000000 },
- { 617, 617, 0, 0, 146, 146,0.000000 },
- { 618, 618, 0, 0, 740, 740,0.000000 },
- { 619, 619, 0, 0, 146, 146,0.000000 },
- { 620, 620, 0, 0, 40000, 6,0.000000 },
- { 621, 621, 0, 0, 913, 913,0.000000 },
- { 622, 622, 0, 0, 2280, 2280,0.000000 },
- { 623, 623, 0, 0, 166, 6,0.000000 },
- { 624, 624, 0, 0, 40000, 0,0.000000 },
- { 625, 625, 0, 0, 40000, 0,0.000000 },
- { 626, 626, 0, 0, 40000, 0,0.000000 },
- { 627, 627, 0, 0, 1046, 1046,0.000000 },
- { 628, 628, 0, 0, 40000, 6,0.000000 },
- { 629, 629, 0, 0, 40000, 0,0.000000 },
- { 630, 630, 0, 0, 1953, 1953,0.000000 },
- { 631, 631, 0, 0, 40000, 106,0.000000 },
- { 632, 632, 0, 0, 533, 13,0.000000 },
- { 633, 633, 0, 0, 2273, 2273,0.000000 },
- { 634, 634, 0, 0, 646, 646,0.000000 },
- { 635, 635, 0, 0, 166, 166,0.000000 },
- { 636, 636, 0, 0, 326, 326,0.000000 },
- { 637, 637, 0, 0, 40000, 26,0.000000 },
- { 638, 638, 0, 0, 246, 246,0.000000 },
- { 346, 346, 0, 0, 140, 140,0.000000 },
- { 639, 639, 0, 0, 1226, 1226,0.000000 },
- { 404, 404, 0, 0, 146, 146,0.000000 },
- { 506, 506, 0, 0, 153, 153,0.000000 },
- { 639, 639, 60, 0, 886, 886,0.000000 },
- { 639, 639, 79, 0, 446, 446,0.000000 },
- { 640, 640, 65, 0, 800, 800,0.000000 },
- { 486, 486, 31, 0, 353, 353,0.000000 },
- { 486, 486, 36, 0, 360, 360,0.000000 },
- { 640, 640, 72, 0, 613, 613,0.000000 },
- { 136, 136, 79, 0, 493, 493,0.000000 },
- { 148, 148, 57, 0, 160, 160,0.000000 },
- { 150, 150, 53, 0, 153, 153,0.000000 },
- { 641, 641, 84, 0, 106, 106,0.000000 },
- { 520, 520, 66, 0, 40, 40,0.000000 },
- { 642, 642, 31, 0, 166, 13,0.000000 },
- { 642, 642, 29, 0, 60, 26,0.000000 },
- { 356, 356, 31, 0, 93, 93,0.000000 },
- { 356, 356, 19, 0, 220, 220,0.000000 },
- { 643, 643, 31, 0, 40000, 6,0.000000 },
- { 643, 643, 29, 0, 40000, 6,0.000000 },
- { 644, 644, 31, 0, 560, 560,0.000000 },
- { 644, 644, 35, 0, 573, 573,0.000000 },
- { 644, 644, 40, 0, 526, 526,0.000000 },
- { 644, 644, 47, 0, 540, 540,0.000000 },
- { 516, 516, 32, 0, 186, 186,0.000000 },
- { 516, 516, 43, 0, 146, 146,0.000000 },
- { 495, 495, 26, 0, 60, 60,0.000000 },
- { 495, 495, 44, 0, 380, 380,0.000000 },
- { 496, 496, 26, 0, 26, 26,0.000000 },
- { 496, 496, 51, 0, 40, 40,0.000000 },
- { 496, 496, 39, 0, 33, 33,0.000000 },
- { 495, 495, 30, 0, 46, 46,0.000000 },
- { 645, 645, 44, 0, 486, 486,0.000000 },
- { 645, 645, 43, 0, 473, 473,0.000000 },
- { 646, 646, 0, 0, 653, 653,0.000000 },
- { 647, 647, 0, 0, 2280, 2280,0.000000 },
- { 648, 648, 0, 0, 526, 526,0.000000 },
- { 649, 649, 0, 0, 40000, 40,0.000000 },
- { 650, 650, 0, 0, 40, 40,0.000000 },
- { 651, 651, 0, 0, 933, 933,0.000000 },
- { 652, 652, 0, 0, 40000, 300,0.000000 },
- { 653, 653, 0, 0, 280, 280,0.000000 },
- { 654, 654, 0, 0, 40000, 6,0.000000 },
- { 655, 655, 0, 0, 40000, 0,0.000000 },
- { 656, 656, 0, 0, 40000, 6,0.000000 },
- { 657, 657, 0, 0, 280, 280,0.000000 },
- { 658, 658, 0, 0, 513, 513,0.000000 },
- { 659, 659, 0, 0, 40000, 6,0.000000 },
- { 660, 660, 0, 0, 600, 600,0.000000 },
- { 661, 661, 0, 0, 646, 646,0.000000 },
- { 662, 662, 0, 0, 1166, 1166,0.000000 },
- { 663, 663, 0, 0, 40, 40,0.000000 },
- { 664, 664, 0, 0, 2073, 2073,0.000000 },
- { 665, 665, 0, 0, 40000, 106,0.000000 },
- { 666, 666, 0, 0, 40000, 146,0.000000 },
- { 667, 667, 0, 0, 40000, 126,0.000000 },
- { 668, 668, 0, 0, 280, 280,0.000000 },
- { 669, 669, 0, 0, 40000, 73,0.000000 },
- { 670, 670, 0, 0, 393, 393,0.000000 },
- { 671, 671, 0, 0, 760, 760,0.000000 },
- { 672, 672, 0, 0, 40000, 233,0.000000 },
- { 673, 673, 0, 0, 253, 253,0.000000 },
- { 674, 674, 0, 0, 186, 186,0.000000 },
- { 675, 675, 0, 0, 40000, 46,0.000000 },
- { 676, 676, 0, 0, 4773, 4773,0.000000 },
- { 677, 677, 0, 0, 2186, 2186,0.000000 },
- { 678, 678, 0, 0, 313, 313,0.000000 },
- { 679, 679, 0, 0, 1226, 1226,0.000000 },
- { 680, 680, 0, 0, 526, 13,0.000000 },
- { 681, 681, 0, 0, 40000, 0,0.000000 },
- { 682, 682, 0, 0, 40, 46,0.000000 },
- { 683, 683, 0, 0, 146, 146,0.000000 },
- { 684, 684, 0, 0, 2193, 2193,0.000000 },
- { 685, 685, 0, 0, 40000, 220,0.000000 },
- { 686, 686, 0, 0, 40000, 560,0.000000 },
- { 687, 687, 0, 0, 86, 86,0.000000 },
- { 688, 688, 0, 0, 40000, 1326,0.000000 },
- { 689, 689, 0, 0, 1166, 1166,0.000000 },
- { 690, 690, 0, 0, 593, 593,0.000000 },
- { 691, 691, 0, 0, 1580, 1580,0.000000 },
- { 692, 692, 0, 0, 513, 513,0.000000 },
- { 693, 693, 0, 0, 333, 333,0.000000 },
- { 694, 694, 0, 0, 1200, 1200,0.000000 },
- { 695, 695, 0, 0, 40000, 6,0.000000 },
- { 645, 645, 0, 0, 486, 486,0.000000 },
- { 696, 696, 0, 0, 40000, 6,0.000000 },
- { 697, 697, 0, 0, 333, 333,0.000000 },
- { 698, 698, 0, 0, 120, 120,0.000000 },
- { 699, 699, 0, 0, 40000, 6,0.000000 },
- { 700, 700, 0, 0, 13, 13,0.000000 },
- { 701, 701, 0, 0, 40000, 53,0.000000 },
- { 702, 702, 0, 0, 806, 806,0.000000 },
- { 703, 703, 0, 0, 40000, 6,0.000000 },
- { 704, 704, 0, 0, 40000, 6,0.000000 },
- { 705, 705, 0, 0, 40000, 0,0.000000 },
- { 706, 706, 0, 0, 40000, 6,0.000000 },
- { 707, 707, 0, 0, 40000, 166,0.000000 },
- { 708, 708, 0, 0, 40000, 26,0.000000 },
- { 709, 709, 0, 0, 40000, 146,0.000000 },
- { 710, 710, 0, 0, 1233, 6,0.000000 },
- { 711, 711, 0, 0, 146, 146,0.000000 },
- { 712, 712, 0, 0, 40000, 6,0.000000 },
- { 713, 713, 0, 0, 40000, 66,0.000000 },
- { 714, 714, 0, 0, 40000, 393,0.000000 },
- { 715, 715, 0, 0, 40000, 93,0.000000 },
- { 716, 716, 0, 0, 620, 620,0.000000 },
- { 717, 717, 0, 0, 40000, 6,0.000000 },
- { 718, 718, 0, 0, 493, 493,0.000000 },
- { 719, 719, 0, 0, 280, 280,0.000000 },
- { 720, 720, 0, 0, 760, 760,0.000000 },
- { 721, 721, 0, 0, 160, 160,0.000000 },
- { 722, 722, 0, 0, 40000, 106,0.000000 },
- { 723, 723, 0, 0, 166, 166,0.000000 },
- { 724, 724, 0, 0, 40000, 6,0.000000 },
- { 725, 725, 0, 0, 126, 126,0.000000 },
- { 726, 726, 0, 0, 593, 593,0.000000 },
- { 727, 727, 0, 0, 513, 513,0.000000 },
- { 728, 728, 0, 0, 246, 246,0.000000 },
- { 507, 507, 0, 0, 40, 40,0.000000 },
- { 512, 512, 0, 0, 93, 93,0.000000 },
- { 729, 729, 0, 0, 2406, 2406,0.000000 },
- { 730, 730, 0, 0, 2400, 2400,0.000000 },
- { 731, 731, 0, 0, 1153, 1153,0.000000 },
- { 732, 732, 0, 0, 40000, 1113,0.000000 },
- { 733, 733, 0, 0, 40000, 613,0.000000 },
- { 734, 734, 0, 0, 4453, 4453,0.000000 },
- { 735, 735, 0, 0, 160, 160,0.000000 },
- { 736, 736, 0, 0, 80, 80,0.000000 },
- { 737, 737, 0, 0, 1513, 13,0.000000 },
- { 738, 738, 38, 0, 33, 33,0.000000 },
- { 739, 739, 44, 0, 40, 40,0.000000 },
- { 500, 500, 58, 0, 13, 13,0.000000 },
- { 740, 740, 24, 0, 160, 160,0.000000 },
- { 741, 741, 60, 0, 133, 133,0.000000 },
- { 736, 736, 44, 0, 80, 80,0.000000 },
- { 742, 742, 25, 0, 146, 146,0.000000 },
- { 743, 743, 60, 0, 33, 33,0.000000 },
- { 742, 742, 30, 0, 146, 146,0.000000 },
- { 377, 377, 60, 0, 93, 93,0.000000 },
- { 742, 742, 33, 0, 173, 173,0.000000 },
- { 744, 744, 60, 0, 53, 53,0.000000 },
- { 742, 742, 35, 0, 186, 186,0.000000 },
- { 742, 742, 37, 0, 200, 200,0.000000 },
- { 745, 745, 0, 0, 313, 313,0.000000 },
- { 742, 742, 40, 0, 206, 206,0.000000 },
- { 746, 746,102, 0, 300, 300,0.000000 },
- { 747, 747, 80, 0, 433, 433,0.000000 },
- { 377, 377, 0, 0, 86, 86,0.000000 },
- { 748, 748, 56, 0, 13, 13,0.000000 },
- { 749, 749, 0, 0, 140, 140,0.000000 },
- { 746, 746,100, 0, 280, 280,0.000000 },
- { 750, 750, 40, 0, 200, 200,0.000000 },
- { 750, 750, 35, 0, 200, 200,0.000000 },
- { 751, 751, 29, 0, 53, 53,0.000000 },
- { 750, 750, 29, 0, 200, 200,0.000000 },
- { 750, 750, 22, 0, 206, 206,0.000000 },
- { 500, 500, 0, 0, 13, 13,0.000000 },
- { 752, 752, 0, 0, 46, 46,0.000000 },
- { 753, 753, 84, 0, 86, 86,0.000000 },
- { 754, 754, 84, 0, 506, 506,0.000000 },
- { 755, 755, 0, 0, 160, 160,0.000000 },
- { 755, 755, 71, 0, 133, 133,0.000000 },
- { 755, 755, 53, 0, 160, 160,0.000000 },
- { 755, 755, 48, 0, 160, 160,0.000000 },
- { 756, 756, 95, 0, 200, 200,0.000000 },
- { 757, 757, 95, 0, 613, 613,0.000000 },
- { 758, 758, 0, 0, 866, 866,0.000000 },
- { 759, 759, 0, 0, 933, 933,0.000000 },
- { 760, 760, 0, 0, 2393, 2393,0.000000 },
- { 761, 761, 0, 0, 760, 760,0.000000 },
- { 762, 762, 0, 0, 1740, 1740,0.000000 },
- { 763, 763, 0, 0, 1846, 1846,0.000000 },
- { 764, 764, 0, 0, 2106, 2106,0.000000 },
- { 765, 765, 0, 0, 1193, 1193,0.000000 },
- { 766, 766, 0, 0, 1613, 1613,0.000000 },
- { 767, 767, 0, 0, 673, 673,0.000000 },
- { 768, 768, 0, 0, 280, 280,0.000000 },
- { 769, 769, 0, 0, 1740, 1740,0.000000 },
- { 770, 770, 0, 0, 193, 193,0.000000 },
- { 771, 771, 0, 0, 140, 140,0.000000 },
- { 772, 772, 0, 0, 933, 933,0.000000 },
- { 773, 773, 0, 0, 333, 333,0.000000 },
- { 774, 774, 0, 0, 40000, 6,0.000000 },
- { 775, 775, 0, 0, 40000, 6,0.000000 },
- { 776, 776, 0, 0, 613, 13,0.000000 },
- { 777, 777, 0, 0, 40000, 80,0.000000 },
- { 778, 778, 0, 0, 40000, 26,0.000000 },
- { 779, 779, 0, 0, 40000, 20,0.000000 },
- { 780, 780, 0, 0, 40000, 20,0.000000 },
- { 781, 781, 0, 0, 40000, 66,0.000000 },
- { 782, 782, 0, 0, 940, 940,0.000000 },
- { 783, 783, 0, 0, 566, 566,0.000000 },
- { 784, 784, 0, 0, 1846, 1846,0.000000 },
- { 785, 785, 0, 0, 1120, 1120,0.000000 },
- { 786, 786, 0, 0, 300, 300,0.000000 },
- { 787, 787, 0, 0, 3000, 3000,0.000000 },
- { 788, 788, 0, 0, 3773, 3773,0.000000 },
- { 789, 789, 0, 0, 620, 620,0.000000 },
- { 790, 790, 0, 0, 846, 846,0.000000 },
- { 791, 791, 0, 0, 4846, 4846,0.000000 },
- { 792, 792, 0, 0, 1133, 1133,0.000000 },
- { 793, 793, 0, 0, 1446, 1446,0.000000 },
- { 794, 794, 0, 0, 566, 566,0.000000 },
- { 795, 795, 0, 0, 600, 600,0.000000 },
- { 796, 796, 0, 0, 1180, 1180,0.000000 },
- { 797, 797, 0, 0, 893, 893,0.000000 },
- { 798, 798, 0, 0, 40000, 20,0.000000 },
- { 799, 799, 0, 0, 40000, 20,0.000000 },
- { 800, 800, 0, 0, 166, 40,0.000000 },
- { 801, 801, 0, 0, 2286, 2286,0.000000 },
- { 802, 802, 0, 0, 40000, 86,0.000000 },
- { 803, 803, 0, 0, 120, 120,0.000000 },
- { 804, 804, 0, 0, 440, 440,0.000000 },
- { 805, 805, 0, 0, 286, 286,0.000000 },
- { 806, 806, 0, 0, 40000, 86,0.000000 },
- { 807, 807, 0, 0, 5473, 120,0.000000 },
- { 808, 808, 0, 0, 100, 13,0.000000 },
- { 809, 809, 0, 0, 40000, 53,0.000000 },
- { 810, 810, 0, 0, 1640, 6,0.000000 },
- { 811, 811, 0, 0, 40000, 53,0.000000 },
- { 812, 812, 0, 0, 1026, 13,0.000000 },
- { 813, 813, 0, 0, 186, 186,0.000000 },
- { 814, 814, 0, 0, 40, 40,0.000000 },
- { 815, 815, 0, 0, 40000, 20,0.000000 },
- { 816, 816, 0, 0, 40000, 20,0.000000 },
- { 817, 817, 0, 0, 873, 873,0.000000 },
- { 818, 818, 0, 0, 4440, 4440,0.000000 },
- { 819, 819, 0, 0, 273, 6,0.000000 },
- { 820, 820, 0, 0, 40000, 53,0.000000 },
- { 821, 821, 0, 0, 40000, 106,0.000000 },
- { 822, 822, 0, 0, 40000, 6,0.000000 },
- { 823, 823, 0, 0, 40000, 0,0.000000 },
- { 824, 824, 0, 0, 40000, 13,0.000000 },
- { 825, 825, 0, 0, 40000, 33,0.000000 },
- { 826, 826, 0, 0, 40000, 20,0.000000 },
- { 827, 827, 0, 0, 40000, 6,0.000000 },
- { 828, 828, 0, 0, 40000, 6,0.000000 },
- { 829, 829, 0, 0, 40000, 20,0.000000 },
- { 830, 830, 0, 0, 40000, 20,0.000000 },
- { 831, 831, 0, 0, 40000, 6,0.000000 },
- { 832, 832, 0, 0, 40000, 13,0.000000 },
- { 833, 833, 0, 0, 40000, 20,0.000000 },
- { 834, 834, 0, 0, 40000, 20,0.000000 },
- { 835, 835, 0, 0, 40000, 20,0.000000 },
- { 836, 836, 0, 0, 40000, 33,0.000000 },
- { 837, 837, 0, 0, 40000, 53,0.000000 },
- { 838, 838, 0, 0, 40000, 6,0.000000 },
- { 839, 839, 0, 0, 1153, 1153,0.000000 },
- { 840, 840, 0, 0, 40000, 20,0.000000 },
- { 841, 841, 0, 0, 20, 20,0.000000 },
- { 842, 842, 0, 0, 2040, 2040,0.000000 },
- { 843, 843, 0, 0, 40000, 6,0.000000 },
- { 844, 844, 0, 0, 40000, 13,0.000000 },
- { 845, 845, 0, 0, 1153, 1153,0.000000 },
- { 846, 846, 0, 0, 1526, 80,0.000000 },
- { 847, 847, 0, 0, 40000, 180,0.000000 },
- { 848, 848, 0, 0, 40000, 86,0.000000 },
- { 849, 849, 0, 0, 40000, 26,0.000000 },
- { 850, 850, 0, 0, 40000, 53,0.000000 },
- { 851, 851, 0, 0, 2886, 2886,0.000000 },
- { 852, 852, 0, 0, 40000, 73,0.000000 },
- { 853, 853, 0, 0, 40000, 126,0.000000 },
- { 854, 854, 0, 0, 1706, 1706,0.000000 },
- { 855, 855, 0, 0, 40000, 213,0.000000 },
- { 856, 856, 0, 0, 920, 920,0.000000 },
- { 857, 857, 0, 0, 993, 993,0.000000 },
- { 858, 858, 0, 0, 1613, 1613,0.000000 },
- { 859, 859, 0, 0, 1000, 106,0.000000 },
- { 860, 860, 0, 0, 40000, 20,0.000000 },
- { 861, 861, 0, 0, 40000, 213,0.000000 },
- { 862, 862, 0, 0, 766, 766,0.000000 },
- { 863, 863, 0, 0, 153, 153,0.000000 },
- { 864, 864, 0, 0, 626, 626,0.000000 },
- { 865, 865, 0, 0, 506, 506,0.000000 },
- { 866, 866, 0, 0, 300, 300,0.000000 },
- { 867, 867, 0, 0, 40000, 33,0.000000 },
- { 868, 868, 0, 0, 40000, 33,0.000000 },
- { 869, 869, 0, 0, 40000, 20,0.000000 },
- { 870, 870, 0, 0, 2106, 2106,0.000000 },
- { 871, 871, 0, 0, 93, 93,0.000000 },
- { 872, 872, 0, 0, 213, 213,0.000000 },
- { 361, 361, 0, 0, 80, 80,0.000000 },
- { 873, 873, 0, 0, 100, 100,0.000000 },
- { 874, 874, 0, 0, 80, 80,0.000000 },
- { 875, 875, 0, 0, 300, 300,0.000000 },
- { 876, 876, 0, 0, 3186, 3186,0.000000 },
- { 877, 877, 0, 0, 226, 226,0.000000 },
- { 878, 878, 0, 0, 53, 53,0.000000 },
- { 879, 879, 0, 0, 2833, 2833,0.000000 },
- { 880, 880, 0, 0, 113, 113,0.000000 },
- { 881, 881, 0, 0, 40000, 40,0.000000 },
- { 882, 882, 0, 0, 40000, 300,0.000000 },
- { 883, 883, 0, 0, 2793, 2793,0.000000 },
- { 884, 884, 36, 0, 73, 73,0.000000 },
- { 885, 885, 48, 0, 60, 60,0.000000 },
- { 885, 885, 36, 0, 73, 73,0.000000 },
- { 886, 886, 36, 0, 20, 20,0.000000 },
- { 887, 887, 32, 0, 46, 46,0.000000 },
- { 767, 767, 96, 0, 580, 580,0.000000 },
- { 888, 888, 30, 0, 53, 53,0.000000 },
- { 889, 889, 35, 0, 106, 106,0.000000 },
- { 890, 890, 60, 0, 86, 86,0.000000 },
- { 884, 884, 59, 0, 40, 40,0.000000 },
- { 890, 890, 44, 0, 80, 80,0.000000 },
- { 891, 891, 41, 0, 166, 166,0.000000 },
- { 892, 892, 47, 0, 40, 40,0.000000 },
- { 891, 891, 44, 0, 140, 140,0.000000 },
- { 891, 891, 48, 0, 153, 153,0.000000 },
- { 893, 893, 62, 0, 606, 606,0.000000 },
- { 891, 891, 51, 0, 160, 160,0.000000 },
- { 891, 891, 54, 0, 160, 160,0.000000 },
- { 894, 894, 40, 0, 386, 386,0.000000 },
- { 891, 891, 57, 0, 113, 113,0.000000 },
- { 895, 895, 97, 0, 73, 73,0.000000 },
- { 896, 896, 50, 0, 86, 86,0.000000 },
- { 376, 376, 60, 0, 153, 153,0.000000 },
- { 897, 897, 53, 0, 33, 33,0.000000 },
- { 898, 898, 46, 0, 53, 53,0.000000 },
- { 897, 897, 57, 0, 33, 33,0.000000 },
- { 899, 899, 42, 0, 193, 193,0.000000 },
- { 899, 899, 37, 0, 200, 200,0.000000 },
- { 900, 900, 41, 0, 200, 200,0.000000 },
- { 900, 900, 37, 0, 193, 193,0.000000 },
- { 871, 871, 77, 0, 46, 46,0.000000 },
- { 871, 871, 72, 0, 40, 40,0.000000 },
- { 388, 388, 70, 0, 46, 46,0.000000 },
- { 901, 901, 39, 0, 173, 173,0.000000 },
- { 902, 902, 36, 0, 1006, 1006,0.000000 },
- { 903, 903, 46, 0, 33, 33,0.000000 },
- { 904, 904, 48, 0, 680, 680,0.000000 },
- { 905, 905, 85, 0, 33, 33,0.000000 },
- { 361, 361, 66, 0, 60, 60,0.000000 },
- { 906, 906, 41, 0, 106, 106,0.000000 },
- { 907, 907, 41, 0, 93, 93,0.000000 },
- { 908, 908, 81, 0, 33, 33,0.000000 },
- { 400, 400, 10, 0, 313, 313,0.000000 },
- { 886, 886, 60, 0, 13, 13,0.000000 },
- { 873, 873, 53, 0, 166, 166,0.000000 },
- { 909, 909, 0, 0, 566, 566,0.000000 },
- { 910, 910, 0, 0, 1313, 1313,0.000000 },
- { 911, 911, 0, 0, 760, 760,0.000000 },
- { 912, 912, 0, 0, 760, 760,0.000000 },
- { 913, 913, 0, 0, 1740, 1740,0.000000 },
- { 914, 914, 0, 0, 1900, 1900,0.000000 },
- { 915, 915, 0, 0, 1173, 1173,0.000000 },
- { 916, 916, 0, 0, 1233, 1233,0.000000 },
- { 917, 917, 0, 0, 493, 493,0.000000 },
- { 362, 362, 0, 0, 246, 246,0.000000 },
- { 918, 918, 0, 0, 226, 226,0.000000 },
- { 919, 919, 0, 0, 1740, 1740,0.000000 },
- { 920, 920, 0, 0, 246, 246,0.000000 },
- { 921, 921, 0, 0, 120, 120,0.000000 },
- { 922, 922, 0, 0, 606, 606,0.000000 },
- { 923, 923, 0, 0, 333, 333,0.000000 },
- { 924, 924, 0, 0, 40000, 6,0.000000 },
- { 925, 925, 0, 0, 40000, 6,0.000000 },
- { 926, 926, 0, 0, 13, 13,0.000000 },
- { 927, 927, 0, 0, 40000, 66,0.000000 },
- { 928, 928, 0, 0, 40000, 26,0.000000 },
- { 929, 929, 0, 0, 40000, 20,0.000000 },
- { 930, 930, 0, 0, 40000, 20,0.000000 },
- { 931, 931, 0, 0, 40000, 33,0.000000 },
- { 932, 932, 0, 0, 866, 866,0.000000 },
- { 933, 933, 0, 0, 566, 566,0.000000 },
- { 934, 934, 0, 0, 1900, 1900,0.000000 },
- { 935, 935, 0, 0, 1146, 1146,0.000000 },
- { 936, 936, 0, 0, 606, 606,0.000000 },
- { 937, 937, 0, 0, 4673, 4673,0.000000 },
- { 938, 938, 0, 0, 3126, 3126,0.000000 },
- { 939, 939, 0, 0, 2406, 2406,0.000000 },
- { 940, 940, 0, 0, 440, 440,0.000000 },
- { 941, 941, 0, 0, 3200, 3200,0.000000 },
- { 942, 942, 0, 0, 1000, 1000,0.000000 },
- { 943, 943, 0, 0, 593, 593,0.000000 },
- { 944, 944, 0, 0, 546, 546,0.000000 },
- { 945, 945, 0, 0, 620, 620,0.000000 },
- { 946, 946, 0, 0, 1206, 1206,0.000000 },
- { 947, 947, 0, 0, 680, 680,0.000000 },
- { 948, 948, 0, 0, 40000, 20,0.000000 },
- { 949, 949, 0, 0, 40000, 20,0.000000 },
- { 950, 950, 0, 0, 4793, 33,0.000000 },
- { 951, 951, 0, 0, 1773, 1773,0.000000 },
- { 952, 952, 0, 0, 40000, 86,0.000000 },
- { 953, 953, 0, 0, 173, 173,0.000000 },
- { 954, 954, 0, 0, 406, 406,0.000000 },
- { 955, 955, 0, 0, 280, 280,0.000000 },
- { 956, 956, 0, 0, 5453, 33,0.000000 },
- { 957, 957, 0, 0, 2466, 100,0.000000 },
- { 958, 958, 0, 0, 973, 973,0.000000 },
- { 959, 959, 0, 0, 40000, 53,0.000000 },
- { 960, 960, 0, 0, 40000, 33,0.000000 },
- { 961, 961, 0, 0, 1026, 13,0.000000 },
- { 962, 962, 0, 0, 166, 166,0.000000 },
- { 963, 963, 0, 0, 806, 806,0.000000 },
- { 964, 964, 0, 0, 40000, 20,0.000000 },
- { 965, 965, 0, 0, 60, 20,0.000000 },
- { 966, 966, 0, 0, 1020, 1020,0.000000 },
- { 967, 967, 0, 0, 3426, 3426,0.000000 },
- { 968, 968, 0, 0, 40000, 20,0.000000 },
- { 969, 969, 0, 0, 40000, 20,0.000000 },
- { 970, 970, 0, 0, 40000, 106,0.000000 },
- { 971, 971, 0, 0, 40000, 6,0.000000 },
- { 972, 972, 0, 0, 40000, 0,0.000000 },
- { 973, 973, 0, 0, 2280, 2280,0.000000 },
- { 974, 974, 0, 0, 40000, 20,0.000000 },
- { 975, 975, 0, 0, 40000, 6,0.000000 },
- { 976, 976, 0, 0, 40000, 6,0.000000 },
- { 977, 977, 0, 0, 40000, 0,0.000000 },
- { 978, 978, 0, 0, 40000, 6,0.000000 },
- { 979, 979, 0, 0, 40000, 33,0.000000 },
- { 980, 980, 0, 0, 40000, 0,0.000000 },
- { 981, 981, 0, 0, 40000, 13,0.000000 },
- { 982, 982, 0, 0, 40000, 20,0.000000 },
- { 983, 983, 0, 0, 40000, 33,0.000000 },
- { 984, 984, 0, 0, 40000, 20,0.000000 },
- { 985, 985, 0, 0, 40000, 33,0.000000 },
- { 986, 986, 0, 0, 40000, 20,0.000000 },
- { 987, 987, 0, 0, 40000, 6,0.000000 },
- { 988, 988, 0, 0, 1133, 1133,0.000000 },
- { 989, 989, 0, 0, 40000, 20,0.000000 },
- { 990, 990, 0, 0, 1340, 1340,0.000000 },
- { 991, 991, 0, 0, 3533, 3533,0.000000 },
- { 992, 992, 0, 0, 40000, 6,0.000000 },
- { 993, 993, 0, 0, 40000, 26,0.000000 },
- { 994, 994, 0, 0, 4140, 4140,0.000000 },
- { 995, 995, 0, 0, 1206, 1206,0.000000 },
- { 996, 996, 0, 0, 40000, 173,0.000000 },
- { 997, 997, 0, 0, 380, 80,0.000000 },
- { 998, 998, 0, 0, 40000, 26,0.000000 },
- { 999, 999, 0, 0, 40000, 20,0.000000 },
- {1000,1000, 0, 0, 2893, 2893,0.000000 },
- {1001,1001, 0, 0, 40000, 73,0.000000 },
- {1002,1002, 0, 0, 40000, 126,0.000000 },
- {1003,1003, 0, 0, 4373, 4373,0.000000 },
- {1004,1004, 0, 0, 40000, 240,0.000000 },
- {1005,1005, 0, 0, 993, 993,0.000000 },
- {1006,1006, 0, 0, 760, 760,0.000000 },
- {1007,1007, 0, 0, 1380, 1380,0.000000 },
- {1008,1008, 0, 0, 726, 53,0.000000 },
- {1009,1009, 0, 0, 40000, 33,0.000000 },
- {1010,1010, 0, 0, 40000, 213,0.000000 },
- {1011,1011, 0, 0, 1046, 1046,0.000000 },
- {1012,1012, 0, 0, 273, 273,0.000000 },
- {1013,1013, 0, 0, 626, 626,0.000000 },
- {1014,1014, 0, 0, 1166, 1166,0.000000 },
- {1015,1015, 0, 0, 153, 153,0.000000 },
- {1016,1016, 0, 0, 40000, 6,0.000000 },
- {1017,1017, 0, 0, 40000, 33,0.000000 },
- {1018,1018, 0, 0, 40000, 20,0.000000 },
- {1019,1019, 0, 0, 2106, 2106,0.000000 },
- { 444, 444, 0, 0, 86, 86,0.000000 },
- {1020,1020, 0, 0, 180, 180,0.000000 },
- { 449, 449, 0, 0, 80, 80,0.000000 },
- { 453, 453, 0, 0, 20, 20,0.000000 },
- {1021,1021, 0, 0, 20, 20,0.000000 },
- {1022,1022, 0, 0, 246, 246,0.000000 },
- {1023,1023, 0, 0, 3186, 3186,0.000000 },
- {1024,1024, 0, 0, 226, 226,0.000000 },
- {1025,1025, 0, 0, 186, 186,0.000000 },
- {1026,1026, 0, 0, 2833, 2833,0.000000 },
- {1027,1027, 0, 0, 2460, 2460,0.000000 },
- {1028,1028, 0, 0, 40000, 40,0.000000 },
- {1029,1029, 0, 0, 40000, 286,0.000000 },
- {1030,1030, 0, 0, 40000, 146,0.000000 },
- {1031,1031, 0, 0, 586, 586,0.000000 },
- {1032,1032, 32, 0, 46, 46,0.000000 },
- {1033,1033, 30, 0, 26, 26,0.000000 },
- {1034,1034, 96, 0, 40, 40,0.000000 },
- {1035,1035, 60, 0, 186, 186,0.000000 },
- {1036,1036, 0, 0, 1100, 1100,0.000000 },
- {1037,1037, 0, 0, 40000, 33,0.000000 },
- {1038,1038, 0, 0, 1740, 1740,0.000000 },
- {1039,1039, 0, 0, 1793, 1793,0.000000 },
- {1040,1040, 0, 0, 160, 160,0.000000 },
- {1041,1041, 0, 0, 1206, 1206,0.000000 },
- {1042,1042, 0, 0, 353, 353,0.000000 },
- {1043,1043, 0, 0, 40000, 6,0.000000 },
- {1044,1044, 0, 0, 40000, 0,0.000000 },
- {1045,1045, 0, 0, 40000, 20,0.000000 },
- {1046,1046, 0, 0, 1186, 1186,0.000000 },
- {1047,1047, 0, 0, 1093, 1093,0.000000 },
- {1048,1048, 0, 0, 620, 620,0.000000 },
- {1049,1049, 0, 0, 4440, 4440,0.000000 },
- {1050,1050, 0, 0, 4506, 4506,0.000000 },
- {1051,1051, 0, 0, 4673, 4673,0.000000 },
- {1052,1052, 0, 0, 2386, 2386,0.000000 },
- {1053,1053, 0, 0, 40000, 146,0.000000 },
- {1054,1054, 0, 0, 1180, 1180,0.000000 },
- {1055,1055, 0, 0, 320, 320,0.000000 },
- {1056,1056, 0, 0, 633, 633,0.000000 },
- {1057,1057, 0, 0, 80, 80,0.000000 },
- {1058,1058, 0, 0, 1180, 1180,0.000000 },
- {1059,1059, 0, 0, 6120, 100,0.000000 },
- {1060,1060, 0, 0, 86, 86,0.000000 },
- {1061,1061, 0, 0, 206, 206,0.000000 },
- {1062,1062, 0, 0, 40000, 86,0.000000 },
- {1063,1063, 0, 0, 40000, 266,0.000000 },
- {1064,1064, 0, 0, 806, 806,0.000000 },
- {1065,1065, 0, 0, 40000, 20,0.000000 },
- {1066,1066, 0, 0, 40000, 53,0.000000 },
- {1067,1067, 0, 0, 40000, 53,0.000000 },
- {1068,1068, 0, 0, 40000, 26,0.000000 },
- {1069,1069, 0, 0, 40000, 20,0.000000 },
- {1070,1070, 0, 0, 40000, 20,0.000000 },
- {1071,1071, 0, 0, 40000, 6,0.000000 },
- {1072,1072, 0, 0, 40000, 26,0.000000 },
- {1073,1073, 0, 0, 40000, 13,0.000000 },
- {1074,1074, 0, 0, 40000, 60,0.000000 },
- {1075,1075, 0, 0, 213, 213,0.000000 },
- {1076,1076, 0, 0, 40000, 73,0.000000 },
- {1077,1077, 0, 0, 4513, 4513,0.000000 },
- {1078,1078, 0, 0, 313, 313,0.000000 },
- {1079,1079, 0, 0, 4273, 4273,0.000000 },
- {1080,1080, 0, 0, 40000, 26,0.000000 },
- {1081,1081, 0, 0, 3153, 3153,0.000000 },
- {1082,1082, 0, 0, 40000, 180,0.000000 },
- {1083,1083, 0, 0, 40000, 213,0.000000 },
- {1084,1084, 0, 0, 1740, 13,0.000000 },
- {1085,1085, 0, 0, 2853, 2853,0.000000 },
- {1086,1086, 0, 0, 40000, 213,0.000000 },
- {1087,1087, 0, 0, 3946, 3946,0.000000 },
- {1088,1088, 0, 0, 2253, 2253,0.000000 },
- {1089,1089, 0, 0, 40000, 260,0.000000 },
- {1090,1090, 0, 0, 166, 166,0.000000 },
- {1091,1091, 0, 0, 40000, 493,0.000000 },
- {1092,1092, 0, 0, 2126, 2126,0.000000 },
- {1093,1093, 0, 0, 40000, 480,0.000000 },
- {1094,1094, 0, 0, 40000, 213,0.000000 },
- {1095,1095, 0, 0, 146, 146,0.000000 },
- {1096,1096, 0, 0, 333, 333,0.000000 },
- {1097,1097, 0, 0, 466, 466,0.000000 },
- {1098,1098, 0, 0, 40000, 40,0.000000 },
- {1099,1099, 0, 0, 4926, 4926,0.000000 },
- {1100,1100, 0, 0, 5113, 5113,0.000000 },
- {1101,1101, 0, 0, 3060, 13,0.000000 },
- {1102,1102, 0, 0, 420, 420,0.000000 },
- {1103,1103, 0, 0, 300, 300,0.000000 },
- {1104,1104, 0, 0, 4426, 4426,0.000000 },
- {1105,1105, 0, 0, 5513, 5513,0.000000 },
- {1106,1106, 0, 0, 40000, 233,0.000000 },
- { 430, 430, 0, 0, 300, 300,0.000000 },
- {1107,1107, 35, 0, 73, 73,0.000000 },
- {1090,1090, 77, 0, 80, 80,0.000000 },
- {1090,1090, 72, 0, 80, 80,0.000000 },
- {1108,1108, 0, 0, 60, 60,0.000000 },
- {1109,1109, 0, 0, 1453, 1453,0.000000 },
- {1110,1111, 0, 1, 506, 506,0.000000 },
- {1112,1113, 0, 1, 1253, 1253,0.031250 },
- {1114,1114, 0, 0, 866, 866,0.000000 },
- {1115,1116, 0, 1, 1473, 1473,0.000000 },
- {1117,1117, 0, 0, 1600, 1600,0.000000 },
- {1118,1118, 0, 0, 680, 680,0.000000 },
- {1119,1119, 0, 0, 1133, 1133,0.000000 },
- {1120,1120, 0, 0, 1013, 1013,0.000000 },
- {1121,1121, 0, 0, 860, 860,0.000000 },
- {1122,1122, 0, 0, 1473, 1473,0.000000 },
- {1123,1123, 0, 0, 280, 280,0.000000 },
- {1124,1124, 0, 0, 53, 53,0.000000 },
- {1125,1125, 0, 0, 1260, 1260,0.000000 },
- {1126,1126, 0, 0, 906, 906,0.000000 },
- {1127,1127, 0, 0, 40000, 66,0.000000 },
- {1128,1128, 0, 0, 260, 13,0.000000 },
- {1129,1130, 0, 1, 13973, 13,0.156250 },
- {1131,1131, 0, 0, 40000, 173,0.000000 },
- {1132,1132, 0, 0, 40000, 53,0.000000 },
- {1133,1134, 0, 1, 40000, 20,-0.046875 },
- {1135,1135, 0, 0, 40000, 26,0.000000 },
- {1136,1137, 0, 1, 40000, 113,0.000025 },
- {1138,1138, 0, 0, 3366, 3366,0.000000 },
- {1139,1139, 0, 0, 400, 400,0.000000 },
- {1140,1140, 0, 0, 473, 473,0.000000 },
- {1141,1141, 0, 0, 840, 840,0.000000 },
- {1142,1142, 0, 0, 800, 800,0.000000 },
- {1143,1143, 0, 0, 2173, 0,0.000000 },
- {1144,1144, 0, 0, 40000, 0,0.000000 },
- {1145,1145, 0, 0, 1433, 1433,0.000000 },
- {1146,1146, 0, 0, 386, 386,0.000000 },
- {1147,1147, 0, 0, 1253, 1253,0.000000 },
- {1148,1148, 0, 0, 1606, 1606,0.000000 },
- {1149,1150, 0, 1, 1553, 1553,-0.031250 },
- {1151,1151, 0, 0, 40000, 6,0.000000 },
- {1152,1152, 0, 0, 1560, 1560,0.000000 },
- {1153,1153, 0, 0, 386, 386,0.000000 },
- {1154,1154, 0, 1, 40000, 20,-0.156250 },
- {1155,1155, 0, 0, 3886, 6,0.000000 },
- {1156,1156, 0, 0, 40000, 66,0.000000 },
- {1157,1157, 0, 0, 40000, 60,0.000000 },
- {1158,1158, 0, 0, 40000, 266,0.000000 },
- {1159,1160, 0, 1, 40000, 273,0.171875 },
- {1161,1161, 0, 0, 173, 173,0.000000 },
- {1162,1162, 0, 0, 993, 993,0.000000 },
- {1163,1163, 0, 0, 726, 726,0.000000 },
- {1164,1165, 0, 1, 40000, 206,-0.125000 },
- {1166,1167, 0, 1, 40000, 266,0.078125 },
- {1168,1168, 0, 1, 40000, 1073,-0.078125 },
- {1169,1170, 0, 1, 40000, 253,0.062500 },
- {1171,1172, 0, 1, 40000, 533,0.156250 },
- {1173,1173, 0, 0, 1813, 1813,0.000000 },
- {1174,1174, 0, 0, 40000, 200,0.000000 },
- {1175,1176, 0, 1, 360, 360,0.000000 },
- {1177,1177, 0, 0, 40000, 6,0.000000 },
- {1178,1178, 0, 0, 806, 6,0.000000 },
- {1179,1179, 0, 0, 1600, 1600,0.000000 },
- {1180,1180, 0, 0, 60, 60,0.000000 },
- {1181,1182, 0, 1, 3153, 3153,0.000025 },
- {1183,1184, 0, 1, 826, 6,0.046875 },
- {1185,1186, 0, 1, 3106, 3106,0.093750 },
- {1187,1188, 0, 1, 1020, 1020,0.093750 },
- {1189,1189, 0, 0, 40000, 33,0.000000 },
- {1190,1190, 0, 0, 40000, 20,0.000000 },
- {1191,1191, 0, 0, 40000, 0,0.000000 },
- {1192,1192, 0, 0, 266, 6,0.000000 },
- {1193,1193, 0, 0, 40000, 33,0.000000 },
- {1194,1194, 0, 0, 40000, 26,0.000000 },
- {1195,1195, 0, 0, 40000, 0,0.000000 },
- {1196,1196, 0, 0, 40000, 13,0.000000 },
- {1197,1197, 0, 0, 40000, 0,0.000000 },
- {1198,1198, 0, 0, 40000, 6,0.000000 },
- {1199,1199, 0, 0, 40000, 53,0.000000 },
- {1200,1200, 0, 0, 40000, 20,0.000000 },
- {1201,1201, 0, 0, 40000, 20,0.000000 },
- {1202,1202, 0, 0, 140, 140,0.000000 },
- {1203,1203, 0, 0, 40000, 93,0.000000 },
- {1204,1204, 0, 0, 40000, 6,0.000000 },
- {1205,1206, 0, 1, 40000, 86,0.031250 },
- {1207,1208, 0, 1, 40000, 100,-0.000025 },
- {1209,1209, 0, 0, 40000, 53,0.000000 },
- {1210,1211, 0, 1, 40000, 0,0.031250 },
- {1212,1212, 0, 0, 40000, 0,0.000000 },
- {1213,1214, 0, 1, 40000, 320,-0.093750 },
- {1215,1216, 0, 1, 1660, 80,-0.046875 },
- {1217,1217, 0, 0, 40000, 66,0.000000 },
- {1218,1219, 0, 1, 40000, 233,0.031250 },
- {1220,1220, 0, 1, 1960, 1960,0.031250 },
- {1221,1222, 0, 1, 17500, 46,0.171875 },
- {1223,1223, 0, 0, 2273, 2273,0.000000 },
- {1224,1224, 0, 0, 1933, 1933,0.000000 },
- {1225,1150, 0, 1, 3126, 13,-0.031250 },
- {1226,1226, 0, 0, 40000, 640,0.000000 },
- {1227,1227, 0, 0, 1080, 1080,0.000000 },
- {1228,1229, 0, 1, 40000, 33,0.125000 },
- {1230,1230, 0, 0, 1046, 1046,0.000000 },
- {1231,1232, 0, 1, 1553, 1553,-0.031250 },
- {1233,1234, 0, 1, 2066, 2066,-0.187500 },
- {1235,1235, 0, 0, 40000, 466,0.000000 },
- {1236,1236, 0, 0, 400, 400,0.000000 },
- {1237,1237, 0, 0, 2706, 2706,0.000000 },
- {1238,1238, 0, 0, 1220, 1220,0.000000 },
- {1239,1239, 0, 0, 446, 446,0.000000 },
- {1240,1241, 0, 1, 360, 360,0.000000 },
- {1242,1242, 0, 0, 4806, 4806,0.000000 },
- {1243,1243, 0, 0, 80, 80,0.000000 },
- {1244,1244, 0, 0, 40000, 80,0.000000 },
- {1245,1245, 0, 0, 40000, 86,0.000000 },
- {1246,1246, 0, 0, 40000, 40,0.000000 },
- {1247,1247, 0, 0, 1920, 1920,0.000000 },
- {1248,1248, 0, 0, 66, 66,0.000000 },
- {1249,1249, 0, 0, 40000, 233,0.000000 },
- {1250,1250, 0, 0, 113, 113,0.000000 },
- {1251,1251, 0, 0, 46, 46,0.000000 },
- {1252,1252, 0, 0, 140, 140,0.000000 },
- {1253,1253, 0, 0, 886, 886,0.000000 },
- {1254,1254, 0, 0, 1080, 1080,0.000000 },
- {1255,1255, 0, 0, 206, 206,0.000000 },
- {1256,1256, 0, 0, 280, 280,0.000000 },
- {1257,1257, 0, 0, 2873, 2873,0.000000 },
- {1258,1258, 0, 0, 313, 313,0.000000 },
- {1259,1259, 0, 0, 40000, 73,0.000000 },
- {1260,1260, 29, 0, 1320, 1320,0.000000 },
- {1261,1261, 65, 0, 40000, 1746,0.000000 },
- {1262,1262, 0, 0, 153, 153,0.000000 },
- {1263,1263, 25, 0, 33, 33,0.000000 },
- {1264,1264, 83, 0, 53, 53,0.000000 },
- {1265,1265, 32, 0, 40, 40,0.000000 },
- {1266,1266, 60, 0, 46, 46,0.000000 },
- {1267,1267, 36, 0, 46, 46,0.000000 },
- {1268,1268, 27, 0, 13, 13,0.000000 },
- {1269,1269, 31, 0, 266, 266,0.000000 },
- {1270,1270, 21, 0, 246, 246,0.000000 },
- {1270,1270, 26, 0, 253, 253,0.000000 },
- {1270,1270, 28, 0, 260, 260,0.000000 },
- {1271,1271, 60, 0, 280, 280,0.000000 },
- {1270,1270, 32, 0, 206, 206,0.000000 },
- {1272,1272, 60, 0, 260, 260,0.000000 },
- {1273,1273, 96, 0, 140, 140,0.000000 },
- {1274,1274, 72, 0, 133, 133,0.000000 },
- {1275,1275, 79, 0, 46, 46,0.000000 },
- {1276,1276, 69, 0, 126, 126,0.000000 },
- {1277,1277, 71, 0, 146, 146,0.000000 },
- {1278,1278, 22, 0, 566, 566,0.000000 },
- {1279,1279, 55, 0, 66, 66,0.000000 },
- {1279,1279, 48, 0, 80, 80,0.000000 },
- {1280,1280, 0, 0, 6, 6,0.000000 },
- {1281,1281, 49, 0, 6, 6,0.000000 },
- {1282,1282, 73, 0, 60, 60,0.000000 },
- {1282,1282, 68, 0, 60, 60,0.000000 },
- {1282,1282, 61, 0, 80, 80,0.000000 },
- {1283,1283, 0, 0, 6, 6,0.000000 },
- {1284,1284, 0, 0, 40000, 46,0.000000 },
- {1285,1285, 0, 0, 40000, 20,0.000000 },
- {1286,1286, 0, 0, 2380, 2380,0.000000 },
- {1287,1287, 0, 0, 700, 700,0.000000 },
- {1288,1289, 0, 1, 653, 6,0.000000 },
- {1290,1290, 0, 0, 80, 80,0.000000 },
- {1291,1292, 36, 1, 46, 46,0.000000 },
- {1293,1293, 69, 0, 126, 126,0.000000 },
- {1294,1294, 0, 0, 120, 120,0.000000 },
- {1295,1295, 0, 0, 40000, 0,0.000000 },
- {1296,1296, 0, 0, 1173, 1173,0.000000 },
- {1297,1297, 22, 0, 566, 566,0.000000 },
- {1298,1298, 0, 0, 40000, 0,0.000000 },
- {1299,1299, 0, 0, 993, 993,0.000000 },
- {1300,1300, 0, 0, 1900, 1900,0.000000 },
- {1301,1301, 0, 0, 1046, 1046,0.000000 },
- {1302,1302, 0, 0, 293, 293,0.000000 },
- {1303,1303, 0, 0, 40000, 33,0.000000 },
- {1304,1304, 0, 0, 40000, 6,0.000000 },
- {1305,1305, 0, 0, 40000, 20,0.000000 },
- {1306,1306, 0, 0, 40000, 193,0.000000 },
- {1307,1307, 0, 0, 40000, 153,0.000000 },
- {1308,1308, 0, 0, 40000, 6,0.000000 },
- {1309,1309, 0, 0, 40000, 46,0.000000 },
- {1310,1310, 0, 0, 40000, 73,0.000000 },
- {1311,1311, 0, 0, 920, 920,0.000000 },
- {1312,1312, 0, 0, 4580, 4580,0.000000 },
- {1313,1313, 0, 0, 1026, 1026,0.000000 },
- {1314,1314, 0, 0, 40000, 6,0.000000 },
- {1315,1315, 0, 0, 3746, 13,0.000000 },
- {1316,1316, 0, 0, 40000, 233,0.000000 },
- {1317,1317, 0, 0, 40000, 153,0.000000 },
- {1318,1318, 0, 0, 40000, 140,0.000000 },
- {1319,1319, 0, 0, 2620, 2620,0.000000 },
- {1320,1320, 0, 0, 40000, 140,0.000000 },
- {1321,1321, 0, 0, 233, 233,0.000000 },
- {1322,1322, 0, 0, 40000, 6,0.000000 },
- {1323,1323, 0, 0, 40000, 0,0.000000 },
- {1324,1324, 0, 0, 40000, 26,0.000000 },
- {1325,1325, 0, 0, 40000, 6,0.000000 },
- { 260, 260, 0, 0, 40000, 20,0.000000 },
- {1326,1326, 0, 0, 40000, 20,0.000000 },
- {1327,1327, 0, 0, 40000, 0,0.000000 },
- {1328,1328, 0, 0, 40000, 13,0.000000 },
- {1329,1329, 0, 0, 40000, 73,0.000000 },
- {1330,1330, 0, 0, 40000, 53,0.000000 },
- {1331,1331, 0, 0, 40000, 66,0.000000 },
- {1332,1332, 0, 0, 40000, 66,0.000000 },
- {1333,1333, 0, 0, 40000, 6,0.000000 },
- {1334,1334, 0, 0, 40000, 73,0.000000 },
- {1335,1335, 0, 0, 40000, 133,0.000000 },
- {1336,1336, 0, 0, 40000, 233,0.000000 },
- {1337,1337, 0, 0, 40000, 406,0.000000 },
- {1338,1338, 0, 0, 1766, 93,0.000000 },
- {1339,1339, 0, 0, 40000, 533,0.000000 },
- {1340,1340, 0, 0, 40000, 106,0.000000 },
- {1341,1341, 0, 0, 593, 13,0.000000 },
- {1342,1342, 0, 0, 940, 940,0.000000 },
- {1343,1343, 0, 0, 40000, 53,0.000000 },
- {1344,1344, 0, 0, 2006, 2006,0.000000 },
- {1345,1345, 0, 0, 40000, 933,0.000000 },
- {1346,1346, 0, 0, 973, 973,0.000000 },
- { 378, 378, 84, 0, 440, 440,0.000000 },
- {1347,1347, 24, 0, 46, 46,0.000000 },
- {1348,1348, 44, 0, 80, 80,0.000000 },
- {1349,1349, 40, 0, 306, 306,0.000000 },
- {1350,1350, 60, 0, 340, 340,0.000000 },
- {1351,1351, 0, 0, 866, 866,0.000000 },
- {1352,1352, 0, 0, 993, 993,0.000000 },
- {1353,1353, 0, 0, 633, 633,0.000000 },
- {1354,1354, 0, 0, 40000, 40,0.000000 },
- {1355,1355, 0, 0, 973, 973,0.000000 },
- {1356,1356, 0, 0, 40000, 126,0.000000 },
- {1357,1357, 0, 0, 166, 166,0.000000 },
- {1358,1358, 0, 0, 640, 640,0.000000 },
- {1359,1359, 0, 0, 100, 100,0.000000 },
- {1360,1360, 0, 0, 40000, 113,0.000000 },
- {1361,1361, 0, 0, 40000, 240,0.000000 },
- {1362,1362, 0, 0, 3793, 80,0.000000 },
- {1363,1363, 0, 0, 40000, 240,0.000000 },
- {1364,1364, 0, 0, 126, 126,0.000000 },
- {1365,1365, 0, 0, 40000, 20,0.000000 },
- {1366,1366, 0, 0, 40000, 26,0.000000 },
- {1367,1367, 0, 0, 2233, 6,0.000000 },
- {1368,1368, 0, 0, 40000, 53,0.000000 },
- {1369,1369, 0, 0, 40000, 33,0.000000 },
- {1370,1370, 0, 0, 40000, 13,0.000000 },
- {1371,1371, 0, 0, 40000, 13,0.000000 },
- {1372,1372, 0, 0, 40000, 26,0.000000 },
- {1373,1373, 0, 0, 40000, 6,0.000000 },
- {1374,1374, 0, 0, 40000, 13,0.000000 },
- {1375,1375, 0, 0, 4473, 13,0.000000 },
- {1376,1376, 0, 0, 146, 146,0.000000 },
- {1377,1377, 0, 0, 86, 86,0.000000 },
- {1378,1378, 35, 0, 73, 73,0.000000 },
- {1379,1379, 49, 0, 40, 40,0.000000 },
- {1377,1377, 48, 0, 80, 80,0.000000 },
- {1380,1380, 58, 0, 40, 40,0.000000 },
- {1377,1377, 60, 0, 86, 86,0.000000 },
- {1381,1381, 47, 0, 106, 106,0.000000 },
- {1382,1382, 60, 0, 20, 20,0.000000 },
- {1381,1381, 49, 0, 153, 153,0.000000 },
- {1383,1383, 72, 0, 80, 80,0.000000 },
- {1381,1381, 51, 0, 200, 200,0.000000 },
- {1384,1384, 84, 0, 273, 273,0.000000 },
- {1381,1381, 54, 0, 233, 233,0.000000 },
- {1381,1381, 57, 0, 260, 260,0.000000 },
- {1385,1385, 72, 0, 506, 506,0.000000 },
- {1381,1381, 60, 0, 306, 306,0.000000 },
- {1386,1386, 36, 0, 866, 866,0.000000 },
- {1387,1387, 93, 0, 66, 66,0.000000 },
- {1388,1388, 72, 0, 273, 273,0.000000 },
- {1389,1389, 84, 0, 426, 426,0.000000 },
- {1390,1390, 36, 0, 20, 20,0.000000 },
- {1391,1391, 64, 0, 86, 86,0.000000 },
- {1392,1392, 68, 0, 26, 26,0.000000 },
- {1393,1393, 0, 0, 1226, 1226,0.000000 },
- {1394,1394, 0, 0, 40000, 140,0.000000 },
- {1395,1395, 0, 0, 40000, 0,0.000000 },
- {1396,1396, 0, 0, 513, 513,0.000000 },
- {1397,1397, 0, 0, 40000, 126,0.000000 },
- {1398,1398, 0, 0, 320, 320,0.000000 },
- {1399,1399, 0, 0, 40000, 0,0.000000 },
- {1400,1400, 0, 0, 1766, 1766,0.000000 },
- {1401,1401, 0, 0, 2513, 2513,0.000000 },
- {1402,1402, 0, 0, 1300, 1300,0.000000 },
- {1403,1403, 0, 0, 46, 46,0.000000 },
- {1404,1404, 0, 0, 186, 6,0.000000 },
- {1405,1405, 0, 0, 40000, 6,0.000000 },
- {1406,1406, 0, 0, 40, 26,0.000000 },
- {1407,1407, 0, 0, 166, 166,0.000000 },
- {1408,1408, 0, 0, 2193, 2193,0.000000 },
- {1409,1409, 0, 0, 40000, 206,0.000000 },
- {1410,1410, 0, 0, 40000, 1460,0.000000 },
- {1411,1411, 0, 0, 166, 166,0.000000 },
- {1412,1412, 0, 0, 1380, 1380,0.000000 },
- {1413,1413, 0, 0, 533, 533,0.000000 },
- {1414,1414, 0, 0, 40000, 33,0.000000 },
- {1415,1415, 0, 0, 40000, 53,0.000000 },
- {1416,1416, 0, 0, 40000, 0,0.000000 },
- {1417,1417, 0, 0, 40000, 6,0.000000 },
- {1418,1418, 0, 0, 40000, 6,0.000000 },
- {1419,1419, 0, 0, 913, 913,0.000000 },
- {1420,1420, 0, 0, 1233, 6,0.000000 },
- {1421,1421, 0, 0, 126, 126,0.000000 },
- {1422,1422, 0, 0, 40000, 46,0.000000 },
- {1423,1423, 0, 0, 933, 933,0.000000 },
- {1424,1424, 0, 0, 1846, 1846,0.000000 },
- {1425,1425, 0, 0, 973, 973,0.000000 },
- {1426,1426, 0, 0, 160, 160,0.000000 },
- {1427,1427, 0, 0, 40000, 106,0.000000 },
- {1428,1428, 0, 0, 120, 120,0.000000 },
- {1429,1429, 0, 0, 40000, 6,0.000000 },
- {1430,1430, 0, 0, 93, 93,0.000000 },
- {1431,1431, 0, 0, 40, 40,0.000000 },
- {1432,1432, 0, 0, 2420, 2420,0.000000 },
- {1433,1433, 0, 0, 1153, 1153,0.000000 },
- {1434,1434, 0, 0, 2406, 2406,0.000000 },
- { 740, 740, 0, 0, 80, 80,0.000000 },
- {1435,1435, 0, 0, 40000, 3220,0.000000 },
- { 739, 739, 48, 0, 93, 93,0.000000 },
- { 500, 500, 55, 0, 13, 13,0.000000 },
- { 740, 740, 60, 0, 53, 53,0.000000 },
- { 500, 500, 41, 0, 13, 13,0.000000 },
- {1436,1436, 84, 0, 40, 40,0.000000 },
- {1437,1437, 84, 0, 73, 73,0.000000 },
- { 500, 500, 48, 0, 13, 13,0.000000 },
- {1438,1438, 15, 0, 86, 86,0.000000 },
- { 752, 752, 49, 0, 46, 46,0.000000 },
- {1438,1438, 16, 0, 93, 93,0.000000 },
- {1438,1438, 12, 0, 86, 86,0.000000 },
- { 740, 740, 55, 0, 53, 53,0.000000 },
- { 752, 752, 18, 0, 46, 46,0.000000 },
- { 752, 752, 15, 0, 46, 46,0.000000 },
- { 752, 752, 17, 0, 46, 46,0.000000 },
- {1439,1440, 0, 0, 1340, 1340,0.000000 },
- {1441,1442, 0, 0, 1113, 1113,0.000000 },
- {1443,1444, 0, 0, 2133, 2133,0.000000 },
- {1445,1446, 0, 0, 953, 953,0.000000 },
- {1447,1448, 0, 0, 100, 100,0.000000 },
- {1449,1450, 0, 0, 1313, 1313,0.000000 },
- { 181,1451, 0, 0, 473, 473,0.000000 },
- {1452,1453, 0, 0, 680, 680,0.000000 },
- {1454,1455, 0, 0, 260, 260,0.000000 },
- {1456,1457, 0, 0, 193, 193,0.000000 },
- {1458,1459, 0, 0, 1320, 1320,0.000000 },
- { 190,1460, 0, 0, 646, 6,0.000000 },
- { 192,1461, 0, 0, 40000, 6,0.000000 },
- {1462,1463, 0, 0, 40000, 113,0.000000 },
- {1464,1465, 0, 0, 40000, 133,0.000000 },
- {1466,1467, 0, 0, 40000, 6,0.000000 },
- {1468,1469, 0, 0, 40000, 0,0.000000 },
- { 35,1470, 0, 0, 1446, 1446,0.000000 },
- { 36,1471, 0, 0, 1606, 1606,0.000000 },
- {1472,1473, 0, 0, 1553, 1553,0.000000 },
- {1474,1475, 0, 0, 2133, 2133,0.000000 },
- { 39,1476, 0, 0, 40000, 26,0.000000 },
- {1477,1476, 0, 0, 40000, 46,0.000000 },
- {1478,1479, 0, 0, 40000, 240,0.000000 },
- { 50,1480, 0, 0, 40000, 153,0.000000 },
- {1481,1482, 0, 0, 40000, 46,0.000000 },
- {1483,1484, 0, 0, 2300, 2300,0.000000 },
- {1485,1486, 0, 0, 40000, 86,0.000000 },
- { 55,1487, 0, 0, 40000, 20,0.000000 },
- {1488,1489, 0, 0, 40000, 20,0.000000 },
- {1490,1491, 0, 0, 40000, 6,0.000000 },
- {1492,1493, 0, 0, 40000, 0,0.000000 },
- {1494,1495, 0, 0, 40000, 6,0.000000 },
- {1496,1497, 0, 0, 40000, 6,0.000000 },
- {1496,1498, 0, 0, 40000, 6,0.000000 },
- {1499,1500, 0, 0, 40000, 6,0.000000 },
- {1501,1502, 0, 0, 40000, 53,0.000000 },
- {1503,1504, 0, 0, 40000, 33,0.000000 },
- {1505,1506, 0, 0, 40000, 6,0.000000 },
- { 86,1507, 0, 0, 40000, 20,0.000000 },
- {1508,1509, 0, 0, 1766, 1766,0.000000 },
- {1510,1511, 0, 0, 2853, 13,0.000000 },
- {1512,1513, 0, 0, 593, 593,0.000000 },
- {1514,1515, 0, 0, 1126, 33,0.000000 },
- {1516,1517, 0, 0, 40000, 460,0.000000 },
- {1518,1519, 0, 0, 233, 233,0.000000 },
- {1520,1521, 0, 0, 40000, 213,0.000000 },
- {1522,1523, 0, 0, 1233, 1233,0.000000 },
- {1524,1525, 0, 0, 40000, 626,0.000000 },
- {1526,1527, 0, 0, 40000, 446,0.000000 },
- {1528,1529, 0, 0, 40000, 320,0.000000 },
- { 111,1530, 0, 0, 786, 786,0.000000 },
- {1531,1532, 0, 0, 20, 20,0.000000 },
- { 115,1533, 0, 0, 26, 26,0.000000 },
- {1534,1535, 0, 0, 166, 166,0.000000 },
- {1536,1537, 0, 0, 2280, 2280,0.000000 },
- {1538,1539, 0, 0, 280, 280,0.000000 },
- {1540, 339, 0, 0, 580, 580,0.000000 },
- {1541, 339, 0, 0, 4613, 4613,0.000000 },
- {1542,1543, 0, 0, 440, 440,0.000000 },
- {1544,1545, 0, 0, 153, 153,0.000000 },
- {1546,1547, 0, 0, 40000, 53,0.000000 },
- { 364, 365, 44, 0, 20, 20,0.000000 },
- { 129,1548, 48, 0, 66, 66,0.000000 },
- { 367, 368, 58, 0, 53, 53,0.000000 },
- { 129,1549, 60, 0, 73, 73,0.000000 },
- {1550,1551, 48, 0, 93, 93,0.000000 },
- { 132,1552, 43, 0, 13, 13,0.000000 },
- {1550,1551, 49, 0, 120, 120,0.000000 },
- {1553,1554, 43, 0, 26, 26,0.000000 },
- {1550,1551, 51, 0, 153, 153,0.000000 },
- { 134,1555, 43, 0, 146, 146,0.000000 },
- {1550,1551, 54, 0, 106, 106,0.000000 },
- {1550,1551, 57, 0, 100, 100,0.000000 },
- { 380, 381, 72, 0, 40000, 0,0.000000 },
- {1550,1551, 60, 0, 106, 106,0.000000 },
- {1556,1557, 70, 0, 246, 246,0.000000 },
- { 374, 375, 60, 0, 40000, 0,0.000000 },
- {1558,1559, 36, 0, 360, 360,0.000000 },
- {1560,1561, 65, 0, 113, 113,0.000000 },
- {1562,1563, 84, 0, 40000, 0,0.000000 },
- {1564,1565, 59, 0, 133, 133,0.000000 },
- {1566,1567, 84, 0, 40000, 0,0.000000 },
- {1568,1569, 35, 0, 53, 53,0.000000 },
- {1570,1571, 44, 0, 273, 273,0.000000 },
- {1572,1573, 67, 0, 66, 66,0.000000 },
- {1574,1575, 66, 0, 46, 46,0.000000 },
- { 145,1576, 59, 0, 13, 13,0.000000 },
- {1577,1578, 51, 0, 40, 40,0.000000 },
- {1579,1580, 45, 0, 40, 40,0.000000 },
- {1581,1582, 71, 0, 120, 120,0.000000 },
- { 149,1583, 60, 0, 180, 180,0.000000 },
- {1584,1585, 58, 0, 166, 166,0.000000 },
- {1586,1587, 53, 0, 140, 140,0.000000 },
- { 397,1588, 64, 0, 86, 86,0.000000 },
- {1589,1590, 71, 0, 13, 13,0.000000 },
- {1591,1592, 61, 0, 313, 313,0.000000 },
- {1593,1594, 61, 0, 513, 513,0.000000 },
- { 391, 392, 48, 0, 80, 80,0.000000 },
- { 391, 393, 48, 0, 80, 80,0.000000 },
- {1595,1596, 69, 0, 20, 20,0.000000 },
- { 159,1597, 68, 0, 20, 20,0.000000 },
- { 159,1597, 63, 0, 33, 33,0.000000 },
- {1598,1599, 74, 0, 333, 333,0.000000 },
- {1600,1601, 60, 0, 380, 380,0.000000 },
- {1602,1603, 80, 0, 60, 60,0.000000 },
- {1604,1605, 64, 0, 646, 646,0.000000 },
- {1606,1607, 69, 0, 33, 33,0.000000 },
- { 398, 399, 55, 0, 500, 500,0.000000 },
- {1608,1609, 75, 0, 346, 346,0.000000 },
- {1610,1611, 68, 0, 20, 20,0.000000 },
- {1612,1613, 48, 0, 46, 46,0.000000 },
- {1614,1615, 53, 0, 40, 40,0.000000 },
- {1616,1616, 0, 0, 40000, 873,0.000000 },
- {1617,1617, 0, 0, 40000, 446,0.000000 },
- {1618,1618, 0, 0, 1020, 1020,0.000000 },
- {1619,1619, 0, 0, 40000, 300,0.000000 },
- {1620,1620, 0, 0, 40000, 780,0.000000 },
- {1621,1621, 0, 0, 1400, 1400,0.000000 },
- {1622,1622, 0, 0, 40000, 480,0.000000 },
- {1623,1623, 0, 0, 40000, 566,0.000000 },
- {1624,1624, 0, 0, 3220, 3220,0.000000 },
- {1625,1625, 0, 0, 40000, 6,0.000000 },
- {1626,1626, 0, 0, 40000, 20,0.000000 },
- {1627,1627, 0, 0, 40000, 20,0.000000 },
- {1628,1628, 0, 0, 40000, 1180,0.000000 },
- {1629,1629, 0, 0, 40000, 20,0.000000 },
- {1630,1630, 0, 0, 40000, 6,0.000000 },
- {1631,1631, 0, 0, 40000, 6,0.000000 },
- {1632,1632, 0, 0, 40000, 280,0.000000 },
- {1633,1633, 0, 0, 40000, 6,0.000000 },
- {1634,1634, 0, 0, 40000, 6,0.000000 },
- {1635,1635, 0, 0, 40000, 6,0.000000 },
- {1636,1636, 0, 0, 340, 26,0.000000 },
- {1637,1637, 0, 0, 1000, 1000,0.000000 },
- {1638,1638, 0, 0, 40000, 200,0.000000 },
- {1639,1639, 0, 0, 460, 460,0.000000 },
- {1640,1640, 0, 0, 40000, 146,0.000000 },
- {1641,1641, 0, 0, 40000, 146,0.000000 },
- {1642,1642, 0, 0, 40000, 233,0.000000 },
- {1643,1643, 0, 0, 40000, 480,0.000000 },
- {1644,1644, 0, 0, 40000, 6,0.000000 },
- {1645,1645, 0, 0, 40000, 6,0.000000 },
- {1646,1646, 0, 0, 40000, 6,0.000000 },
- {1647,1647, 0, 0, 40000, 6,0.000000 },
- {1648,1648, 0, 0, 40000, 6,0.000000 },
- {1649,1649, 0, 0, 40000, 6,0.000000 },
- {1650,1650, 0, 0, 40000, 53,0.000000 },
- {1651,1651, 0, 0, 40000, 480,0.000000 },
- {1652,1652, 0, 0, 40000, 286,0.000000 },
- {1653,1653, 0, 0, 40000, 106,0.000000 },
- {1654,1654, 0, 0, 40000, 413,0.000000 },
- {1655,1655, 0, 0, 1213, 1213,0.000000 },
- {1656,1656, 0, 0, 513, 513,0.000000 },
- {1657,1657, 0, 0, 40000, 160,0.000000 },
- {1658,1658, 0, 0, 40000, 153,0.000000 },
- {1659,1659, 0, 0, 40000, 1973,0.000000 },
- {1660,1660, 0, 0, 40000, 3593,0.000000 },
- {1661,1661, 0, 0, 40000, 1120,0.000000 },
- {1662,1662, 0, 0, 620, 620,0.000000 },
- {1663,1663, 0, 0, 1740, 1740,0.000000 },
- {1664,1664, 0, 0, 940, 940,0.000000 },
- {1665,1665, 0, 0, 40000, 260,0.000000 },
- {1666,1666, 0, 0, 1900, 1900,0.000000 },
- {1667,1667, 0, 0, 40000, 426,0.000000 },
- {1668,1668, 12, 0, 66, 66,0.000000 },
- {1669,1669, 48, 0, 100, 100,0.000000 },
- { 736, 736, 52, 0, 80, 80,0.000000 },
- {1670,1670, 48, 0, 153, 153,0.000000 },
- {1670,1670, 36, 0, 146, 146,0.000000 },
- { 377, 377, 84, 0, 73, 73,0.000000 },
- { 730, 730, 95, 0, 600, 600,0.000000 },
- {1669,1669, 84, 0, 86, 86,0.000000 },
- { 755, 755, 20, 0, 200, 200,0.000000 },
- { 755, 755, 22, 0, 193, 193,0.000000 },
- { 755, 755, 24, 0, 200, 200,0.000000 },
- {1671,1671, 0, 0, 400, 400,0.000000 },
- {1672,1672, 0, 0, 460, 460,0.000000 },
- {1673,1673, 0, 0, 566, 566,0.000000 },
- {1674,1674, 0, 0, 40, 40,0.000000 },
- {1675,1675, 0, 0, 913, 913,0.000000 },
- {1676,1676, 0, 0, 940, 940,0.000000 },
- {1677,1677, 0, 0, 553, 553,0.000000 },
- {1678,1678, 0, 0, 653, 653,0.000000 },
- {1679,1679, 0, 0, 140, 140,0.000000 },
- {1680,1680, 0, 0, 440, 440,0.000000 },
- {1681,1681, 0, 0, 493, 493,0.000000 },
- {1682,1682, 0, 0, 40000, 213,0.000000 },
- {1683,1683, 0, 0, 246, 246,0.000000 },
- {1684,1684, 0, 0, 140, 140,0.000000 },
- {1685,1685, 0, 0, 880, 880,0.000000 },
- {1686,1686, 0, 0, 700, 700,0.000000 },
- {1687,1687, 0, 0, 40000, 0,0.000000 },
- {1688,1688, 0, 0, 40000, 6,0.000000 },
- {1689,1689, 0, 0, 86, 86,0.000000 },
- {1690,1690, 0, 0, 40000, 6,0.000000 },
- {1691,1691, 0, 0, 40000, 6,0.000000 },
- {1692,1692, 0, 0, 40000, 6,0.000000 },
- {1693,1693, 0, 0, 40000, 6,0.000000 },
- {1694,1694, 0, 0, 440, 440,0.000000 },
- {1695,1695, 0, 0, 440, 440,0.000000 },
- {1696,1696, 0, 0, 100, 0,0.000000 },
- {1697,1697, 0, 0, 1846, 1846,0.000000 },
- {1698,1698, 0, 0, 40, 40,0.000000 },
- {1699,1699, 0, 0, 6580, 6580,0.000000 },
- {1700,1700, 0, 0, 1846, 1846,0.000000 },
- {1701,1701, 0, 0, 1080, 1080,0.000000 },
- {1702,1702, 0, 0, 40000, 0,0.000000 },
- {1703,1703, 0, 0, 1020, 1020,0.000000 },
- {1704,1704, 0, 0, 40000, 53,0.000000 },
- {1705,1705, 0, 0, 40000, 0,0.000000 },
- {1706,1706, 0, 0, 40000, 0,0.000000 },
- {1707,1707, 0, 0, 40000, 53,0.000000 },
- {1708,1708, 0, 0, 40000, 0,0.000000 },
- {1709,1709, 0, 0, 40000, 26,0.000000 },
- {1710,1710, 0, 0, 626, 626,0.000000 },
- {1711,1711, 0, 0, 40000, 26,0.000000 },
- {1712,1712, 0, 0, 1226, 13,0.000000 },
- {1713,1713, 0, 0, 40000, 0,0.000000 },
- {1714,1714, 0, 0, 3980, 13,0.000000 },
- {1715,1715, 0, 0, 253, 253,0.000000 },
- {1716,1716, 0, 0, 940, 940,0.000000 },
- {1717,1717, 0, 0, 126, 126,0.000000 },
- {1718,1718, 0, 0, 3766, 13,0.000000 },
- {1719,1719, 0, 0, 660, 200,0.000000 },
- {1720,1720, 0, 0, 40000, 20,0.000000 },
- {1721,1721, 0, 0, 40000, 20,0.000000 },
- {1722,1722, 0, 0, 40000, 146,0.000000 },
- {1723,1723, 0, 0, 40000, 26,0.000000 },
- {1724,1724, 0, 0, 40000, 140,0.000000 },
- {1725,1725, 0, 0, 260, 260,0.000000 },
- {1726,1726, 0, 0, 40000, 0,0.000000 },
- {1727,1727, 0, 0, 126, 0,0.000000 },
- {1728,1728, 0, 0, 386, 6,0.000000 },
- {1729,1729, 0, 0, 40000, 33,0.000000 },
- {1730,1730, 0, 0, 126, 33,0.000000 },
- {1731,1731, 0, 0, 1580, 1580,0.000000 },
- {1732,1732, 0, 0, 40000, 6,0.000000 },
- {1733,1733, 0, 0, 40000, 6,0.000000 },
- {1734,1734, 0, 0, 40000, 6,0.000000 },
- {1735,1735, 0, 0, 40000, 13,0.000000 },
- {1736,1736, 0, 0, 40000, 13,0.000000 },
- {1737,1737, 0, 0, 40000, 20,0.000000 },
- {1738,1738, 0, 0, 40000, 13,0.000000 },
- {1739,1739, 0, 0, 40000, 13,0.000000 },
- {1740,1740, 0, 0, 40000, 73,0.000000 },
- {1741,1741, 0, 0, 40000, 6,0.000000 },
- {1742,1742, 0, 0, 40000, 6,0.000000 },
- {1743,1743, 0, 0, 40000, 20,0.000000 },
- {1744,1744, 0, 0, 993, 993,0.000000 },
- {1745,1745, 0, 0, 40000, 20,0.000000 },
- {1746,1746, 0, 0, 40000, 0,0.000000 },
- {1747,1747, 0, 0, 40000, 0,0.000000 },
- {1748,1748, 0, 0, 933, 6,0.000000 },
- {1749,1749, 0, 0, 40000, 20,0.000000 },
- {1750,1750, 0, 0, 40000, 6,0.000000 },
- {1751,1751, 0, 0, 40000, 13,0.000000 },
- {1752,1752, 0, 0, 40000, 26,0.000000 },
- {1753,1753, 0, 0, 40000, 0,0.000000 },
- {1754,1754, 0, 0, 1793, 1793,0.000000 },
- {1755,1755, 0, 0, 40000, 106,0.000000 },
- {1756,1756, 0, 0, 40000, 46,0.000000 },
- {1757,1757, 0, 0, 40000, 33,0.000000 },
- {1758,1758, 0, 0, 40000, 286,0.000000 },
- {1759,1759, 0, 0, 40000, 906,0.000000 },
- {1760,1760, 0, 0, 40000, 220,0.000000 },
- {1761,1761, 0, 0, 40000, 53,0.000000 },
- {1762,1762, 0, 0, 40000, 40,0.000000 },
- {1763,1763, 0, 0, 3446, 3446,0.000000 },
- {1764,1764, 0, 0, 860, 13,0.000000 },
- {1765,1765, 0, 0, 513, 513,0.000000 },
- {1766,1766, 0, 0, 1846, 1846,0.000000 },
- {1767,1767, 0, 0, 973, 973,0.000000 },
- {1768,1768, 0, 0, 40000, 366,0.000000 },
- {1769,1769, 0, 0, 1426, 1426,0.000000 },
- {1770,1770, 0, 0, 40000, 686,0.000000 },
- {1771,1771, 0, 0, 1060, 1060,0.000000 },
- {1772,1772, 0, 0, 13, 13,0.000000 },
- {1773,1773, 0, 0, 380, 380,0.000000 },
- {1774,1774, 0, 0, 146, 146,0.000000 },
- {1775,1775, 0, 0, 166, 166,0.000000 },
- {1776,1776, 0, 0, 40000, 6,0.000000 },
- {1777,1777, 0, 0, 40000, 0,0.000000 },
- {1778,1778, 0, 0, 40000, 66,0.000000 },
- {1779,1779, 0, 0, 1473, 1473,0.000000 },
- {1780,1780, 0, 0, 113, 113,0.000000 },
- {1781,1781, 0, 0, 353, 353,0.000000 },
- {1782,1782, 0, 0, 46, 46,0.000000 },
- {1783,1783, 0, 0, 86, 86,0.000000 },
- {1784,1784, 0, 0, 60, 60,0.000000 },
- {1785,1785, 0, 0, 2280, 2280,0.000000 },
- {1786,1786, 0, 0, 366, 366,0.000000 },
- {1787,1787, 0, 0, 1713, 1713,0.000000 },
- {1788,1788, 0, 0, 206, 206,0.000000 },
- {1789,1789, 0, 0, 40000, 6,0.000000 },
- {1790,1790, 0, 0, 40000, 0,0.000000 },
- {1791,1791, 0, 0, 40000, 553,0.000000 },
- {1792,1792, 0, 0, 160, 160,0.000000 },
- {1793,1793, 48, 0, 46, 46,0.000000 },
- {1794,1794, 48, 0, 13, 13,0.000000 },
- {1795,1795, 60, 0, 46, 46,0.000000 },
- {1796,1796, 60, 0, 33, 33,0.000000 },
- {1797,1797, 70, 0, 33, 33,0.000000 },
- {1798,1798, 51, 0, 160, 160,0.000000 },
- {1799,1799, 60, 0, 40, 40,0.000000 },
- {1798,1798, 54, 0, 140, 140,0.000000 },
- {1800,1800, 60, 0, 53, 53,0.000000 },
- {1798,1798, 56, 0, 140, 140,0.000000 },
- {1801,1801, 60, 0, 300, 300,0.000000 },
- {1798,1798, 61, 0, 166, 166,0.000000 },
- {1798,1798, 63, 0, 166, 166,0.000000 },
- {1802,1802, 48, 0, 300, 300,0.000000 },
- {1798,1798, 68, 0, 133, 133,0.000000 },
- {1803,1803, 60, 0, 393, 393,0.000000 },
- {1804,1804, 60, 0, 313, 313,0.000000 },
- {1805,1805, 66, 0, 100, 100,0.000000 },
- {1806,1806, 60, 0, 306, 306,0.000000 },
- { 379, 379, 59, 0, 40, 40,0.000000 },
- {1802,1802, 64, 0, 306, 306,0.000000 },
- {1807,1807, 48, 0, 566, 566,0.000000 },
- {1808,1808, 56, 0, 26, 26,0.000000 },
- {1809,1809, 53, 0, 73, 73,0.000000 },
- {1810,1810, 65, 0, 13, 13,0.000000 },
- {1811,1811, 49, 0, 86, 86,0.000000 },
- {1811,1811, 43, 0, 86, 86,0.000000 },
- { 386, 386, 65, 0, 86, 86,0.000000 },
- { 386, 386, 60, 0, 86, 86,0.000000 },
- {1812,1812, 70, 0, 80, 80,0.000000 },
- {1812,1812, 65, 0, 100, 100,0.000000 },
- {1813,1813, 60, 0, 40, 40,0.000000 },
- {1814,1814, 60, 0, 33, 33,0.000000 },
- {1815,1815, 56, 0, 93, 93,0.000000 },
- {1816,1816, 53, 0, 280, 280,0.000000 },
- {1817,1817, 60, 0, 60, 60,0.000000 },
- {1818,1818, 48, 0, 180, 180,0.000000 },
- {1819,1819, 69, 0, 20, 20,0.000000 },
- { 328, 328, 67, 0, 20, 20,0.000000 },
- { 328, 328, 62, 0, 20, 20,0.000000 },
- {1820,1820, 65, 0, 220, 220,0.000000 },
- {1821,1821, 60, 0, 220, 220,0.000000 },
- {1822,1822, 63, 0, 26, 26,0.000000 },
- {1823,1823, 63, 0, 606, 606,0.000000 },
- {1824,1824, 67, 0, 86, 86,0.000000 },
- {1825,1825, 60, 0, 300, 300,0.000000 },
- {1825,1825, 72, 0, 273, 273,0.000000 },
- { 401, 401, 62, 0, 6, 6,0.000000 },
- {1826,1826, 48, 0, 13, 13,0.000000 },
- {1827,1827, 53, 0, 213, 213,0.000000 },
- {1828,1828, 60, 0, 93, 93,0.000000 },
- {1829,1829, 60, 0, 40, 40,0.000000 },
- {1830,1830, 60, 0, 20, 20,0.000000 },
- {1831,1831, 60, 0, 46, 46,0.000000 },
- {1832,1832, 0, 0, 126, 0,0.000000 },
- {1833,1833, 0, 0, 1240, 1240,0.000000 },
- {1834,1834, 0, 0, 433, 433,0.000000 },
- {1835,1835, 0, 0, 40000, 0,0.000000 },
- {1836,1836, 0, 0, 40000, 153,0.000000 },
- {1837,1837, 0, 0, 146, 106,0.000000 },
- {1838,1838, 0, 0, 126, 126,0.000000 },
- {1839,1839, 0, 0, 1740, 1740,0.000000 },
- {1840,1840, 0, 0, 440, 13,0.000000 },
- {1841,1841, 0, 0, 546, 546,0.000000 },
- {1842,1842, 0, 0, 1420, 1420,0.000000 },
- { 525, 525, 0, 0, 1220, 1220,0.000000 },
- {1843,1843, 0, 0, 40000, 140,0.000000 },
- {1844,1844, 0, 0, 3873, 3873,0.000000 },
- {1845,1845, 0, 0, 546, 546,0.000000 },
- {1846,1846, 0, 0, 333, 333,0.000000 },
- {1847,1847, 0, 0, 4933, 4933,0.000000 },
- {1848,1848, 0, 0, 126, 0,0.000000 },
- {1849,1849, 0, 0, 380, 380,0.000000 },
- {1850,1850, 0, 0, 40000, 6,0.000000 },
- {1851,1851, 0, 0, 273, 273,0.000000 },
- {1852,1852, 0, 0, 233, 233,0.000000 },
- {1853,1853, 0, 0, 40000, 233,0.000000 },
- {1854,1854, 0, 0, 1466, 6,0.000000 },
- {1855,1855, 0, 0, 1380, 1380,0.000000 },
- {1856,1856, 0, 0, 40000, 106,0.000000 },
- {1857,1857, 0, 0, 40000, 133,0.000000 },
- {1858,1858, 0, 0, 913, 913,0.000000 },
- {1859,1859, 0, 0, 60, 60,0.000000 },
- {1860,1860, 0, 0, 40000, 6,0.000000 },
- {1861,1861, 0, 0, 866, 866,0.000000 },
- {1862,1862, 0, 0, 4726, 4726,0.000000 },
- {1863,1863, 0, 0, 40, 40,0.000000 },
- {1864,1864, 0, 0, 1793, 1793,0.000000 },
- {1865,1865, 0, 0, 246, 246,0.000000 },
- {1866,1866, 0, 0, 40000, 133,0.000000 },
- {1867,1867, 0, 0, 2006, 2006,0.000000 },
- {1868,1868, 0, 0, 140, 140,0.000000 },
- {1869,1869, 0, 0, 40000, 106,0.000000 },
- {1870,1870, 0, 0, 460, 460,0.000000 },
- {1871,1871, 0, 0, 146, 146,0.000000 },
- {1872,1872, 0, 0, 273, 273,0.000000 },
- {1873,1873, 0, 0, 40000, 46,0.000000 },
- {1874,1874, 41, 0, 120, 120,0.000000 },
- {1875,1875, 70, 0, 13, 13,0.000000 },
- {1876,1876, 60, 0, 40, 40,0.000000 },
- {1877,1877, 80, 0, 13, 13,0.000000 },
- {1878,1878, 84, 0, 20, 20,0.000000 },
- {1879,1879, 72, 0, 133, 133,0.000000 },
- {1880,1880, 84, 0, 266, 266,0.000000 },
- { 128, 128, 70, 0, 13, 13,0.000000 },
- { 132, 132, 60, 0, 13, 13,0.000000 },
- {1881,1882, 0, 0, 40000, 173,0.000000 },
- {1883,1883, 0, 0, 260, 260,0.000000 },
- {1884,1885, 0, 0, 40000, 6,0.000000 },
- {1886,1887, 0, 0, 40000, 20,0.000000 },
- {1888,1889, 0, 0, 40000, 6,0.000000 },
- {1890,1890, 0, 0, 1020, 53,0.000000 },
- {1891,1891, 0, 0, 40000, 100,0.000000 },
- {1892,1892, 0, 0, 786, 340,0.000000 },
- {1893,1893, 0, 0, 40000, 140,0.000000 },
- {1894,1894, 0, 0, 86, 86,0.000000 },
- {1895,1895, 0, 0, 80, 40,0.000000 },
- {1896,1896, 0, 0, 40000, 86,0.000000 },
- {1897,1897, 0, 0, 173, 173,0.000000 },
- {1898,1898, 0, 0, 886, 886,0.000000 },
- {1899,1899, 0, 0, 466, 466,0.000000 },
- {1900,1900, 0, 0, 40000, 106,0.000000 },
- {1901,1901, 0, 0, 40000, 66,0.000000 },
- {1902,1902, 0, 0, 40000, 13,0.000000 },
- {1903,1903, 0, 0, 60, 60,0.000000 },
- {1904,1904, 0, 0, 1226, 1226,0.000000 },
- {1905,1905, 0, 0, 280, 280,0.000000 },
- {1906,1906, 0, 0, 40000, 153,0.000000 },
- {1907,1907, 0, 0, 40000, 173,0.000000 },
- {1908,1908, 0, 0, 40000, 340,0.000000 },
- {1909,1909, 0, 0, 166, 166,0.000000 },
- { 501, 501, 0, 0, 86, 86,0.000000 },
- {1910,1910, 0, 0, 40000, 20,0.000000 },
- {1911,1911, 0, 0, 20, 20,0.000000 },
- {1912,1912, 0, 0, 600, 600,0.000000 },
- {1913,1913, 0, 0, 40000, 2393,0.000000 },
- {1914,1914, 0, 0, 166, 166,0.000000 },
- { 511, 511, 0, 0, 586, 586,0.000000 },
- {1915,1915, 0, 0, 73, 73,0.000000 },
- {1910,1910, 60, 0, 40000, 26,0.000000 },
- { 511, 511, 72, 0, 493, 493,0.000000 },
- {1915,1915, 84, 0, 60, 60,0.000000 },
- {1916,1916, 0, 0, 2080, 2080,0.000000 },
- {1917,1917, 0, 0, 593, 593,0.000000 },
- {1918,1918, 0, 0, 600, 600,0.000000 },
- {1919,1919, 0, 0, 940, 940,0.000000 },
- {1920,1920, 0, 0, 940, 940,0.000000 },
- {1921,1921, 0, 0, 940, 940,0.000000 },
- {1922,1922, 0, 0, 853, 853,0.000000 },
- {1923,1923, 0, 0, 893, 893,0.000000 },
- {1924,1924, 0, 0, 40000, 73,0.000000 },
- {1925,1925, 0, 0, 40000, 33,0.000000 },
- {1926,1926, 0, 0, 40000, 20,0.000000 },
- {1927,1927, 0, 0, 40000, 0,0.000000 },
- {1928,1928, 0, 0, 40000, 193,0.000000 },
- {1929,1929, 0, 0, 40000, 133,0.000000 },
- {1930,1930, 0, 0, 40000, 153,0.000000 },
- {1931,1931, 0, 0, 1146, 1146,0.000000 },
- {1932,1932, 0, 0, 960, 960,0.000000 },
- {1933,1933, 0, 0, 2406, 2406,0.000000 },
- {1934,1934, 0, 0, 2406, 2406,0.000000 },
- {1935,1935, 0, 0, 40000, 0,0.000000 },
- {1936,1936, 0, 0, 40000, 6,0.000000 },
- {1937,1937, 0, 0, 40000, 0,0.000000 },
- {1938,1938, 0, 0, 40000, 0,0.000000 },
- {1939,1939, 0, 0, 40000, 26,0.000000 },
- {1940,1940, 0, 0, 1426, 1426,0.000000 },
- {1941,1941, 0, 0, 40000, 766,0.000000 },
- {1942,1942, 0, 0, 40000, 453,0.000000 },
- {1943,1943, 0, 0, 40000, 486,0.000000 },
- {1944,1944, 0, 0, 40000, 106,0.000000 },
- {1945,1945, 0, 0, 2273, 2273,0.000000 },
- {1946,1946, 0, 0, 40000, 33,0.000000 },
- {1947,1947, 0, 0, 1226, 1226,0.000000 },
- {1948,1948, 0, 0, 40000, 6,0.000000 },
- {1949,1949, 0, 0, 40000, 1966,0.000000 },
- {1950,1950, 0, 0, 1153, 1153,0.000000 },
- {1951,1951, 0, 0, 40000, 6,0.000000 },
- {1952,1952, 0, 0, 1473, 1473,0.000000 },
- {1953,1953, 0, 0, 40000, 20,0.000000 },
- {1954,1954, 0, 0, 466, 33,0.000000 },
- {1955,1955, 0, 0, 833, 833,0.000000 },
- {1956,1956, 0, 0, 40000, 0,0.000000 },
- {1957,1957, 0, 0, 40000, 33,0.000000 },
- {1958,1958, 0, 0, 40000, 126,0.000000 },
- {1959,1959, 0, 0, 40000, 33,0.000000 },
- {1960,1960, 0, 0, 280, 280,0.000000 },
- {1961,1961, 0, 0, 40000, 266,0.000000 },
- {1962,1962, 0, 0, 40000, 46,0.000000 },
- {1963,1963, 0, 0, 40000, 266,0.000000 },
- {1964,1964, 0, 0, 40000, 0,0.000000 },
- {1965,1965, 0, 0, 40000, 113,0.000000 },
- {1966,1966, 0, 0, 800, 800,0.000000 },
- {1967,1967, 0, 0, 1206, 1206,0.000000 },
- {1968,1968, 0, 0, 1080, 1080,0.000000 },
- {1969,1969, 0, 0, 40000, 13,0.000000 },
- {1970,1970, 0, 0, 546, 546,0.000000 },
- {1971,1971, 0, 0, 40000, 6,0.000000 },
- {1972,1972, 0, 0, 40000, 20,0.000000 },
- {1973,1973, 0, 0, 1233, 20,0.000000 },
- {1974,1974, 0, 0, 40000, 0,0.000000 },
- {1975,1975, 0, 0, 40000, 0,0.000000 },
- {1976,1976, 0, 0, 466, 6,0.000000 },
- {1977,1977, 0, 0, 206, 206,0.000000 },
- {1978,1978, 0, 0, 40000, 6,0.000000 },
- {1979,1979, 0, 0, 40000, 6,0.000000 },
- {1980,1980, 0, 0, 40000, 6,0.000000 },
- {1981,1981, 0, 0, 40000, 6,0.000000 },
- {1982,1982, 0, 0, 40000, 0,0.000000 },
- {1983,1983, 0, 0, 40000, 0,0.000000 },
- {1984,1984, 0, 0, 40000, 0,0.000000 },
- {1985,1985, 0, 0, 40000, 180,0.000000 },
- {1986,1986, 0, 0, 40000, 53,0.000000 },
- {1987,1987, 0, 0, 40000, 53,0.000000 },
- {1988,1988, 0, 0, 40000, 6,0.000000 },
- {1989,1989, 0, 0, 40000, 6,0.000000 },
- {1990,1990, 0, 0, 100, 100,0.000000 },
- {1991,1991, 0, 0, 40000, 73,0.000000 },
- {1992,1992, 0, 0, 60, 60,0.000000 },
- {1993,1993, 0, 0, 40000, 0,0.000000 },
- {1994,1994, 0, 0, 40000, 0,0.000000 },
- {1995,1995, 0, 0, 40000, 0,0.000000 },
- {1996,1996, 0, 0, 40000, 6,0.000000 },
- {1997,1997, 0, 0, 40000, 0,0.000000 },
- {1998,1998, 0, 0, 40000, 0,0.000000 },
- {1999,1999, 0, 0, 40000, 0,0.000000 },
- {2000,2000, 0, 0, 40000, 233,0.000000 },
- {2001,2001, 0, 0, 40000, 233,0.000000 },
- {2002,2002, 0, 0, 620, 620,0.000000 },
- {2003,2003, 0, 0, 1740, 1740,0.000000 },
- {2004,2004, 0, 0, 1153, 1153,0.000000 },
- {2005,2005, 0, 0, 920, 920,0.000000 },
- {2006,2006, 0, 0, 153, 153,0.000000 },
- {2007,2007, 0, 0, 526, 526,0.000000 },
- {2008,2008, 0, 0, 40000, 6,0.000000 },
- {2009,2009, 0, 0, 40000, 40,0.000000 },
- {2010,2010, 0, 0, 40000, 53,0.000000 },
- {2011,2011, 0, 0, 40000, 160,0.000000 },
- {2012,2012, 0, 0, 40000, 6,0.000000 },
- {2013,2013, 0, 0, 1046, 1046,0.000000 },
- {2014,2014, 0, 0, 513, 513,0.000000 },
- {2015,2015, 0, 0, 40, 40,0.000000 },
- {2016,2016, 0, 0, 40, 40,0.000000 },
- {2017,2017, 0, 0, 93, 93,0.000000 },
- {2018,2018, 0, 0, 66, 66,0.000000 },
- {2019,2019, 0, 0, 13, 13,0.000000 },
- {2020,2020, 0, 0, 300, 300,0.000000 },
- {2021,2021, 0, 0, 40, 40,0.000000 },
- {2022,2022, 0, 0, 586, 586,0.000000 },
- {2023,2023, 0, 0, 260, 260,0.000000 },
- {2024,2024, 0, 0, 2406, 2406,0.000000 },
- {2025,2025, 0, 0, 126, 126,0.000000 },
- {2026,2026, 0, 0, 1220, 1220,0.000000 },
- {2027,2027, 0, 0, 386, 386,0.000000 },
- { 352, 352, 51, 0, 40000, 0,0.000000 },
- {2028,2028, 35, 0, 106, 106,0.000000 },
- {2028,2028, 36, 0, 93, 93,0.000000 },
- {2029,2029, 47, 0, 13, 13,0.000000 },
- {2030,2030, 38, 0, 106, 106,0.000000 },
- {2019,2019, 39, 0, 20, 20,0.000000 },
- {2031,2031, 45, 0, 80, 80,0.000000 },
- { 492, 492, 41, 0, 26, 26,0.000000 },
- {2032,2032, 42, 0, 33, 33,0.000000 },
- {2033,2033, 44, 0, 160, 160,0.000000 },
- { 492, 492, 48, 0, 40, 40,0.000000 },
- {2034,2034, 46, 0, 600, 600,0.000000 },
- { 492, 492, 53, 0, 26, 26,0.000000 },
- { 167, 167, 56, 0, 160, 160,0.000000 },
- {2035,2035, 61, 0, 93, 93,0.000000 },
- {2036,2036, 56, 0, 353, 353,0.000000 },
- {2037,2037, 60, 0, 40, 40,0.000000 },
- { 144, 144, 59, 0, 40, 40,0.000000 },
- {2038,2038, 59, 0, 13, 13,0.000000 },
- { 169, 169, 51, 0, 40, 40,0.000000 },
- { 169, 169, 45, 0, 40, 40,0.000000 },
- {2039,2039, 72, 0, 126, 126,0.000000 },
- {2040,2040, 60, 0, 153, 153,0.000000 },
- {2041,2041, 58, 0, 40, 40,0.000000 },
- {2042,2042, 53, 0, 40, 40,0.000000 },
- {2043,2043, 73, 0, 26, 26,0.000000 },
- { 158, 158, 75, 0, 20, 20,0.000000 },
- {2044,2044, 0, 0, 1226, 1226,0.000000 },
- {2045,2045, 0, 0, 493, 493,0.000000 },
- {2046,2046, 0, 0, 620, 620,0.000000 },
- {2047,2047, 0, 0, 280, 280,0.000000 },
- {2048,2048, 0, 0, 260, 260,0.000000 },
- {2049,2049, 0, 0, 40000, 1093,0.000000 },
- {2050,2050, 0, 0, 40000, 233,0.000000 },
- {2051,2051, 0, 0, 120, 120,0.000000 },
- {2052,2052, 0, 0, 40000, 926,0.000000 },
- {2053,2053, 0, 0, 40000, 926,0.000000 },
- {2054,2054, 0, 0, 40000, 233,0.000000 },
- {2055,2055, 0, 0, 40000, 280,0.000000 },
- {2056,2056, 0, 0, 40000, 6,0.000000 },
- {2057,2057, 0, 0, 40000, 153,0.000000 },
- {2058,2058, 0, 0, 286, 286,0.000000 },
- {2059,2059, 0, 0, 286, 286,0.000000 },
- {2060,2060, 0, 0, 40000, 0,0.000000 },
- {2061,2061, 0, 0, 680, 680,0.000000 },
- {2062,2062, 0, 0, 280, 280,0.000000 },
- {2063,2063, 0, 0, 40000, 200,0.000000 },
- {2064,2064, 0, 0, 40, 40,0.000000 },
- {2065,2065, 0, 0, 1580, 1580,0.000000 },
- {2066,2066, 0, 0, 140, 133,0.000000 },
- {2067,2067, 0, 0, 40000, 213,0.000000 },
- {2068,2068, 0, 0, 613, 613,0.000000 },
- {2069,2069, 0, 0, 293, 293,0.000000 },
- {2070,2070, 0, 0, 160, 160,0.000000 },
- {2071,2071, 0, 0, 146, 13,0.000000 },
- {2072,2072, 0, 0, 40000, 6,0.000000 },
- {2073,2073, 0, 0, 40000, 133,0.000000 },
- {2074,2074, 0, 0, 40000, 140,0.000000 },
- {2075,2075, 0, 0, 40000, 66,0.000000 },
- {2076,2076, 0, 0, 40000, 40,0.000000 },
- {2077,2077, 0, 0, 40000, 153,0.000000 },
- {2078,2078, 0, 0, 593, 593,0.000000 },
- {2079,2079, 0, 0, 40000, 40,0.000000 },
- {2080,2080, 0, 0, 4480, 4480,0.000000 },
- {2081,2081, 0, 0, 3600, 313,0.000000 },
- {2082,2082, 0, 0, 40000, 413,0.000000 },
- {2083,2083, 0, 0, 40000, 566,0.000000 },
- {2084,2084, 0, 0, 8420, 80,0.000000 },
- {2085,2085, 0, 0, 40000, 926,0.000000 },
- {2086,2086, 0, 0, 40000, 853,0.000000 },
- {2087,2087, 0, 0, 40000, 853,0.000000 },
- {2088,2088, 0, 0, 40000, 853,0.000000 },
- {2089,2089, 0, 0, 40000, 873,0.000000 },
- {2090,2090, 0, 0, 40000, 1780,0.000000 },
- {2091,2091, 0, 0, 40000, 1673,0.000000 },
- {2092,2092, 0, 0, 4026, 4026,0.000000 },
- {2093,2093, 0, 0, 1773, 153,0.000000 },
- {2094,2094, 0, 0, 1446, 1446,0.000000 },
- {2095,2095, 0, 0, 633, 633,0.000000 },
- {2096,2096, 0, 0, 333, 333,0.000000 },
- {2097,2097, 0, 0, 193, 193,0.000000 },
- {2098,2098, 0, 0, 86, 86,0.000000 },
- {2099,2099, 0, 0, 246, 246,0.000000 },
- {2100,2100, 0, 0, 40000, 6,0.000000 },
- {2101,2101, 0, 0, 40000, 6,0.000000 },
- {2102,2102, 0, 0, 313, 313,0.000000 },
- {2103,2103, 0, 0, 160, 160,0.000000 },
- {2104,2104, 0, 0, 46, 46,0.000000 },
- {2105,2105, 0, 0, 100, 100,0.000000 },
- {2106,2106, 0, 0, 2313, 2313,0.000000 },
- {2107,2107, 0, 0, 306, 306,0.000000 },
- {2108,2108, 0, 0, 40000, 2180,0.000000 },
- {2109,2109, 0, 0, 40000, 133,0.000000 },
- {2110,2110, 0, 0, 40000, 126,0.000000 },
- {2111,2111, 0, 0, 40000, 146,0.000000 },
- { 752, 752, 60, 0, 40, 40,0.000000 },
- { 755, 755, 12, 0, 160, 160,0.000000 },
- {2112,2112, 89, 0, 13, 13,0.000000 },
- {2113,2113, 89, 0, 206, 206,0.000000 },
- { 755, 755, 14, 0, 160, 160,0.000000 },
- { 755, 755, 16, 0, 160, 160,0.000000 },
- {2114,2114, 84, 0, 513, 513,0.000000 },
- { 755, 755, 19, 0, 160, 160,0.000000 },
- {2115,2115, 38, 0, 60, 60,0.000000 },
- {2116,2116, 36, 0, 20, 20,0.000000 },
- { 755, 755, 28, 0, 193, 193,0.000000 },
- { 755, 755, 26, 0, 200, 200,0.000000 },
- { 755, 755, 35, 0, 200, 200,0.000000 },
- { 755, 755, 30, 0, 193, 193,0.000000 },
- {2117,2117, 60, 0, 73, 73,0.000000 },
- {2104,2104, 60, 0, 40, 40,0.000000 },
- {2104,2104, 55, 0, 46, 46,0.000000 },
- { 730, 730, 94, 0, 626, 626,0.000000 },
- {2118,2118, 0, 0, 280, 280,0.000000 },
- {2119,2119, 0, 0, 1446, 1446,0.000000 },
- {2120,2120, 0, 0, 40000, 53,0.000000 },
- {2121,2121, 0, 0, 40000, 20,0.000000 },
- {2122,2122, 0, 0, 40000, 20,0.000000 },
- {2123,2123, 0, 0, 3106, 3106,0.000000 },
- {2124,2124, 0, 0, 40, 66,0.000000 },
- {2125,2125, 0, 0, 40000, 106,0.000000 },
- {2126,2126, 0, 0, 40000, 6,0.000000 },
- {2127,2127, 0, 0, 40000, 13,0.000000 },
- {2128,2128, 0, 0, 40000, 6,0.000000 },
- {2129,2129, 0, 0, 40000, 6,0.000000 },
- {2130,2130, 0, 0, 40000, 6,0.000000 },
- {2131,2131, 0, 0, 40000, 13,0.000000 },
- {2132,2132, 0, 0, 40000, 6,0.000000 },
- {2133,2133, 0, 0, 2060, 13,0.000000 },
- {2134,2134, 0, 0, 40000, 53,0.000000 },
- {2135,2135, 0, 0, 2886, 2886,0.000000 },
- {2136,2136, 0, 0, 40000, 126,0.000000 },
- {2137,2137, 0, 0, 5280, 100,0.000000 },
- {2138,2138, 0, 0, 140, 140,0.000000 },
- {2139,2139, 0, 0, 4553, 20,0.000000 },
- {2140,2140, 0, 0, 513, 513,0.000000 },
- {2141,2141, 60, 0, 40, 40,0.000000 },
- {2141,2141, 44, 0, 40, 40,0.000000 },
- {2142,2142, 47, 0, 40, 40,0.000000 },
- {2143,2143, 47, 0, 60, 60,0.000000 },
- {2144,2144, 62, 0, 606, 606,0.000000 },
- {2145,2145, 93, 0, 226, 226,0.000000 },
- {2146,2146, 50, 0, 80, 80,0.000000 },
- {2145,2145, 40, 0, 420, 420,0.000000 },
- {2147,2147, 60, 0, 20, 20,0.000000 },
- { 898, 898, 60, 0, 46, 46,0.000000 },
- {2147,2147, 57, 0, 20, 20,0.000000 },
- { 900, 900, 42, 0, 193, 193,0.000000 },
- { 900, 900, 38, 0, 193, 193,0.000000 },
- { 908, 908, 88, 0, 33, 33,0.000000 },
- {2148,2148, 0, 0, 1553, 1553,0.000000 },
- {2149,2149, 0, 0, 40000, 6,0.000000 },
- {2150,2150, 0, 0, 993, 993,0.000000 },
- {2151,2151, 0, 0, 40000, 26,0.000000 },
- {2152,2152, 0, 0, 29720, 80,0.000000 },
- {2153,2153, 0, 0, 40000, 306,0.000000 },
- {2154,2154, 0, 0, 700, 700,0.000000 },
- {2155,2155, 0, 0, 880, 880,0.000000 },
- {2156,2156, 0, 0, 40000, 6,0.000000 },
- {2157,2157, 0, 0, 1046, 1046,0.000000 },
- {2158,2158, 0, 0, 100, 100,0.000000 },
- {2159,2159, 0, 0, 40, 40,0.000000 },
- { 136, 136, 0, 0, 640, 640,0.000000 },
- { 168, 168, 0, 0, 40, 40,0.000000 },
- { 164, 164, 0, 0, 1220, 1220,0.000000 },
- { 167, 167, 0, 0, 160, 160,0.000000 },
- {2160,2160, 65, 0, 40, 40,0.000000 },
- {2161,2161, 21, 0, 200, 200,0.000000 },
- {2162, 173, 0, 0, 1513, 1513,0.000000 },
- {2163,2164, 0, 0, 653, 653,0.000000 },
- {2165,2166, 0, 0, 633, 633,0.000000 },
- {2167,2168, 0, 0, 913, 913,0.000000 },
- {2169,2170, 0, 0, 300, 300,0.000000 },
- {2171,2172, 0, 0, 1773, 1773,0.000000 },
- {2173,2174, 0, 0, 40000, 306,0.000000 },
- {2175,2174, 0, 0, 40000, 433,0.000000 },
- {2176, 299, 0, 0, 40000, 66,0.000000 },
- {2177,2178, 0, 0, 40000, 246,0.000000 },
- {2179,2180, 0, 0, 40000, 300,0.000000 },
- {2181,2182, 0, 0, 40000, 233,0.000000 },
- {2183,2184, 0, 0, 1740, 1740,0.000000 },
- { 127, 127, 65, 0, 66, 66,0.000000 },
- { 127, 127, 72, 0, 46, 46,0.000000 },
- { 364, 365, 52, 0, 20, 20,0.000000 },
- {2185,2186, 60, 0, 80, 80,0.000000 },
- {1550,1551, 47, 0, 100, 100,0.000000 },
- {1556,1557, 76, 0, 253, 253,0.000000 },
- { 374, 375, 84, 0, 40000, 0,0.000000 },
- {1564,1565, 83, 0, 73, 73,0.000000 },
- {1568,1569, 24, 0, 40, 40,0.000000 },
- {1556,1557, 77, 0, 253, 253,0.000000 },
- {1572,1573, 60, 0, 80, 80,0.000000 },
- {1574,1575, 65, 0, 46, 46,0.000000 },
- { 391, 392, 44, 0, 80, 80,0.000000 },
- { 391, 393, 40, 0, 40, 40,0.000000 },
- {1606,1607, 72, 0, 33, 33,0.000000 },
- { 398, 399, 73, 0, 400, 400,0.000000 },
- {1608,1609, 70, 0, 353, 353,0.000000 },
- {2187,2187, 0, 0, 40000, 140,0.000000 },
- {2188,2188, 0, 0, 40000, 153,0.000000 },
- {2189,2189, 0, 0, 453, 453,0.000000 },
- {2190,2190, 0, 0, 1300, 1300,0.000000 },
- {2191,2191, 0, 0, 46, 46,0.000000 },
- {2192,2192, 0, 0, 40000, 186,0.000000 },
- {2193,2193, 0, 0, 80, 80,0.000000 },
- {2194,2194, 0, 0, 40000, 6,0.000000 },
- {2195,2195, 0, 0, 186, 186,0.000000 },
- {2196,2196, 0, 0, 40000, 0,0.000000 },
- {2197,2197, 0, 0, 40000, 0,0.000000 },
- {2198,2198, 0, 0, 166, 0,0.000000 },
- {2199,2199, 0, 0, 40, 40,0.000000 },
- {2200,2200, 0, 0, 1740, 1740,0.000000 },
- { 528, 528, 0, 0, 140, 140,0.000000 },
- {2201,2201, 0, 0, 40000, 53,0.000000 },
- {2202,2202, 0, 0, 40, 40,0.000000 },
- {2203,2203, 0, 0, 80, 80,0.000000 },
- {2204,2204, 41, 0, 46, 46,0.000000 },
- {2205,2205, 84, 0, 40, 40,0.000000 },
- {2206,2206, 72, 0, 133, 133,0.000000 },
- { 741, 741, 48, 0, 133, 133,0.000000 },
- {2207,2207, 0, 0, 40, 40,0.000000 },
- {2208,2208, 0, 0, 940, 940,0.000000 },
- {2209,2209, 0, 0, 40000, 213,0.000000 },
- {2210,2210, 0, 0, 866, 866,0.000000 },
- {2211,2211, 0, 0, 40000, 0,0.000000 },
- {2212,2212, 0, 0, 40000, 6,0.000000 },
- {2213,2213, 0, 0, 1080, 1080,0.000000 },
- {2214,2214, 0, 0, 40000, 0,0.000000 },
- {2215,2215, 0, 0, 40000, 73,0.000000 },
- {2216,2216, 0, 0, 40000, 26,0.000000 },
- {2217,2217, 0, 0, 2360, 13,0.000000 },
- {2218,2218, 0, 0, 40000, 0,0.000000 },
- {2219,2219, 0, 0, 3126, 13,0.000000 },
- {2220,2220, 0, 0, 40000, 140,0.000000 },
- {2221,2221, 0, 0, 40000, 26,0.000000 },
- {2222,2222, 0, 0, 40000, 140,0.000000 },
- {2223,2223, 0, 0, 40000, 0,0.000000 },
- {2224,2224, 0, 0, 126, 0,0.000000 },
- {2225,2225, 0, 0, 40000, 6,0.000000 },
- {2226,2226, 0, 0, 40000, 33,0.000000 },
- {2227,2227, 0, 0, 40000, 6,0.000000 },
- {2228,2228, 0, 0, 40000, 6,0.000000 },
- {2229,2229, 0, 0, 40000, 0,0.000000 },
- {2230,2230, 0, 0, 40000, 6,0.000000 },
- {2231,2231, 0, 0, 40000, 20,0.000000 },
- {2232,2232, 0, 0, 40000, 6,0.000000 },
- {2233,2233, 0, 0, 40000, 26,0.000000 },
- {2234,2234, 0, 0, 40000, 266,0.000000 },
- {2235,2235, 0, 0, 40000, 40,0.000000 },
- {2236,2236, 0, 0, 3500, 3500,0.000000 },
- {2237,2237, 0, 0, 860, 20,0.000000 },
- {2238,2238, 0, 0, 513, 513,0.000000 },
- {2239,2239, 0, 0, 973, 973,0.000000 },
- {2240,2240, 0, 0, 1446, 1446,0.000000 },
- {2241,2241, 0, 0, 2280, 2280,0.000000 },
- {2242,2242, 0, 0, 1713, 1713,0.000000 },
- {2243,2243, 0, 0, 200, 200,0.000000 },
- {2244,2244, 0, 0, 40000, 6,0.000000 },
- {2245,2245, 0, 0, 40000, 0,0.000000 },
- {2246,2246, 0, 0, 140, 140,0.000000 },
- {2247,2247, 60, 0, 46, 46,0.000000 },
- {2248,2248, 60, 0, 306, 306,0.000000 },
- {2249,2249, 48, 0, 300, 300,0.000000 },
- {2250,2250, 60, 0, 360, 360,0.000000 },
- {2251,2251, 60, 0, 306, 306,0.000000 },
- {2252,2252, 66, 0, 93, 93,0.000000 },
- {2253,2253, 60, 0, 313, 313,0.000000 },
- {2249,2249, 64, 0, 300, 300,0.000000 },
- {2254,2254, 60, 0, 40, 40,0.000000 },
- {2255,2255, 60, 0, 26, 26,0.000000 },
- {2256,2256, 56, 0, 106, 106,0.000000 },
- {2257,2257, 53, 0, 313, 313,0.000000 },
- {2258,2258, 60, 0, 60, 60,0.000000 },
- {2259,2259, 48, 0, 180, 180,0.000000 },
- {2260,2260, 67, 0, 80, 80,0.000000 },
- {2261,2261, 60, 0, 320, 320,0.000000 },
- {2261,2261, 72, 0, 246, 246,0.000000 },
- {2262,2262, 60, 0, 40, 40,0.000000 },
- {2263,2263, 0, 0, 593, 593,0.000000 },
- {2264,2264, 24, 0, 13, 13,0.000000 },
- {2265,2265, 36, 0, 26, 26,0.000000 },
- { 343, 343, 36, 0, 26, 26,0.000000 },
- { 347, 347, 0, 0, 66, 66,0.000000 },
- { 347, 347, 12, 0, 53, 53,0.000000 },
- {2266,2266, 12, 0, 60, 60,0.000000 },
- {2267,2267, 24, 0, 20, 20,0.000000 },
- {2267,2267, 36, 0, 13, 13,0.000000 },
- {2268,2268, 0, 0, 66, 66,0.000000 },
- {2266,2266, 24, 0, 20, 20,0.000000 },
- {2269,2269, 88, 0, 920, 920,0.000000 },
- {2270,2270, 88, 0, 486, 486,0.000000 },
- {2271,2271, 13, 0, 100, 100,0.000000 },
- { 351, 351, 0, 0, 73, 73,0.000000 },
- {2271,2271, 15, 0, 113, 113,0.000000 },
- {2272,2272, 0, 0, 1226, 1226,0.000000 },
- {2273,2273, 0, 0, 2193, 2193,0.000000 },
- {2274,2274, 0, 0, 866, 866,0.000000 },
- {2275,2275, 0, 0, 886, 886,0.000000 },
- {2276,2276, 0, 0, 1900, 1900,0.000000 },
- {2277,2277, 0, 0, 266, 266,0.000000 },
- {2278,2278, 0, 0, 313, 313,0.000000 },
- {2279,2279, 0, 0, 40000, 1833,0.000000 },
- {2280,2280, 0, 0, 126, 126,0.000000 },
- {2281,2281, 0, 0, 4580, 4580,0.000000 },
- {2282,2282, 0, 0, 253, 253,0.000000 },
- {2283,2283, 0, 0, 120, 120,0.000000 },
- {2284,2284, 0, 0, 40000, 46,0.000000 },
- {2285,2285, 0, 0, 2320, 13,0.000000 },
- {2286,2286, 0, 0, 80, 60,0.000000 },
- {2287,2287, 0, 0, 400, 400,0.000000 },
- {2288,2288, 0, 0, 1953, 1953,0.000000 },
- {2289,2289, 0, 0, 1446, 1446,0.000000 },
- {2290,2290, 0, 0, 360, 360,0.000000 },
- {2291,2291, 0, 0, 40000, 6,0.000000 },
- {2292,2292, 0, 0, 40000, 6,0.000000 },
- {2293,2293, 0, 0, 2026, 2026,0.000000 },
- {2294,2294, 0, 0, 246, 13,0.000000 },
- {2295,2295, 0, 0, 233, 233,0.000000 },
- {2296,2296, 0, 0, 2600, 1333,0.000000 },
- {2297,2297, 79, 0, 20, 20,0.000000 },
- {2297,2297, 72, 0, 20, 20,0.000000 },
- {2298,2298, 72, 0, 13, 13,0.000000 },
- {2298,2298, 79, 0, 13, 13,0.000000 },
- { 554, 554, 60, 0, 160, 160,0.000000 },
- {2299,2299, 72, 0, 253, 253,0.000000 },
- {2300,2300, 84, 0, 106, 106,0.000000 },
- { 555, 555, 66, 0, 20, 20,0.000000 },
- {2301,2302, 35, 0, 20, 20,0.000000 },
- {2303,2304, 52, 0, 20, 20,0.000000 },
- {2305,1548, 48, 0, 66, 66,0.000000 },
- {1595,1595, 58, 0, 33, 33,0.000000 },
- {2305,1548, 60, 0, 73, 73,0.000000 },
- {2306,2307, 47, 0, 606, 606,0.000000 },
- {2306,2307, 43, 0, 313, 313,0.000000 },
- {2306,2307, 49, 0, 706, 706,0.000000 },
- {2306,2307, 51, 0, 840, 840,0.000000 },
- {2306,2307, 54, 0, 820, 820,0.000000 },
- {2306,2307, 57, 0, 780, 780,0.000000 },
- {2306,2307, 72, 0, 713, 713,0.000000 },
- {2306,2307, 60, 0, 786, 786,0.000000 },
- {2306,2307, 76, 0, 720, 720,0.000000 },
- {2306,2307, 84, 0, 720, 720,0.000000 },
- {2306,2307, 36, 0, 193, 193,0.000000 },
- {1560,2308, 65, 0, 113, 113,0.000000 },
- {2309,2310, 84, 0, 40000, 0,0.000000 },
- {1564,1564, 83, 0, 60, 60,0.000000 },
- { 380, 381, 84, 0, 40000, 0,0.000000 },
- {1568,1568, 24, 0, 40, 40,0.000000 },
- {2306,2307, 77, 0, 713, 713,0.000000 },
- {2311,2312, 60, 0, 86, 86,0.000000 },
- {2313,2314, 65, 0, 160, 160,0.000000 },
- {2315,2315, 59, 0, 13, 13,0.000000 },
- {2316,2316, 51, 0, 40, 40,0.000000 },
- {1612,1612, 45, 0, 46, 46,0.000000 },
- {2317,2317, 71, 0, 133, 133,0.000000 },
- {2318,2318, 60, 0, 153, 153,0.000000 },
- {2319,2319, 58, 0, 40, 40,0.000000 },
- {2320,2320, 53, 0, 40, 40,0.000000 },
- { 397, 397, 64, 0, 86, 86,0.000000 },
- {2321,2321, 71, 0, 13, 13,0.000000 },
- {2322,2322, 61, 0, 326, 326,0.000000 },
- {2323,2323, 61, 0, 640, 640,0.000000 },
- {2324, 392, 44, 0, 80, 80,0.000000 },
- {2324, 393, 40, 0, 40, 40,0.000000 },
- {1595,1595, 69, 0, 20, 20,0.000000 },
- {1595,1595, 68, 0, 20, 20,0.000000 },
- {1595,1595, 63, 0, 33, 33,0.000000 },
- {2325,2326, 74, 0, 200, 200,0.000000 },
- {2327,2328, 60, 0, 340, 340,0.000000 },
- {2329,2330, 80, 0, 113, 113,0.000000 },
- {2331,2332, 64, 0, 500, 500,0.000000 },
- { 397, 397, 72, 0, 73, 73,0.000000 },
- {2333,2334, 78, 0, 806, 806,0.000000 },
- {1608,1609, 82, 0, 353, 353,0.000000 },
- {2315,2315, 48, 0, 13, 13,0.000000 },
- {2316,2316, 53, 0, 40, 40,0.000000 },
- {2335,2335, 0, 0, 546, 546,0.000000 },
- {2336,2337, 0, 0, 546, 546,0.000000 },
- {2338,2339, 0, 0, 40000, 86,0.000000 },
- {2340,2340, 0, 0, 1580, 1580,0.000000 },
- {2341,2341, 0, 0, 1153, 1153,0.000000 },
- {2342,2342, 0, 0, 40000, 220,0.000000 },
- {2343,2343, 0, 0, 40000, 240,0.000000 },
- {2344,2345, 0, 0, 380, 380,0.000000 },
- {2346,2346, 0, 0, 40000, 6,0.000000 },
- {2347,2348, 0, 0, 40000, 20,0.000000 },
- {2349,2350, 0, 0, 40000, 6,0.000000 },
- {2351,2352, 0, 0, 40000, 6,0.000000 },
- {2353,2354, 0, 0, 40000, 20,0.000000 },
- {2355,2356, 0, 0, 40000, 213,0.000000 },
- {2357,2357, 14, 0, 26, 26,0.000000 },
- {2358,2358, 35, 0, 40, 40,0.000000 },
- {2357,2357, 19, 0, 26, 26,0.000000 },
- {2359,2359, 43, 0, 86, 86,0.000000 },
- {2360,2360, 41, 0, 60, 60,0.000000 },
- {2360,2360, 43, 0, 53, 53,0.000000 },
- {2360,2360, 45, 0, 60, 60,0.000000 },
- {2360,2360, 47, 0, 53, 53,0.000000 },
- {2361,2362, 0, 0, 1553, 1553,0.000000 },
- {2363,2363, 0, 0, 1213, 1213,0.000000 },
- {2364,2364, 0, 0, 2280, 2280,0.000000 },
- {2365,2365, 0, 0, 966, 966,0.000000 },
- {2366,2366, 0, 0, 500, 500,0.000000 },
- {2367,2367, 0, 0, 326, 326,0.000000 },
- {2368,2368, 0, 0, 1926, 1926,0.000000 },
- {2369,2369, 0, 0, 520, 520,0.000000 },
- {2370,2370, 0, 0, 993, 993,0.000000 },
- {2371,2371, 0, 0, 1740, 1740,0.000000 },
- {2372,2372, 0, 0, 2300, 80,0.000000 },
- {2373,2373, 0, 0, 513, 513,0.000000 },
- {2374,2374, 0, 0, 40, 40,0.000000 },
- {2375,2375, 0, 0, 1226, 1226,0.000000 },
- {2376,2376, 0, 0, 606, 606,0.000000 },
- {2377,2377, 0, 0, 40000, 6,0.000000 },
- {2378,2378, 0, 0, 993, 6,0.000000 },
- {2379,2379, 0, 0, 40000, 153,0.000000 },
- {2380,2380, 0, 0, 40000, 6,0.000000 },
- {2381,2381, 0, 0, 40000, 0,0.000000 },
- {2382,2382, 0, 0, 40000, 6,0.000000 },
- {2383,2383, 0, 0, 40000, 6,0.000000 },
- {2384,2384, 0, 0, 40000, 6,0.000000 },
- {2385,2385, 0, 0, 273, 273,0.000000 },
- {2386,2386, 0, 0, 1580, 1580,0.000000 },
- {2387,2387, 0, 0, 140, 140,0.000000 },
- { 402, 402, 0, 0, 146, 146,0.000000 },
- {2388,2388, 0, 0, 40000, 446,0.000000 },
- {2389,2389, 0, 0, 2006, 2006,0.000000 },
- {2390,2390, 0, 0, 353, 353,0.000000 },
- {2391,2391, 0, 0, 233, 233,0.000000 },
- {2392,2392, 0, 0, 226, 226,0.000000 },
- {2393,2393, 0, 0, 853, 853,0.000000 },
- {2394,2394, 0, 0, 100, 100,0.000000 },
- {2395,2395, 0, 0, 40000, 40,0.000000 },
- {2396,2397, 0, 0, 633, 20,0.000000 },
- {2398,2398, 0, 0, 40, 40,0.000000 },
- {2399,2400, 0, 0, 493, 493,0.000000 },
- {2401,2401, 0, 0, 40000, 86,0.000000 },
- {2402,2402, 0, 0, 40000, 0,0.000000 },
- {2403,2404, 0, 0, 40000, 66,0.000000 },
- {2405,2406, 0, 0, 186, 46,0.000000 },
- {2407,2408, 0, 0, 40000, 6,0.000000 },
- {2409,2409, 0, 0, 1153, 1153,0.000000 },
- {2410,2410, 0, 0, 40000, 0,0.000000 },
- {2411,2411, 0, 0, 86, 86,0.000000 },
- {2412,2413, 0, 0, 40000, 73,0.000000 },
- {2414,2414, 0, 0, 40000, 40,0.000000 },
- {2415,2416, 0, 0, 40000, 286,0.000000 },
- {2417,2418, 0, 0, 40000, 20,0.000000 },
- {2419,2420, 0, 0, 600, 600,0.000000 },
- {2421,2422, 0, 0, 253, 253,0.000000 },
- {2423,2424, 0, 0, 466, 466,0.000000 },
- {2425,2426, 0, 0, 40000, 6,0.000000 },
- {2427,2427, 33, 0, 53, 53,0.000000 },
- {2428,2429, 38, 0, 46, 46,0.000000 },
- {2430,2430, 38, 0, 13, 13,0.000000 },
- {2431,2431, 38, 0, 86, 86,0.000000 },
- {2432,2432, 40, 0, 6, 6,0.000000 },
- {2433,2434, 41, 0, 60, 60,0.000000 },
- {2435,2435, 0, 0, 20, 20,0.000000 },
- {2435,2435, 41, 0, 26, 26,0.000000 },
- {2360,2360, 48, 0, 53, 53,0.000000 },
- {2436,2436, 17, 0, 446, 446,0.000000 },
- {2360,2360, 50, 0, 46, 46,0.000000 },
- {2435,2435, 45, 0, 20, 20,0.000000 },
- {2437,2437,254, 0, 26, 26,0.000000 },
- {2438,2438, 60, 0, 80, 80,0.000000 },
- {2439,2439, 56, 0, 80, 80,0.000000 },
- {2440,2440, 60, 0, 40, 40,0.000000 },
- {2440,2440, 55, 0, 40, 40,0.000000 },
- {2441,2441, 63, 0, 86, 86,0.000000 },
- {2442,2442, 57, 0, 40, 40,0.000000 },
- {2443,2443, 0, 0, 40000, 106,0.000000 },
- {2444,2444, 0, 0, 246, 246,0.000000 },
- {2445,2445, 0, 0, 3133, 13,0.000000 },
- {2446,2446, 0, 0, 40000, 153,0.000000 },
- {2447,2447, 0, 0, 40000, 480,0.000000 },
- {2448,2448, 0, 0, 40000, 73,0.000000 },
- {2449,2449, 0, 0, 40000, 526,0.000000 },
- {2450,2450, 0, 0, 40000, 146,0.000000 },
- {2451,2451, 0, 0, 4520, 4520,0.000000 },
- {2452,2452, 0, 0, 280, 280,0.000000 },
- { 752, 752, 55, 0, 46, 46,0.000000 },
- {2453,2453, 0, 0, 646, 646,0.000000 },
- {2454,2454, 0, 0, 600, 600,0.000000 },
- {2455,2455, 0, 0, 86, 86,0.000000 },
- {2456,2456, 0, 0, 386, 386,0.000000 },
- {2457,2457, 0, 0, 40000, 0,0.000000 },
- {2458,2458, 0, 0, 1340, 1340,0.000000 },
- {2459,2459, 0, 0, 786, 786,0.000000 },
- {2460,2460, 0, 0, 680, 680,0.000000 },
- {2461,2461, 0, 0, 2113, 2113,0.000000 },
- {2462,2462, 0, 0, 3193, 13,0.000000 },
- {2463,2463, 0, 0, 726, 726,0.000000 },
- { 884, 884, 0, 0, 46, 46,0.000000 },
- { 884, 884, 28, 0, 100, 100,0.000000 },
- {2464,2464, 29, 0, 66, 66,0.000000 },
- { 886, 886, 31, 0, 20, 20,0.000000 },
- { 360, 360, 32, 0, 46, 46,0.000000 },
- { 361, 361, 33, 0, 100, 100,0.000000 },
- {2453,2453, 34, 0, 760, 760,0.000000 },
- { 888, 888, 29, 0, 46, 46,0.000000 },
- { 886, 886, 55, 0, 13, 13,0.000000 },
- { 890, 890, 48, 0, 73, 73,0.000000 },
- { 884, 884, 58, 0, 40, 40,0.000000 },
- {2465,2465, 45, 0, 46, 46,0.000000 },
- {2465,2465, 43, 0, 46, 46,0.000000 },
- {2466,2466, 73, 0, 520, 520,0.000000 },
- {2467,2467, 72, 0, 266, 266,0.000000 },
- {2468,2468, 76, 0, 160, 160,0.000000 },
- {2467,2467, 84, 0, 273, 273,0.000000 },
- {2468,2468, 36, 0, 166, 166,0.000000 },
- {2469,2469, 65, 0, 86, 86,0.000000 },
- {2470,2470, 83, 0, 73, 73,0.000000 },
- {2471,2471, 50, 0, 300, 300,0.000000 },
- {2468,2468, 77, 0, 133, 133,0.000000 },
- { 897, 897, 55, 0, 33, 33,0.000000 },
- {2472,2472, 60, 0, 46, 46,0.000000 },
- { 897, 897, 50, 0, 33, 33,0.000000 },
- {2473,2473, 42, 0, 206, 206,0.000000 },
- {2473,2473, 46, 0, 166, 166,0.000000 },
- {2474,2474, 71, 0, 133, 133,0.000000 },
- {2474,2474, 60, 0, 160, 160,0.000000 },
- {2455,2455, 58, 0, 66, 66,0.000000 },
- {2455,2455, 53, 0, 86, 86,0.000000 },
- {2475,2475, 91, 0, 40, 40,0.000000 },
- {2476,2476, 61, 0, 140, 140,0.000000 },
- {2477,2477, 61, 0, 786, 786,0.000000 },
- {2478,2478, 44, 0, 33, 33,0.000000 },
- {2479,2479, 40, 0, 840, 840,0.000000 },
- {2480,2480, 69, 0, 40, 40,0.000000 },
- { 361, 361, 68, 0, 40, 40,0.000000 },
- { 361, 361, 63, 0, 60, 60,0.000000 },
- {2481,2481, 74, 0, 73, 73,0.000000 },
- {2482,2482, 60, 0, 73, 73,0.000000 },
- { 908, 908, 80, 0, 33, 33,0.000000 },
- {2483,2483, 64, 0, 306, 306,0.000000 },
- {2483,2483, 73, 0, 260, 260,0.000000 },
- {2483,2483, 70, 0, 260, 260,0.000000 },
- { 886, 886, 68, 0, 6, 6,0.000000 },
- { 886, 886, 48, 0, 13, 13,0.000000 },
- {2484,2484, 0, 0, 440, 440,0.000000 },
- {2485,2485, 0, 0, 253, 253,0.000000 },
- {2486,2486, 0, 0, 306, 306,0.000000 },
- {2487,2487, 0, 0, 1213, 1213,0.000000 },
- {2488,2488, 0, 0, 626, 626,0.000000 },
- {2489,2489, 0, 0, 40000, 206,0.000000 },
- {2490,2490, 0, 0, 40000, 100,0.000000 },
- {2491,2491, 0, 0, 40000, 13,0.000000 },
- {2492,2492, 0, 0, 2273, 2273,0.000000 },
- {2493,2493, 0, 0, 1740, 1740,0.000000 },
- {2494,2494, 0, 0, 1953, 1953,0.000000 },
- {2495,2495, 0, 0, 1740, 1740,0.000000 },
- {2496,2496, 0, 0, 386, 386,0.000000 },
- {2497,2497, 0, 0, 233, 233,0.000000 },
- {2498,2498, 0, 0, 40000, 106,0.000000 },
- {2499,2499, 0, 0, 40000, 13,0.000000 },
- {2500,2500, 0, 0, 40000, 0,0.000000 },
- {2501,2501, 0, 0, 40000, 186,0.000000 },
- {2502,2502, 0, 0, 66, 66,0.000000 },
- {2503,2503, 0, 0, 46, 46,0.000000 },
- {2504,2504, 0, 0, 40000, 186,0.000000 },
- {2505,2505, 0, 0, 1106, 1106,0.000000 },
- {2506,2506, 0, 0, 40000, 186,0.000000 },
- {2507,2507, 0, 0, 40000, 100,0.000000 },
- {2508,2508, 0, 0, 40000, 206,0.000000 },
- {2509,2509, 0, 0, 40000, 60,0.000000 },
- {2510,2510, 0, 0, 40000, 106,0.000000 },
- {2511,2511, 0, 0, 60, 60,0.000000 },
- {2512,2512, 0, 0, 40, 40,0.000000 },
- {2513,2513, 0, 0, 1833, 26,0.000000 },
- {2514,2514, 0, 0, 806, 806,0.000000 },
- {2515,2515, 0, 0, 1106, 1106,0.000000 },
- {2516,2516, 0, 0, 40000, 6,0.000000 },
- {2517,2517, 0, 0, 40000, 180,0.000000 },
- {2518,2518, 0, 0, 40000, 340,0.000000 },
- {2519,2519, 0, 0, 1873, 6,0.000000 },
- {2520,2520, 0, 0, 2586, 2586,0.000000 },
- {2521,2521, 0, 0, 1740, 1740,0.000000 },
- {2522,2522, 0, 0, 3493, 13,0.000000 },
- {2523,2523, 0, 0, 40000, 266,0.000000 },
- {2524,2524, 0, 0, 6160, 33,0.000000 },
- {2525,2525, 0, 0, 40000, 46,0.000000 },
- {2526,2526, 0, 0, 1140, 1140,0.000000 },
- { 346, 346, 30, 0, 46, 46,0.000000 },
- { 346, 346, 31, 0, 33, 33,0.000000 },
- { 346, 346, 32, 0, 40, 40,0.000000 },
- { 346, 346, 33, 0, 46, 46,0.000000 },
- { 346, 346, 34, 0, 53, 53,0.000000 },
- { 346, 346, 35, 0, 33, 33,0.000000 },
- { 346, 346, 37, 0, 146, 146,0.000000 },
- { 346, 346, 39, 0, 186, 186,0.000000 },
- { 346, 346, 41, 0, 206, 206,0.000000 },
- { 346, 346, 43, 0, 133, 133,0.000000 },
- { 346, 346, 45, 0, 126, 126,0.000000 },
- { 346, 346, 47, 0, 153, 153,0.000000 },
- { 346, 346, 48, 0, 153, 153,0.000000 },
- { 346, 346, 49, 0, 153, 153,0.000000 },
- { 512, 512, 84, 0, 73, 73,0.000000 },
- {2206,2206, 84, 0, 140, 140,0.000000 },
- {2527,2527, 55, 0, 13, 13,0.000000 },
- {2528,2528, 36, 0, 20, 20,0.000000 },
- {2529,2529, 38, 0, 66, 66,0.000000 },
- {2530,2530, 60, 0, 86, 86,0.000000 },
- {2531,2531, 38, 0, 60, 60,0.000000 },
- {2532,2532, 17, 0, 2233, 2233,0.000000 },
- {2532,2532, 18, 0, 2266, 2266,0.000000 },
- {2532,2532, 19, 0, 2280, 2280,0.000000 },
- {2532,2532, 20, 0, 46, 46,0.000000 },
- {2532,2532, 21, 0, 46, 46,0.000000 },
- {2532,2532, 22, 0, 40, 40,0.000000 },
- {2532,2532, 23, 0, 53, 53,0.000000 },
- {2532,2532, 24, 0, 100, 100,0.000000 },
- {2532,2532, 25, 0, 46, 46,0.000000 },
- {2532,2532, 26, 0, 60, 60,0.000000 },
- {2532,2532, 27, 0, 40, 40,0.000000 },
- {2532,2532, 28, 0, 53, 53,0.000000 },
- {2532,2532, 29, 0, 126, 126,0.000000 },
- {2533,2533, 84, 0, 133, 133,0.000000 },
- {2534,2534, 48, 0, 86, 86,0.000000 },
- {2535,2535, 65, 0, 486, 486,0.000000 },
- {2536,2536, 65, 0, 526, 526,0.000000 },
- {2537,2537, 55, 0, 66, 66,0.000000 },
- {2537,2537, 41, 0, 60, 60,0.000000 },
- { 346, 346, 63, 0, 106, 106,0.000000 },
- { 346, 346, 55, 0, 106, 106,0.000000 },
- {2538,2538, 55, 0, 1200, 1200,0.000000 },
- {2538,2538, 53, 0, 1206, 1206,0.000000 },
- {2534,2534, 50, 0, 86, 86,0.000000 },
- { 506, 506, 84, 0, 133, 133,0.000000 },
- { 506, 506, 74, 0, 133, 133,0.000000 },
- { 504, 504, 84, 0, 473, 473,0.000000 },
- { 504, 504, 74, 0, 486, 486,0.000000 },
- {2539,2539, 84, 0, 133, 133,0.000000 },
- {2540,2540, 74, 0, 20, 20,0.000000 },
- {1911,1911, 48, 0, 46, 46,0.000000 },
- {1911,1911, 36, 0, 20, 20,0.000000 },
- {2541,2541, 74, 0, 133, 133,0.000000 },
- {2542,2542, 0, 0, 613, 613,0.000000 },
- {2543,2543, 0, 0, 40000, 480,0.000000 },
- {2544,2544, 0, 0, 1133, 1133,0.000000 },
- {2545,2545, 0, 0, 1200, 1200,0.000000 },
- {2546,2547, 0, 0, 1313, 1313,0.000000 },
- {2548,2549, 0, 0, 40000, 6,0.000000 },
- {2550,2550, 0, 0, 1740, 1740,0.000000 },
- {2551,2552, 0, 0, 860, 860,0.000000 },
- {2553,2553, 0, 0, 40000, 0,0.000000 },
- {2554,2554, 0, 0, 2300, 2300,0.000000 },
- {2555,2556, 0, 0, 40000, 0,0.000000 },
- {2557,2557, 0, 0, 506, 13,0.000000 },
- {2558,1467, 0, 0, 40000, 6,0.000000 },
- {2559,2560, 0, 0, 40000, 0,0.000000 },
- {2561,2561, 0, 0, 40000, 106,0.000000 },
- {2562,2562, 0, 0, 1013, 1013,0.000000 },
- {2563,2564, 0, 0, 1020, 1020,0.000000 },
- {2565,2565, 0, 0, 1746, 1746,0.000000 },
- {2566,2567, 0, 0, 1446, 1446,0.000000 },
- {2568,2568, 0, 0, 826, 826,0.000000 },
- {2569,2569, 0, 0, 2293, 2293,0.000000 },
- {2570,2570, 0, 0, 2386, 2386,0.000000 },
- {2571,2572, 0, 0, 40000, 46,0.000000 },
- {2573,2574, 0, 0, 40000, 26,0.000000 },
- {2575,2575, 0, 0, 40000, 126,0.000000 },
- { 229,2576, 0, 0, 1893, 13,0.000000 },
- {2577,2577, 0, 0, 1046, 1046,0.000000 },
- { 239,2578, 0, 0, 40000, 53,0.000000 },
- {2579,2579, 0, 0, 40000, 13,0.000000 },
- {2580,2580, 0, 0, 40000, 66,0.000000 },
- {2581,2582, 0, 0, 3466, 3466,0.000000 },
- {2583,2584, 0, 0, 233, 233,0.000000 },
- {2585,2586, 0, 0, 40000, 0,0.000000 },
- {2587,2588, 0, 0, 40000, 0,0.000000 },
- {2589,2589, 0, 0, 40000, 6,0.000000 },
- {2590,2590, 0, 0, 40000, 6,0.000000 },
- {2591,2592, 0, 0, 40000, 0,0.000000 },
- {2593,2594, 0, 0, 680, 0,0.000000 },
- {2595,2595, 0, 0, 40000, 0,0.000000 },
- {2596,2597, 0, 0, 40000, 6,0.000000 },
- {2598,2599, 0, 0, 40000, 0,0.000000 },
- {2600,2601, 0, 0, 40000, 13,0.000000 },
- {2602,2602, 0, 0, 5093, 5093,0.000000 },
- {2603,2603, 0, 0, 40000, 6,0.000000 },
- {2604,2604, 0, 0, 40000, 40,0.000000 },
- {2605,2606, 0, 0, 40000, 0,0.000000 },
- {2607,2607, 0, 0, 40000, 0,0.000000 },
- {2608,2609, 0, 0, 40000, 6,0.000000 },
- {2610,2610, 0, 0, 40000, 20,0.000000 },
- {2611,2611, 0, 0, 40000, 6,0.000000 },
- {2612,2612, 0, 0, 2253, 2253,0.000000 },
- {2613,2613, 0, 0, 973, 973,0.000000 },
- {2614,2615, 0, 0, 40000, 6,0.000000 },
- {2616,2617, 0, 0, 40000, 6,0.000000 },
- {2618,2619, 0, 0, 353, 353,0.000000 },
- {2620,2621, 0, 0, 40000, 500,0.000000 },
- {2622,2623, 0, 0, 40000, 26,0.000000 },
- {2624,2625, 0, 0, 40000, 53,0.000000 },
- {2626,2627, 0, 0, 4026, 13,0.000000 },
- {2628,2629, 0, 0, 3400, 13,0.000000 },
- {1516,2630, 0, 0, 226, 226,0.000000 },
- {2631,2632, 0, 0, 40000, 193,0.000000 },
- {2633,2633, 0, 0, 2380, 2380,0.000000 },
- {2634,2635, 0, 0, 40000, 373,0.000000 },
- {2636,2636, 0, 0, 40000, 133,0.000000 },
- {2637,2637, 0, 0, 280, 280,0.000000 },
- {2638,2639, 0, 0, 273, 273,0.000000 },
- {2640,2641, 0, 0, 3333, 3333,0.000000 },
- {2642,2642, 0, 0, 40000, 266,0.000000 },
- {2643,2644, 0, 0, 166, 166,0.000000 },
- {2645,2645, 0, 0, 40000, 6,0.000000 },
- {2646,2647, 0, 0, 40000, 0,0.000000 },
- {2648,2648, 0, 0, 586, 586,0.000000 },
- {2649,2649, 0, 0, 1660, 86,0.000000 },
- {2650,2651, 0, 0, 440, 440,0.000000 },
- {2652,2652, 0, 0, 40000, 113,0.000000 },
- {2653,2654, 0, 0, 40000, 6,0.000000 },
- {2655,2656, 0, 0, 1766, 1766,0.000000 },
- {2657,2657, 0, 0, 40000, 0,0.000000 },
- {2658,2658, 35, 0, 20, 20,0.000000 },
- {2659,2659, 35, 0, 26, 26,0.000000 },
- {2660,2660, 52, 0, 20, 20,0.000000 },
- {2661,2661, 60, 0, 80, 80,0.000000 },
- {2662,2662, 58, 0, 20, 20,0.000000 },
- {2663,2663, 60, 0, 113, 113,0.000000 },
- {2664,2664, 50, 0, 433, 433,0.000000 },
- {2665,2665, 43, 0, 40, 40,0.000000 },
- {2664,2664, 55, 0, 513, 513,0.000000 },
- {1553,1553, 43, 0, 26, 26,0.000000 },
- {2666,2666, 50, 0, 173, 173,0.000000 },
- {2667,2667, 43, 0, 173, 173,0.000000 },
- {2666,2666, 53, 0, 40, 40,0.000000 },
- {2666,2666, 57, 0, 186, 186,0.000000 },
- {2668,2668, 72, 0, 260, 260,0.000000 },
- {2666,2666, 60, 0, 220, 220,0.000000 },
- { 373, 373, 76, 0, 260, 260,0.000000 },
- {2669,2669, 84, 0, 213, 213,0.000000 },
- {2670,2670, 42, 0, 406, 406,0.000000 },
- {2671,2671, 65, 0, 86, 86,0.000000 },
- {2672,2672, 84, 0, 113, 113,0.000000 },
- {2673,2673, 84, 0, 426, 426,0.000000 },
- {2674,2674, 24, 0, 46, 46,0.000000 },
- { 383, 383, 77, 0, 246, 246,0.000000 },
- {2675,2675, 58, 0, 153, 153,0.000000 },
- {2676,2676, 53, 0, 153, 153,0.000000 },
- {2677,2677, 64, 0, 73, 73,0.000000 },
- {2678,2678, 71, 0, 26, 26,0.000000 },
- {2679,2679, 44, 0, 606, 606,0.000000 },
- {2680,2680, 40, 0, 366, 366,0.000000 },
- {2681,2681, 69, 0, 20, 20,0.000000 },
- {2682,2682, 60, 0, 360, 360,0.000000 },
- {2683,2683, 80, 0, 60, 60,0.000000 },
- {2684,2684, 64, 0, 873, 873,0.000000 },
- {2685,2685, 72, 0, 33, 33,0.000000 },
- {2686,2686, 70, 0, 273, 273,0.000000 },
- {2687,2687, 48, 0, 40, 40,0.000000 },
- {2688,2688, 53, 0, 213, 213,0.000000 },
- {2689,2690, 0, 0, 40000, 140,0.000000 },
- {2691,2692, 0, 0, 626, 626,0.000000 },
- {2693,2694, 0, 0, 40000, 0,0.000000 },
- {2695,2696, 0, 0, 2213, 2213,0.000000 },
- {2697,2698, 0, 0, 4140, 0,0.000000 },
- { 192,2699, 0, 0, 40000, 6,0.000000 },
- {2700,2701, 0, 0, 153, 153,0.000000 },
- {2702,2703, 0, 0, 253, 253,0.000000 },
- {2704,2705, 0, 0, 40000, 0,0.000000 },
- {2706,2707, 0, 0, 40000, 6,0.000000 },
- {2708,2709, 0, 0, 40000, 6,0.000000 },
- {2710,2711, 0, 0, 440, 440,0.000000 },
- {2712,1473, 0, 0, 213, 213,0.000000 },
- {2713,2714, 0, 0, 120, 120,0.000000 },
- {2715,2716, 0, 0, 140, 140,0.000000 },
- {1478,2717, 0, 0, 40000, 113,0.000000 },
- {2718,2719, 0, 0, 40000, 6,0.000000 },
- { 286,2720, 0, 0, 40000, 20,0.000000 },
- {2721,2722, 0, 0, 40000, 13,0.000000 },
- {2723,2724, 0, 0, 40000, 0,0.000000 },
- {2725,2726, 0, 0, 526, 526,0.000000 },
- {2727,2724, 0, 0, 40000, 0,0.000000 },
- {1514,2728, 0, 0, 40000, 53,0.000000 },
- {2729,2730, 0, 0, 186, 186,0.000000 },
- {2731,2732, 0, 0, 226, 226,0.000000 },
- {2733,2734, 0, 0, 266, 266,0.000000 },
- {2735,2736, 0, 0, 80, 80,0.000000 },
- {2737,2738, 0, 0, 40000, 0,0.000000 },
- {2739,2740, 0, 0, 260, 260,0.000000 },
- {2741,2742, 0, 0, 286, 286,0.000000 },
- {2743,2744, 0, 0, 193, 193,0.000000 },
- {2745,2746, 0, 0, 40000, 0,0.000000 },
- {2747,2747, 35, 0, 20, 20,0.000000 },
- {2748,2748, 60, 0, 153, 153,0.000000 },
- {2749,2749, 43, 0, 20, 20,0.000000 },
- {2750,2750, 0, 0, 626, 626,0.000000 },
- {2751,2752, 0, 0, 1553, 1553,0.000000 },
- {2753,2754, 0, 0, 1386, 1386,0.000000 },
- {2755,2756, 0, 0, 2026, 2026,0.000000 },
- {2757,2758, 0, 0, 1020, 1020,0.000000 },
- {2759,2760, 0, 0, 2486, 2486,0.000000 },
- {2761,2762, 0, 0, 2880, 2880,0.000000 },
- {2763,2764, 0, 0, 2346, 2346,0.000000 },
- {2765,2766, 0, 0, 40000, 0,0.000000 },
- {2767,2768, 0, 0, 40000, 100,0.000000 },
- {2769,2770, 0, 0, 40000, 13,0.000000 },
- {2771,2772, 0, 0, 40000, 6,0.000000 },
- {2773,2774, 0, 0, 40000, 0,0.000000 },
- {2775,2776, 0, 0, 40000, 13,0.000000 },
- {2777,2778, 0, 0, 40000, 0,0.000000 },
- {2779,2780, 0, 0, 40000, 6,0.000000 },
- {2781,2782, 0, 0, 40000, 6,0.000000 },
- {2783,2784, 0, 0, 913, 913,0.000000 },
- {2785,2786, 0, 0, 1653, 1653,0.000000 },
- {2787,2788, 0, 0, 40000, 153,0.000000 },
- {2789,2790, 0, 0, 1273, 1273,0.000000 },
- {2791,2792, 0, 0, 1166, 1166,0.000000 },
- {2793,2794, 0, 0, 386, 386,0.000000 },
- {2795,2796, 0, 0, 40000, 1993,0.000000 },
- {2795,2797, 0, 0, 2526, 1333,0.000000 },
- {2798,2799, 0, 0, 166, 6,0.000000 },
- {2800,2801, 0, 0, 13080, 213,0.000000 },
- {2802,2803, 0, 0, 40000, 6,0.000000 },
- {2804,2805, 0, 0, 40000, 6,0.000000 },
- {2806,2807, 0, 0, 493, 493,0.000000 },
- {2808,2809, 0, 0, 126, 6,0.000000 },
- {2810,2811, 0, 0, 80, 80,0.000000 },
- {2812,2813, 0, 0, 380, 380,0.000000 },
- {2814,2815, 0, 0, 2506, 2506,0.000000 },
- {2816,2817, 0, 0, 2186, 2186,0.000000 },
- {2818,2819, 0, 0, 2520, 2520,0.000000 },
- {2820,2821, 0, 0, 440, 440,0.000000 },
- {2822,2823, 0, 0, 106, 106,0.000000 },
- {2824,2825, 0, 0, 1933, 1933,0.000000 },
- {2826,2827, 0, 0, 40000, 6,0.000000 },
- {2828,2829, 0, 0, 1933, 1933,0.000000 },
- {2830,2831, 0, 0, 546, 546,0.000000 },
- {2832,2833, 0, 0, 973, 973,0.000000 },
- {2834,2835, 0, 0, 586, 26,0.000000 },
- {2836,2837, 0, 0, 786, 786,0.000000 },
- {2838,2839, 0, 0, 1920, 1920,0.000000 },
- {2840,2841, 0, 0, 333, 333,0.000000 },
- {2842,2843, 0, 0, 1120, 1120,0.000000 },
- {2844,2845, 0, 0, 40000, 153,0.000000 },
- {2846,2847, 0, 0, 40000, 153,0.000000 },
- {2848,2849, 0, 0, 40000, 153,0.000000 },
- {2850,2851, 0, 0, 40000, 213,0.000000 },
- {2852,2853, 0, 0, 40000, 240,0.000000 },
- {2854,2855, 0, 0, 40000, 93,0.000000 },
- {2856,2856, 0, 0, 333, 333,0.000000 },
- {2857,2857, 0, 0, 333, 333,0.000000 },
- {2858,2859, 0, 0, 866, 866,0.000000 },
- {2860,2861, 0, 0, 40000, 180,0.000000 },
- {2862,2863, 0, 0, 866, 866,0.000000 },
- {2864,2865, 0, 0, 40000, 6,0.000000 },
- {2866,2867, 0, 0, 946, 946,0.000000 },
- {2868,2869, 0, 0, 906, 906,0.000000 },
- {2870,2871, 0, 0, 846, 846,0.000000 },
- {2872,2873, 0, 0, 160, 160,0.000000 },
- {2874,2875, 0, 0, 586, 6,0.000000 },
- {2876,2877, 0, 0, 160, 160,0.000000 },
- {2878,2879, 0, 0, 760, 760,0.000000 },
- {2880,2881, 0, 0, 1193, 1193,0.000000 },
- {2882,2883, 0, 0, 493, 493,0.000000 },
- {2884,2885, 0, 0, 893, 893,0.000000 },
- {2886,2887, 0, 0, 40000, 0,0.000000 },
- {2888,2888, 0, 0, 4413, 4413,0.000000 },
- {2889,2889, 0, 0, 4193, 4193,0.000000 },
- {2890,2890, 0, 0, 3946, 3946,0.000000 },
- {2891,2892, 0, 0, 40000, 26,0.000000 },
- {2893,2893, 0, 0, 60, 60,0.000000 },
- {2894,2894, 0, 0, 40, 40,0.000000 },
- {2895,2895, 0, 0, 1773, 1773,0.000000 },
- {2896,2897, 0, 0, 40000, 6,0.000000 },
- {2898,2899, 0, 0, 1073, 6,0.000000 },
- {2353,2900, 0, 0, 4800, 4800,0.000000 },
- {2901,2901, 0, 0, 126, 126,0.000000 },
- {2902,2903, 0, 0, 40000, 20,0.000000 },
- {2904,2905, 0, 0, 40000, 20,0.000000 },
- {2906,2907, 0, 0, 40000, 6,0.000000 },
- {2908,2909, 0, 0, 4546, 4546,0.000000 },
- {2910,2911, 0, 0, 40000, 6,0.000000 },
- {2912,2912, 0, 0, 913, 913,0.000000 },
- {2913,2914, 0, 0, 486, 486,0.000000 },
- {2915,2916, 0, 0, 1740, 1740,0.000000 },
- {2917,2918, 0, 0, 1726, 1726,0.000000 },
- {2919,2920, 0, 0, 1740, 1740,0.000000 },
- {2921,2922, 0, 0, 1420, 1420,0.000000 },
- {2923,2924, 0, 0, 546, 546,0.000000 },
- {2925,2926, 0, 0, 513, 513,0.000000 },
- {2927,2928, 0, 0, 226, 226,0.000000 },
- {2929,2929, 0, 0, 40000, 73,0.000000 },
- {2930,2931, 0, 0, 40000, 33,0.000000 },
- {2932,2933, 0, 0, 40000, 6,0.000000 },
- {2934,2935, 0, 0, 40000, 20,0.000000 },
- {2936,2937, 0, 0, 40000, 13,0.000000 },
- {2938,2939, 0, 0, 40000, 106,0.000000 },
- {2940,2940, 0, 0, 40, 40,0.000000 },
- {2941,2941, 0, 0, 40000, 86,0.000000 },
- {2942,2943, 0, 0, 293, 293,0.000000 },
- {2944,2944, 0, 0, 53, 53,0.000000 },
- {2945,2945, 0, 0, 260, 260,0.000000 },
- {2946,2947, 0, 0, 1026, 1026,0.000000 },
- {2948,2948, 0, 0, 40000, 120,0.000000 },
- {2949,2949, 0, 0, 280, 280,0.000000 },
- {2950,2951, 0, 0, 3926, 3926,0.000000 },
- {2952,2953, 0, 0, 6373, 206,0.000000 },
- {2954,2954, 60, 0, 40000, 0,0.000000 },
- {2955,2956, 0, 0, 40000, 153,0.000000 },
- {2957,2958, 0, 0, 40000, 6,0.000000 },
- {2959,2960, 0, 0, 40000, 26,0.000000 },
- {2961,2962, 0, 0, 700, 140,0.000000 },
- {2963,2963, 0, 0, 506, 506,0.000000 },
- {2964,2964, 0, 0, 40000, 680,0.000000 },
- {2436,2436, 49, 0, 593, 593,0.000000 },
- {2357,2357, 61, 0, 26, 26,0.000000 },
- {2357,2357, 56, 0, 26, 26,0.000000 },
- {2357,2357, 58, 0, 26, 26,0.000000 },
- {2357,2357, 49, 0, 33, 33,0.000000 },
- {2357,2357, 44, 0, 26, 26,0.000000 },
- {2965,2965, 0, 0, 40000, 186,0.000000 },
- {2966,2966, 0, 0, 186, 186,0.000000 },
- {2967,2967, 0, 0, 1793, 1793,0.000000 },
- {2968,2968, 0, 0, 40000, 53,0.000000 },
- {2969,2969, 0, 0, 80, 80,0.000000 },
- {2970,2970, 84, 0, 40, 40,0.000000 },
- {2971,2971, 72, 0, 140, 140,0.000000 },
- {2972,2972, 0, 0, 2080, 2080,0.000000 },
- {2973,2973, 0, 0, 40000, 66,0.000000 },
- {2974,2974, 0, 0, 40000, 2100,0.000000 },
- {2975,2975, 0, 0, 1766, 1766,0.000000 },
- {2976,2976, 0, 0, 120, 120,0.000000 },
- {2977,2977, 0, 0, 40000, 0,0.000000 },
- {2978,2978, 0, 0, 40000, 66,0.000000 },
- {2979,2979, 0, 0, 40000, 73,0.000000 },
- {2980,2980, 0, 0, 40000, 126,0.000000 },
- {2981,2981, 0, 0, 40000, 506,0.000000 },
- {2982,2982, 0, 0, 40000, 373,0.000000 },
- {2983,2983, 0, 0, 920, 920,0.000000 },
- {2984,2984, 0, 0, 1106, 1106,0.000000 },
- {2985,2985, 0, 0, 40000, 0,0.000000 },
- {2986,2986, 0, 0, 40000, 0,0.000000 },
- {2987,2987, 0, 0, 40000, 0,0.000000 },
- {2988,2988, 0, 0, 40000, 140,0.000000 },
- {2989,2989, 0, 0, 726, 726,0.000000 },
- {2990,2990, 0, 0, 573, 573,0.000000 },
- {2991,2991, 0, 0, 40000, 146,0.000000 },
- {2992,2992, 0, 0, 40000, 66,0.000000 },
- {2993,2993, 0, 0, 146, 146,0.000000 },
- {2994,2994, 0, 0, 1380, 1380,0.000000 },
- {2995,2995, 0, 0, 40000, 113,0.000000 },
- {2996,2996, 0, 0, 1140, 1140,0.000000 },
- {2997,2997, 0, 0, 1180, 1180,0.000000 },
- {2998,2998, 0, 0, 40000, 0,0.000000 },
- {2999,2999, 0, 0, 40000, 13,0.000000 },
- {3000,3000, 0, 0, 193, 193,0.000000 },
- {3001,3001, 0, 0, 40000, 0,0.000000 },
- {3002,3002, 0, 0, 40000, 433,0.000000 },
- {3003,3003, 0, 0, 1206, 1206,0.000000 },
- {3004,3004, 0, 0, 40000, 480,0.000000 },
- {3005,3005, 0, 0, 40000, 0,0.000000 },
- {3006,3006, 0, 0, 126, 126,0.000000 },
- {3007,3007, 0, 0, 333, 333,0.000000 },
- { 350, 350, 0, 0, 66, 66,0.000000 },
- {3008,3008, 0, 0, 46, 46,0.000000 },
- {3009,3009, 0, 0, 26, 26,0.000000 },
- {3010,3010, 0, 0, 320, 320,0.000000 },
- {3011,3011, 0, 0, 2380, 2380,0.000000 },
- {3012,3012, 0, 0, 180, 180,0.000000 },
- {3013,3013, 0, 0, 260, 260,0.000000 },
- {3014,3014, 0, 0, 40000, 6,0.000000 },
- {3015,3015, 0, 0, 40000, 146,0.000000 },
- { 350, 350, 36, 0, 86, 86,0.000000 },
- { 369, 369, 37, 0, 33, 33,0.000000 },
- {3008,3008, 38, 0, 53, 53,0.000000 },
- { 369, 369, 24, 0, 33, 33,0.000000 },
- {3008,3008, 32, 0, 60, 60,0.000000 },
- { 369, 369, 48, 0, 33, 33,0.000000 },
- {3009,3009, 42, 0, 33, 33,0.000000 },
- { 369, 369, 50, 0, 100, 100,0.000000 },
- { 369, 369, 52, 0, 66, 66,0.000000 },
- { 369, 369, 54, 0, 93, 93,0.000000 },
- { 369, 369, 55, 0, 86, 86,0.000000 },
- { 369, 369, 57, 0, 100, 100,0.000000 },
- {3010,3010, 51, 0, 333, 333,0.000000 },
- { 144, 144, 61, 0, 40, 40,0.000000 },
- {3016,3016, 0, 0, 106, 106,0.000000 },
- {3016,3016, 63, 0, 86, 86,0.000000 },
- {3016,3016, 64, 0, 86, 86,0.000000 },
- {3017,3017, 40, 0, 60, 60,0.000000 },
- {3017,3017, 70, 0, 40, 40,0.000000 },
- {3018,3018, 0, 0, 40000, 6,0.000000 },
- {3019,3019, 0, 0, 40000, 0,0.000000 },
- {3020,3020, 0, 0, 40000, 6,0.000000 },
- {3021,3021, 0, 0, 40000, 6,0.000000 },
- {3022,3022, 38, 0, 46, 46,0.000000 },
- {2441,2441, 57, 0, 73, 73,0.000000 },
- {3023,3023, 63, 0, 33, 33,0.000000 },
- {3024,3024, 74, 0, 80, 80,0.000000 },
- {3025,3025, 74, 0, 206, 206,0.000000 },
- {3026,3026, 60, 0, 300, 300,0.000000 },
- {1593,1594, 35, 0, 646, 646,0.000000 },
- {1564,1565, 35, 0, 66, 66,0.000000 },
- { 248,3027, 0, 0, 40000, 33,0.000000 },
- {1445,3028, 0, 0, 1860, 1860,0.000000 },
- {1447,3029, 0, 0, 1626, 1626,0.000000 },
- {1452,3030, 0, 0, 1740, 1740,0.000000 },
- {1544,3031, 0, 0, 160, 160,0.000000 },
- {1546,3032, 0, 0, 1913, 1913,0.000000 },
- { 398, 399, 35, 0, 600, 600,0.000000 },
- {1550,3033, 35, 0, 20, 20,0.000000 },
- {1556,1557, 35, 0, 386, 386,0.000000 },
- {1558,1559, 35, 0, 346, 346,0.000000 },
- {1570,1571, 35, 0, 360, 360,0.000000 },
- {1608,1609, 35, 0, 460, 460,0.000000 },
- {1595,1596, 35, 0, 60, 60,0.000000 },
- { 159,1597, 35, 0, 60, 60,0.000000 },
- {1610,1611, 35, 0, 60, 60,0.000000 },
- { 397,1588, 35, 0, 100, 100,0.000000 },
- {1606,1607, 35, 0, 46, 46,0.000000 },
- { 145,1576, 35, 0, 6, 6,0.000000 },
- {1612,1613, 35, 0, 60, 60,0.000000 },
- {1577,1578, 35, 0, 53, 53,0.000000 },
- {1614,1615, 35, 0, 6, 6,0.000000 },
- {1550,1551, 35, 0, 20, 20,0.000000 },
- { 364, 365, 35, 0, 20, 20,0.000000 },
- { 129,1549, 35, 0, 93, 93,0.000000 },
- { 132,1552, 35, 0, 20, 20,0.000000 },
- {1553,1554, 35, 0, 33, 33,0.000000 },
- { 129,1548, 35, 0, 86, 86,0.000000 },
- { 134,1555, 35, 0, 133, 133,0.000000 },
- {1560,1561, 35, 0, 140, 140,0.000000 },
- {1562,1563, 35, 0, 40000, 0,0.000000 },
- {1572,1573, 35, 0, 66, 66,0.000000 },
- {1574,1575, 35, 0, 60, 60,0.000000 },
- {1581,1582, 35, 0, 20, 20,0.000000 },
- { 149,1583, 35, 0, 53, 53,0.000000 },
- {1584,1585, 35, 0, 206, 206,0.000000 },
- {1591,1592, 35, 0, 386, 386,0.000000 },
- {1579,1580, 35, 0, 53, 53,0.000000 },
- {1586,1587, 35, 0, 180, 180,0.000000 },
- {1589,1590, 35, 0, 20, 20,0.000000 },
- {1600,1601, 35, 0, 140, 140,0.000000 },
- {1602,1603, 35, 0, 220, 220,0.000000 },
- {1604,1605, 35, 0, 1293, 1293,0.000000 },
- {1598,1599, 35, 0, 233, 233,0.000000 },
- { 374, 375, 35, 0, 580, 580,0.000000 },
- {1566,1567, 35, 0, 1666, 0,0.000000 },
- {2306,2307, 35, 0, 140, 140,0.000000 },
- {3034, 339, 35, 0, 4293, 4293,0.000000 },
- {2305,1548, 35, 0, 80, 80,0.000000 },
- {1595,1595, 35, 0, 60, 60,0.000000 },
- {2303,2304, 35, 0, 20, 20,0.000000 },
- {1560,2308, 35, 0, 140, 140,0.000000 },
- {2309,2310, 35, 0, 40000, 0,0.000000 },
- {1568,1568, 35, 0, 20, 20,0.000000 },
- {2311,2312, 35, 0, 66, 66,0.000000 },
- {2313,2314, 35, 0, 66, 66,0.000000 },
- {2315,2315, 35, 0, 13, 13,0.000000 },
- {2316,2316, 35, 0, 53, 53,0.000000 },
- {1612,1612, 35, 0, 60, 60,0.000000 },
- {2317,2317, 35, 0, 153, 153,0.000000 },
- {2318,2318, 35, 0, 86, 86,0.000000 },
- {2319,2319, 35, 0, 46, 46,0.000000 },
- {2320,2320, 35, 0, 46, 46,0.000000 },
- {2321,2321, 35, 0, 20, 20,0.000000 },
- {2322,2322, 35, 0, 426, 426,0.000000 },
- {2323,2323, 35, 0, 826, 826,0.000000 },
- {2324, 392, 35, 0, 20, 20,0.000000 },
- {2324, 393, 35, 0, 346, 346,0.000000 },
- {2325,2326, 35, 0, 220, 220,0.000000 },
- {2327,2328, 35, 0, 180, 180,0.000000 },
- {2329,2330, 35, 0, 160, 160,0.000000 },
- {2331,2332, 35, 0, 573, 573,0.000000 },
- {3035,3036, 35, 0, 1026, 1026,0.000000 },
- {3037,3038, 35, 0, 400, 400,0.000000 },
- {1564,1564, 35, 0, 60, 60,0.000000 },
- {3039,3039, 0, 0, 2293, 2293,0.000000 },
- {3040,3040, 0, 0, 2006, 2006,0.000000 },
- {3041,3041, 0, 0, 1226, 1226,0.000000 },
- {3042,3042, 0, 0, 1026, 1026,0.000000 },
- {3043,3043, 0, 0, 760, 760,0.000000 },
- {3044,3044, 0, 0, 546, 546,0.000000 },
- {3045,3045, 0, 0, 613, 613,0.000000 },
- {3046,3046, 0, 0, 40000, 53,0.000000 },
- {3047,3047, 0, 0, 1013, 1013,0.000000 },
- {3048,3048, 0, 0, 40000, 606,0.000000 },
- {3049,3049, 0, 0, 3626, 3626,0.000000 },
- {3050,3050, 0, 0, 993, 993,0.000000 },
- {3051,3051, 0, 0, 266, 266,0.000000 },
- {3052,3052, 0, 0, 140, 140,0.000000 },
- {3053,3053, 0, 0, 2253, 2253,0.000000 },
- {3054,3054, 0, 0, 2513, 2513,0.000000 },
- {3055,3055, 0, 0, 40000, 0,0.000000 },
- {3056,3056, 0, 0, 40000, 0,0.000000 },
- {3057,3057, 0, 0, 2146, 2146,0.000000 },
- {3058,3058, 0, 0, 40000, 0,0.000000 },
- {3059,3059, 0, 0, 40000, 6,0.000000 },
- {3060,3060, 0, 0, 40000, 6,0.000000 },
- {3061,3061, 0, 0, 460, 460,0.000000 },
- {3062,3062, 0, 0, 1846, 1846,0.000000 },
- {3063,3063, 0, 0, 933, 933,0.000000 },
- {3064,3064, 0, 0, 206, 206,0.000000 },
- {3065,3065, 0, 0, 40000, 20,0.000000 },
- {3066,3066, 0, 0, 80, 80,0.000000 },
- {3067,3067, 0, 0, 1973, 1973,0.000000 },
- {3068,3068, 0, 0, 40000, 60,0.000000 },
- {3069,3069, 0, 0, 1120, 1120,0.000000 },
- {3070,3070, 0, 0, 420, 420,0.000000 },
- {3071,3071, 0, 0, 1120, 1120,0.000000 },
- {3072,3072, 0, 0, 806, 806,0.000000 },
- {3073,3073, 0, 0, 1186, 1186,0.000000 },
- {3074,3074, 0, 0, 1900, 1900,0.000000 },
- {3075,3075, 0, 0, 40000, 0,0.000000 },
- {3076,3076, 0, 0, 1046, 1046,0.000000 },
- {3077,3077, 0, 0, 600, 600,0.000000 },
- {3078,3078, 0, 0, 146, 13,0.000000 },
- {3079,3079, 0, 0, 786, 786,0.000000 },
- {3080,3080, 0, 0, 40000, 26,0.000000 },
- {3081,3081, 0, 0, 146, 13,0.000000 },
- {3082,3082, 0, 0, 40000, 46,0.000000 },
- {3083,3083, 0, 0, 100, 100,0.000000 },
- {3084,3084, 0, 0, 1580, 1580,0.000000 },
- {3085,3085, 0, 0, 280, 280,0.000000 },
- {3086,3086, 0, 0, 40000, 80,0.000000 },
- {3087,3087, 0, 0, 40000, 73,0.000000 },
- {3088,3088, 0, 0, 40000, 66,0.000000 },
- {3089,3089, 0, 0, 40000, 73,0.000000 },
- {3090,3090, 0, 0, 40000, 0,0.000000 },
- {3091,3091, 0, 0, 40000, 6,0.000000 },
- {3092,3092, 0, 0, 40000, 6,0.000000 },
- {3093,3093, 0, 0, 246, 246,0.000000 },
- {3094,3094, 0, 0, 40000, 73,0.000000 },
- {3095,3095, 0, 0, 273, 126,0.000000 },
- {3096,3096, 0, 0, 40000, 33,0.000000 },
- {3097,3097, 0, 0, 40000, 6,0.000000 },
- {3098,3098, 0, 0, 40000, 73,0.000000 },
- {3099,3099, 0, 0, 1233, 53,0.000000 },
- {3100,3100, 0, 0, 40000, 66,0.000000 },
- {3101,3101, 0, 0, 40000, 0,0.000000 },
- {3102,3102, 0, 0, 40000, 0,0.000000 },
- {3103,3103, 0, 0, 40000, 6,0.000000 },
- {3104,3104, 0, 0, 40000, 0,0.000000 },
- {3105,3105, 0, 0, 40000, 6,0.000000 },
- {3106,3106, 0, 0, 40000, 0,0.000000 },
- {3107,3107, 0, 0, 40000, 0,0.000000 },
- {3108,3108, 0, 0, 40000, 6,0.000000 },
- {3109,3109, 0, 0, 40000, 6,0.000000 },
- {3110,3110, 0, 0, 40000, 6,0.000000 },
- {3111,3111, 0, 0, 40000, 20,0.000000 },
- {3112,3112, 0, 0, 2240, 2240,0.000000 },
- {3113,3113, 0, 0, 100, 6,0.000000 },
- {3114,3114, 0, 0, 4466, 4466,0.000000 },
- {3115,3115, 0, 0, 40000, 20,0.000000 },
- {3116,3116, 0, 0, 40000, 13,0.000000 },
- {3117,3117, 0, 0, 40000, 53,0.000000 },
- {3118,3118, 0, 0, 40000, 300,0.000000 },
- {3119,3119, 0, 0, 6906, 6906,0.000000 },
- {3120,3120, 0, 0, 40000, 33,0.000000 },
- {3121,3121, 0, 0, 40000, 6,0.000000 },
- {3122,3122, 0, 0, 1953, 1953,0.000000 },
- {3123,3123, 0, 0, 973, 973,0.000000 },
- {3124,3124, 0, 0, 2240, 6,0.000000 },
- {3125,3125, 0, 0, 1986, 1986,0.000000 },
- {3126,3126, 0, 0, 1613, 1613,0.000000 },
- {3127,3127, 0, 0, 353, 353,0.000000 },
- {3128,3128, 0, 0, 66, 66,0.000000 },
- {3129,3129, 0, 0, 5586, 5586,0.000000 },
- {3130,3130, 0, 0, 173, 173,0.000000 },
- {3131,3131, 35, 0, 120, 120,0.000000 },
- {3132,3132, 35, 0, 6, 6,0.000000 },
- {3133,3133, 35, 0, 40000, 46,0.000000 },
- {3134,3134, 35, 0, 40000, 46,0.000000 },
- {3135,3135, 35, 0, 100, 100,0.000000 },
- {3061,3061, 35, 0, 140, 140,0.000000 },
- {3136,3136, 35, 0, 20, 20,0.000000 },
- { 739, 739, 35, 0, 40, 40,0.000000 },
- {3137,3137, 35, 0, 186, 186,0.000000 },
- {3138,3138, 35, 0, 160, 160,0.000000 },
- {3139,3139, 35, 0, 93, 93,0.000000 },
- {3140,3140, 35, 0, 80, 80,0.000000 },
- {3141,3141, 35, 0, 133, 133,0.000000 },
- {3142,3142, 35, 0, 66, 66,0.000000 },
- {3143,3143, 35, 0, 133, 133,0.000000 },
- {3144,3144, 35, 0, 666, 666,0.000000 },
- {3145,3145, 35, 0, 93, 93,0.000000 },
- {3146,3146, 35, 0, 1433, 1433,0.000000 },
- {3147,3147, 35, 0, 393, 393,0.000000 },
- {3148,3148, 35, 0, 93, 93,0.000000 },
- {3149,3149, 35, 0, 1480, 1480,0.000000 },
- {3150,3150, 0, 0, 1126, 1126,0.000000 },
- {3151,3151, 0, 0, 1766, 1766,0.000000 },
- {3152,3152, 0, 0, 620, 620,0.000000 },
- {3153,3153, 0, 0, 460, 460,0.000000 },
- {3154,3154, 0, 0, 1173, 1173,0.000000 },
- {3155,3155, 0, 0, 626, 626,0.000000 },
- {3156,3156, 0, 0, 1740, 1740,0.000000 },
- {3157,3157, 0, 0, 280, 280,0.000000 },
- {3158,3158, 0, 0, 46, 46,0.000000 },
- {3159,3159, 0, 0, 280, 280,0.000000 },
- {3160,3160, 0, 0, 1153, 1153,0.000000 },
- {3161,3161, 0, 0, 40000, 0,0.000000 },
- {3162,3162, 0, 0, 40000, 6,0.000000 },
- {3163,3163, 0, 0, 40000, 46,0.000000 },
- {3164,3164, 0, 0, 40000, 0,0.000000 },
- {3165,3165, 0, 0, 40000, 6,0.000000 },
- {3166,3166, 0, 0, 2280, 2280,0.000000 },
- {3167,3167, 0, 0, 40000, 0,0.000000 },
- {3168,3168, 0, 0, 486, 486,0.000000 },
- {3169,3169, 0, 0, 600, 600,0.000000 },
- {3170,3170, 0, 0, 466, 466,0.000000 },
- {3171,3171, 0, 0, 593, 593,0.000000 },
- {3172,3172, 0, 0, 1153, 1153,0.000000 },
- {3173,3173, 0, 0, 280, 280,0.000000 },
- {3174,3174, 0, 0, 586, 586,0.000000 },
- {3175,3175, 0, 0, 206, 13,0.000000 },
- {3176,3176, 0, 0, 186, 60,0.000000 },
- {3177,3177, 0, 0, 2366, 2366,0.000000 },
- {3178,3178, 0, 0, 1700, 1700,0.000000 },
- {3179,3179, 0, 0, 46, 46,0.000000 },
- {3180,3180, 0, 0, 886, 886,0.000000 },
- {3181,3181, 0, 0, 186, 186,0.000000 },
- {3182,3182, 0, 0, 40000, 186,0.000000 },
- {3183,3183, 0, 0, 560, 560,0.000000 },
- {3184,3184, 0, 0, 1466, 1466,0.000000 },
- {3185,3185, 0, 0, 1553, 1553,0.000000 },
- {3186,3186, 0, 0, 380, 380,0.000000 },
- {3187,3187, 0, 0, 146, 146,0.000000 },
- {3188,3188, 0, 0, 146, 146,0.000000 },
- {3189,3189, 0, 0, 4726, 4726,0.000000 },
- {3190,3190, 0, 0, 40000, 6,0.000000 },
- {3191,3191, 0, 0, 1766, 1766,0.000000 },
- {3192,3192, 0, 0, 40000, 0,0.000000 },
- {3193,3193, 0, 0, 806, 806,0.000000 },
- {3194,3194, 0, 0, 1133, 1133,0.000000 },
- {3195,3195, 0, 0, 40000, 6,0.000000 },
- {3196,3196, 0, 0, 40000, 0,0.000000 },
- {3197,3197, 0, 0, 40000, 6,0.000000 },
- {3198,3198, 0, 0, 40000, 20,0.000000 },
- {3199,3199, 0, 0, 40000, 6,0.000000 },
- {3200,3200, 0, 0, 213, 213,0.000000 },
- {3201,3201, 0, 0, 40000, 106,0.000000 },
- {3202,3202, 0, 0, 1113, 1113,0.000000 },
- {3203,3203, 0, 0, 1953, 1953,0.000000 },
- {3204,3204, 0, 0, 40000, 0,0.000000 },
- {3205,3205, 0, 0, 40000, 0,0.000000 },
- {3206,3206, 0, 0, 340, 340,0.000000 },
- {3207,3207, 0, 0, 40000, 6,0.000000 },
- {3208,3208, 0, 0, 1126, 1126,0.000000 },
- {3209,3209, 0, 0, 300, 300,0.000000 },
- {3210,3210, 0, 0, 40000, 46,0.000000 },
- {3211,3211, 0, 0, 40000, 113,0.000000 },
- {3212,3212, 0, 0, 1126, 1126,0.000000 },
- {3213,3213, 0, 0, 2853, 2853,0.000000 },
- {3214,3214, 0, 0, 40000, 0,0.000000 },
- {3215,3215, 0, 0, 1286, 0,0.000000 },
- {3216,3216, 0, 0, 40000, 233,0.000000 },
- {3217,3217, 0, 0, 40000, 1640,0.000000 },
- {3218,3218, 0, 0, 40000, 240,0.000000 },
- {3219,3219, 0, 0, 1766, 1766,0.000000 },
- {3220,3220, 0, 0, 40000, 1493,0.000000 },
- {3221,3221, 0, 0, 40000, 2120,0.000000 },
- {3222,3222, 0, 0, 1226, 1226,0.000000 },
- {3223,3223, 0, 0, 306, 306,0.000000 },
- {3224,3224, 0, 0, 40000, 6,0.000000 },
- {3225,3225, 0, 0, 666, 13,0.000000 },
- {3226,3226, 0, 0, 153, 153,0.000000 },
- {3227,3227, 0, 0, 626, 626,0.000000 },
- {3228,3228, 0, 0, 140, 140,0.000000 },
- {3229,3229, 0, 0, 233, 233,0.000000 },
- { 499, 499, 0, 0, 40, 40,0.000000 },
- {3230,3230, 0, 0, 46, 46,0.000000 },
- {3231,3231, 0, 0, 146, 146,0.000000 },
- {3232,3232, 0, 0, 206, 206,0.000000 },
- {3233,3233, 0, 0, 5686, 5686,0.000000 },
- {3234,3234, 0, 0, 326, 326,0.000000 },
- { 403, 403, 0, 0, 40000, 0,0.000000 },
- {3235,3235, 0, 0, 1913, 1913,0.000000 },
- {3236,3236, 0, 0, 2080, 2080,0.000000 },
- {3237,3237, 0, 0, 2026, 2026,0.000000 },
- {3238,3238, 0, 0, 1166, 1166,0.000000 },
- {3239,3239, 0, 0, 600, 600,0.000000 },
- {3240,3240, 0, 0, 1213, 1213,0.000000 },
- {3241,3241, 0, 0, 40000, 0,0.000000 },
- {3242,3242, 0, 0, 40000, 0,0.000000 },
- {3243,3243, 0, 0, 40000, 0,0.000000 },
- {3244,3244, 0, 0, 40000, 0,0.000000 },
- {3245,3245, 0, 0, 40000, 146,0.000000 },
- {3246,3246, 0, 0, 40000, 146,0.000000 },
- {3247,3247, 0, 0, 40000, 146,0.000000 },
- {3248,3248, 0, 0, 40000, 153,0.000000 },
- {3249,3249, 0, 0, 873, 873,0.000000 },
- {3250,3250, 0, 0, 553, 553,0.000000 },
- {3251,3251, 0, 0, 873, 873,0.000000 },
- {3252,3252, 0, 0, 606, 606,0.000000 },
- {3253,3253, 0, 0, 606, 606,0.000000 },
- {3254,3254, 0, 0, 600, 600,0.000000 },
- {3255,3255, 0, 0, 1013, 1013,0.000000 },
- {3256,3256, 0, 0, 626, 626,0.000000 },
- {3257,3257, 0, 0, 40000, 0,0.000000 },
- {3258,3258, 0, 0, 40000, 0,0.000000 },
- {3259,3259, 0, 0, 40000, 66,0.000000 },
- {3260,3260, 0, 0, 40000, 66,0.000000 },
- {3261,3261, 0, 0, 40000, 20,0.000000 },
- {3262,3262, 0, 0, 1120, 1120,0.000000 },
- {3263,3263, 0, 0, 1206, 1206,0.000000 },
- {3264,3264, 0, 0, 940, 940,0.000000 },
- {3265,3265, 0, 0, 3626, 3626,0.000000 },
- {3266,3266, 0, 0, 40000, 320,0.000000 },
- {3267,3267, 0, 0, 40000, 6,0.000000 },
- {3268,3268, 0, 0, 3926, 3926,0.000000 },
- {3269,3269, 0, 0, 40000, 446,0.000000 },
- {3270,3270, 0, 0, 40000, 180,0.000000 },
- {3271,3271, 0, 0, 3426, 3426,0.000000 },
- {3272,3272, 0, 0, 2253, 2253,0.000000 },
- {3273,3273, 0, 0, 40000, 2133,0.000000 },
- {3274,3274, 0, 0, 2566, 2566,0.000000 },
- {3275,3275, 0, 0, 166, 26,0.000000 },
- {3276,3276, 0, 0, 40000, 346,0.000000 },
- {3277,3277, 0, 0, 40000, 66,0.000000 },
- {3278,3278, 0, 0, 40000, 213,0.000000 },
- {3279,3279, 0, 0, 2273, 2273,0.000000 },
- {3280,3280, 0, 0, 40000, 40,0.000000 },
- {3281,3281, 0, 0, 40000, 906,0.000000 },
- {3282,3282, 0, 0, 40000, 213,0.000000 },
- {3283,3283, 0, 0, 40000, 186,0.000000 },
- {3284,3284, 0, 0, 60, 60,0.000000 },
- {3285,3285, 0, 0, 146, 146,0.000000 },
- {3286,3286, 0, 0, 146, 13,0.000000 },
- {3287,3287, 0, 0, 786, 786,0.000000 },
- {3288,3288, 0, 0, 40000, 26,0.000000 },
- {3289,3289, 0, 0, 1580, 1580,0.000000 },
- {3290,3290, 0, 0, 653, 653,0.000000 },
- {3291,3291, 0, 0, 2400, 2400,0.000000 },
- {3292,3292, 0, 0, 1926, 1926,0.000000 },
- {3293,3293, 0, 0, 2593, 2593,0.000000 },
- {3294,3294, 0, 0, 2360, 2360,0.000000 },
- {3295,3295, 0, 0, 4933, 4933,0.000000 },
- {3296,3296, 0, 0, 593, 593,0.000000 },
- {3297,3297, 0, 0, 253, 253,0.000000 },
- {3298,3298, 0, 0, 306, 306,0.000000 },
- {3299,3299, 0, 0, 613, 613,0.000000 },
- {3300,3300, 0, 0, 1900, 1900,0.000000 },
- {3301,3301, 0, 0, 1213, 1213,0.000000 },
- {3302,3302, 0, 0, 273, 273,0.000000 },
- {3303,3303, 0, 0, 566, 566,0.000000 },
- {3304,3304, 0, 0, 40000, 6,0.000000 },
- {3305,3305, 0, 0, 40000, 6,0.000000 },
- {3306,3306, 0, 0, 40000, 6,0.000000 },
- {3307,3307, 0, 0, 40000, 6,0.000000 },
- {3308,3308, 0, 0, 40000, 6,0.000000 },
- {3309,3309, 0, 0, 40000, 0,0.000000 },
- {3310,3310, 0, 0, 40000, 0,0.000000 },
- {3311,3311, 0, 0, 40000, 0,0.000000 },
- {3312,3312, 0, 0, 40000, 6,0.000000 },
- {3313,3313, 0, 0, 40000, 53,0.000000 },
- {3314,3314, 0, 0, 40000, 73,0.000000 },
- {3315,3315, 0, 0, 40000, 0,0.000000 },
- {3316,3316, 0, 0, 40000, 0,0.000000 },
- {3317,3317, 0, 0, 40000, 0,0.000000 },
- {3318,3318, 0, 0, 40000, 80,0.000000 },
- {3319,3319, 0, 0, 40, 60,0.000000 },
- {3320,3320, 0, 0, 1320, 1320,0.000000 },
- {3321,3321, 0, 0, 40000, 126,0.000000 },
- {3322,3322, 0, 0, 273, 126,0.000000 },
- {3323,3323, 0, 0, 40000, 126,0.000000 },
- {3324,3324, 0, 0, 40000, 33,0.000000 },
- {3325,3325, 0, 0, 40000, 73,0.000000 },
- {3326,3326, 0, 0, 40, 40,0.000000 },
- {3327,3327, 0, 0, 40000, 233,0.000000 },
- {3328,3328, 0, 0, 40000, 233,0.000000 },
- {3329,3329, 0, 0, 593, 593,0.000000 },
- {3330,3330, 0, 0, 40000, 213,0.000000 },
- {3331,3331, 0, 0, 40000, 606,0.000000 },
- {3332,3332, 0, 0, 2253, 2253,0.000000 },
- {3333,3333, 0, 0, 140, 140,0.000000 },
- {3334,3334, 0, 0, 40000, 926,0.000000 },
- {3335,3335, 0, 0, 40000, 33,0.000000 },
- {3336,3336, 0, 0, 40000, 1120,0.000000 },
- {3337,3337, 0, 0, 160, 160,0.000000 },
- {3338,3338, 0, 0, 40000, 6,0.000000 },
- {3339,3339, 0, 0, 40000, 1093,0.000000 },
- {3340,3340, 0, 0, 160, 160,0.000000 },
- {3341,3341, 0, 0, 1206, 1206,0.000000 },
- {3342,3342, 0, 0, 146, 146,0.000000 },
- {3343,3343, 0, 0, 146, 146,0.000000 },
- {3344,3344, 0, 0, 140, 140,0.000000 },
- {3345,3345, 0, 0, 140, 140,0.000000 },
- {3346,3346, 0, 0, 140, 140,0.000000 },
- {3347,3347, 0, 0, 80, 80,0.000000 },
- {3348,3348, 0, 0, 40000, 33,0.000000 },
- {3349,3349, 0, 0, 1186, 1186,0.000000 },
- {3350,3350, 0, 0, 40000, 1413,0.000000 },
- {3351,3351, 0, 0, 1226, 1226,0.000000 },
- {3352,3352, 0, 0, 40, 40,0.000000 },
- {3353,3353, 0, 0, 60, 60,0.000000 },
- {3354,3354, 0, 0, 100, 100,0.000000 },
- {3355,3355, 0, 0, 246, 246,0.000000 },
- {3356,3356, 0, 0, 1140, 1140,0.000000 },
- { 142, 142, 20, 0, 20, 20,0.000000 },
- {3357,1451, 0, 0, 613, 613,0.000000 },
- {3358,3359, 0, 0, 1740, 1740,0.000000 },
- {3360,1455, 0, 0, 280, 280,0.000000 },
- {3361,1463, 0, 0, 40000, 133,0.000000 },
- { 225,3362, 0, 0, 2026, 2026,0.000000 },
- {3363,1545, 0, 0, 153, 153,0.000000 },
- {3364,1547, 0, 0, 40000, 60,0.000000 },
- {3365,3366, 39, 0, 13, 13,0.000000 },
- {3367, 368, 58, 0, 46, 46,0.000000 },
- {3368,1551, 48, 0, 93, 93,0.000000 },
- {3368,3033, 49, 0, 73, 73,0.000000 },
- {3368,3033, 51, 0, 153, 153,0.000000 },
- {3368,3033, 54, 0, 140, 140,0.000000 },
- {3368,3033, 57, 0, 126, 126,0.000000 },
- {3368,3033, 60, 0, 133, 133,0.000000 },
- {3369,3370, 70, 0, 893, 893,0.000000 },
- {1564,1565, 80, 0, 66, 66,0.000000 },
- {3371,1571, 44, 0, 520, 520,0.000000 },
- {3372,3372, 0, 0, 1486, 1486,0.000000 },
- {3373,3373, 0, 0, 1806, 1806,0.000000 },
- {3374,3374, 0, 0, 633, 633,0.000000 },
- {3375,3375, 0, 0, 1273, 1273,0.000000 },
- {3376,3376, 0, 0, 1553, 1553,0.000000 },
- {3377,3377, 0, 0, 1206, 1206,0.000000 },
- {3378,3378, 0, 0, 313, 313,0.000000 },
- {3379,3379, 0, 0, 1486, 1486,0.000000 },
- {3380,3380, 0, 0, 626, 626,0.000000 },
- {3381,3381, 0, 0, 1846, 1846,0.000000 },
- {3382,3382, 0, 0, 300, 300,0.000000 },
- {3383,3383, 0, 0, 1740, 1740,0.000000 },
- {3384,3384, 0, 0, 513, 513,0.000000 },
- {3385,3385, 0, 0, 46, 46,0.000000 },
- {3386,3386, 0, 0, 1226, 1226,0.000000 },
- {3387,3387, 0, 0, 333, 333,0.000000 },
- {3388,3388, 0, 0, 40000, 300,0.000000 },
- {3389,3389, 0, 0, 40000, 533,0.000000 },
- {3390,3390, 0, 0, 40000, 126,0.000000 },
- {3391,3391, 0, 0, 40000, 0,0.000000 },
- {3392,3392, 0, 0, 40000, 33,0.000000 },
- {3393,3393, 0, 0, 40000, 6,0.000000 },
- {3394,3394, 0, 0, 40000, 6,0.000000 },
- {3395,3395, 0, 0, 3880, 6,0.000000 },
- {3396,3396, 0, 0, 1066, 1066,0.000000 },
- {3397,3397, 0, 0, 4086, 4086,0.000000 },
- {3398,3398, 0, 0, 866, 866,0.000000 },
- {3399,3399, 0, 0, 466, 466,0.000000 },
- {3400,3400, 0, 0, 420, 420,0.000000 },
- {3401,3401, 0, 0, 40000, 73,0.000000 },
- {3402,3402, 0, 0, 40000, 20,0.000000 },
- {3403,3403, 0, 0, 40000, 26,0.000000 },
- {3404,3404, 0, 0, 4266, 4266,0.000000 },
- {3405,3405, 0, 0, 40000, 0,0.000000 },
- {3406,3406, 0, 0, 253, 253,0.000000 },
- {3407,3407, 0, 0, 380, 380,0.000000 },
- {3408,3408, 0, 0, 573, 573,0.000000 },
- {3409,3409, 0, 0, 280, 280,0.000000 },
- {3410,3410, 0, 0, 40000, 6,0.000000 },
- {3411,3411, 0, 0, 1933, 1933,0.000000 },
- {3412,3412, 0, 0, 40000, 140,0.000000 },
- {3413,3413, 0, 0, 40000, 140,0.000000 },
- {3414,3414, 0, 0, 40000, 40,0.000000 },
- {3415,3415, 0, 0, 353, 353,0.000000 },
- {3416,3416, 0, 0, 40000, 166,0.000000 },
- {3417,3417, 0, 0, 273, 273,0.000000 },
- {3418,3418, 0, 0, 126, 126,0.000000 },
- {3419,3419, 0, 0, 146, 146,0.000000 },
- {3420,3420, 0, 0, 40000, 213,0.000000 },
- {3421,3421, 0, 0, 40000, 173,0.000000 },
- {3422,3422, 0, 0, 40000, 206,0.000000 },
- {3423,3423, 0, 0, 40000, 213,0.000000 },
- {3424,3424, 0, 0, 40000, 153,0.000000 },
- {3425,3425, 0, 0, 40000, 106,0.000000 },
- {3426,3426, 0, 0, 40000, 6,0.000000 },
- {3427,3427, 0, 0, 233, 233,0.000000 },
- {3428,3428, 0, 0, 40000, 6,0.000000 },
- {3429,3429, 0, 0, 11193, 13,0.000000 },
- {3430,3430, 0, 0, 40000, 126,0.000000 },
- {3431,3431, 0, 0, 40000, 13,0.000000 },
- {3432,3432, 0, 0, 40000, 6,0.000000 },
- {3433,3433, 0, 0, 40000, 0,0.000000 },
- {3434,3434, 0, 0, 40000, 0,0.000000 },
- {3435,3435, 0, 0, 40000, 0,0.000000 },
- {3436,3436, 0, 0, 40000, 0,0.000000 },
- {3437,3437, 0, 0, 40000, 0,0.000000 },
- {3438,3438, 0, 0, 40000, 0,0.000000 },
- {3439,3439, 0, 0, 6013, 6013,0.000000 },
- {3440,3440, 0, 0, 40000, 0,0.000000 },
- {3441,3441, 0, 0, 40000, 0,0.000000 },
- {3442,3442, 0, 0, 293, 293,0.000000 },
- {3443,3443, 0, 0, 40000, 6,0.000000 },
- {3444,3444, 0, 0, 40000, 20,0.000000 },
- {3445,3445, 0, 0, 40000, 0,0.000000 },
- {3446,3446, 0, 0, 40000, 0,0.000000 },
- {3447,3447, 0, 0, 40000, 0,0.000000 },
- {3448,3448, 0, 0, 40000, 0,0.000000 },
- {3449,3449, 0, 0, 40000, 20,0.000000 },
- {3450,3450, 0, 0, 40000, 153,0.000000 },
- {3451,3451, 0, 0, 440, 440,0.000000 },
- {3452,3452, 0, 0, 3253, 3253,0.000000 },
- {3453,3453, 0, 0, 3946, 3946,0.000000 },
- {3454,3454, 0, 0, 140, 140,0.000000 },
- {3455,3455, 0, 0, 40000, 20,0.000000 },
- {3456,3456, 0, 0, 40000, 33,0.000000 },
- {3457,3457, 0, 0, 40000, 20,0.000000 },
- {3458,3458, 0, 0, 40000, 26,0.000000 },
- {3459,3459, 0, 0, 40000, 20,0.000000 },
- {3460,3460, 0, 0, 786, 786,0.000000 },
- {3461,3461, 0, 0, 2560, 2560,0.000000 },
- {3462,3462, 0, 0, 40000, 26,0.000000 },
- {3463,3463, 0, 0, 40000, 580,0.000000 },
- {3464,3464, 0, 0, 40000, 2393,0.000000 },
- {3465,3465, 0, 0, 40000, 53,0.000000 },
- {3466,3466, 0, 0, 40000, 33,0.000000 },
- {3467,3467, 0, 0, 40000, 193,0.000000 },
- {3468,3468, 0, 0, 40000, 280,0.000000 },
- {3469,3469, 0, 0, 40000, 86,0.000000 },
- {3470,3470, 0, 0, 40000, 820,0.000000 },
- {3471,3471, 0, 0, 40000, 286,0.000000 },
- {3472,3472, 0, 0, 40000, 1100,0.000000 },
- {3473,3473, 0, 0, 40000, 1073,0.000000 },
- {3474,3474, 0, 0, 40000, 1173,0.000000 },
- {3475,3475, 0, 0, 340, 340,0.000000 },
- {3476,3476, 0, 0, 4846, 4846,0.000000 },
- {3477,3477, 0, 0, 40000, 0,0.000000 },
- {3478,3478, 0, 0, 4846, 4846,0.000000 },
- {3479,3479, 0, 0, 606, 606,0.000000 },
- {3480,3480, 0, 0, 106, 106,0.000000 },
- {3481,3481, 0, 0, 40000, 0,0.000000 },
- {3482,3482, 0, 0, 40000, 73,0.000000 },
- {3483,3483, 0, 0, 40000, 0,0.000000 },
- {3484,3484, 0, 0, 586, 586,0.000000 },
- {3485,3485, 0, 0, 73, 73,0.000000 },
- {3486,3486, 0, 0, 460, 460,0.000000 },
- {3487,3487, 0, 0, 40, 40,0.000000 },
- {3488,3488, 0, 0, 526, 526,0.000000 },
- {3489,3489, 0, 0, 540, 540,0.000000 },
- {3490,3490, 0, 0, 253, 253,0.000000 },
- {3491,3491, 0, 0, 2280, 2280,0.000000 },
- {3492,3492, 0, 0, 73, 73,0.000000 },
- {3493,3493, 0, 0, 40000, 73,0.000000 },
- {3494,3494, 0, 0, 40000, 2220,0.000000 },
- {3495,3495, 0, 0, 146, 146,0.000000 },
- {3496,3496, 0, 0, 40000, 13,0.000000 },
- {3497,3497, 0, 0, 380, 13,0.000000 },
- {3498,3498, 0, 0, 40000, 2220,0.000000 },
- {3499,3499, 0, 0, 40000, 146,0.000000 },
- {3500,3500, 0, 0, 1513, 13,0.000000 },
- { 739, 739, 46, 0, 53, 53,0.000000 },
- {3501,3501, 47, 0, 106, 106,0.000000 },
- {3502,3502, 64, 0, 26, 26,0.000000 },
- {3503,3503, 40, 0, 106, 106,0.000000 },
- {3504,3504, 48, 0, 13, 13,0.000000 },
- {3505,3505, 48, 0, 80, 80,0.000000 },
- {3506,3506, 46, 0, 86, 86,0.000000 },
- {3507,3507,111, 0, 33, 33,0.000000 },
- {3508,3508, 49, 0, 140, 140,0.000000 },
- {3509,3509, 56, 0, 33, 33,0.000000 },
- {3510,3510, 52, 0, 140, 140,0.000000 },
- {3511,3511, 96, 0, 440, 440,0.000000 },
- {3510,3510, 54, 0, 140, 140,0.000000 },
- {3512,3512, 57, 0, 260, 260,0.000000 },
- {3513,3513, 82, 0, 486, 486,0.000000 },
- {3510,3510, 60, 0, 153, 153,0.000000 },
- {3514,3514, 60, 0, 606, 606,0.000000 },
- {3515,3515, 92, 0, 60, 60,0.000000 },
- {3516,3516, 60, 0, 46, 46,0.000000 },
- {3517,3517, 58, 0, 40, 40,0.000000 },
- {3518,3518, 22, 0, 53, 53,0.000000 },
- {3519,3519, 60, 0, 613, 613,0.000000 },
- {3520,3520, 72, 0, 80, 80,0.000000 },
- {3521,3521, 77, 0, 80, 80,0.000000 },
- {3522,3522, 70, 0, 73, 73,0.000000 },
- {3523,3523, 75, 0, 60, 60,0.000000 },
- {3524,3524, 69, 0, 140, 140,0.000000 },
- {3525,3525, 59, 0, 113, 113,0.000000 },
- {3526,3526, 48, 0, 153, 153,0.000000 },
- {3527,3527, 89, 0, 133, 133,0.000000 },
- {3528,3528, 84, 0, 260, 260,0.000000 },
- {3529,3529, 33, 0, 93, 93,0.000000 },
- {3530,3530, 55, 0, 86, 86,0.000000 },
- {3531,3531, 58, 0, 186, 186,0.000000 },
- {3532,3532, 52, 0, 166, 166,0.000000 },
- {3533,3533, 57, 0, 46, 46,0.000000 },
- {3534,3534, 57, 0, 73, 73,0.000000 },
- {3535,3535, 85, 0, 60, 60,0.000000 },
- {3536,3536, 68, 0, 40, 40,0.000000 },
- {3536,3536, 61, 0, 60, 60,0.000000 },
- {3537,3537, 64, 0, 93, 93,0.000000 },
- {3538,3538, 44, 0, 386, 386,0.000000 },
- {3539,3539,100, 0, 80, 80,0.000000 },
- {3540,3540,100, 0, 306, 306,0.000000 },
- {3541,3541, 0, 0, 1400, 1400,0.000000 },
- {3542,3542, 0, 0, 253, 253,0.000000 },
- {3543,3543, 0, 0, 460, 460,0.000000 },
- {3544,3544, 0, 0, 1226, 1226,0.000000 },
- {3545,3545, 0, 0, 886, 886,0.000000 },
- {3546,3546, 0, 0, 40, 40,0.000000 },
- {3547,3547, 0, 0, 2406, 2406,0.000000 },
- {3548,3548, 0, 0, 1180, 1180,0.000000 },
- {3549,3549, 0, 0, 40000, 0,0.000000 },
- {3550,3550, 0, 0, 40000, 0,0.000000 },
- {3551,3551, 0, 0, 40000, 33,0.000000 },
- {3552,3552, 0, 0, 40000, 0,0.000000 },
- {3553,3553, 0, 0, 40000, 6,0.000000 },
- {3554,3554, 0, 0, 1553, 1553,0.000000 },
- {3555,3555, 0, 0, 40000, 0,0.000000 },
- {3556,3556, 0, 0, 573, 573,0.000000 },
- {3557,3557, 0, 0, 526, 526,0.000000 },
- {3558,3558, 0, 0, 940, 940,0.000000 },
- {3559,3559, 0, 0, 606, 606,0.000000 },
- {3560,3560, 0, 0, 40000, 6,0.000000 },
- {3561,3561, 0, 0, 40000, 0,0.000000 },
- {3562,3562, 0, 0, 1120, 1120,0.000000 },
- {3563,3563, 0, 0, 700, 700,0.000000 },
- {3564,3564, 0, 0, 66, 66,0.000000 },
- {3565,3565, 0, 0, 620, 620,0.000000 },
- {3566,3566, 0, 0, 286, 286,0.000000 },
- {3567,3567, 0, 0, 40000, 73,0.000000 },
- {3568,3568, 0, 0, 80, 80,0.000000 },
- {3569,3569, 0, 0, 186, 186,0.000000 },
- {3570,3570, 0, 0, 1506, 1506,0.000000 },
- {3571,3571, 0, 0, 40000, 0,0.000000 },
- {3572,3572, 0, 0, 40000, 186,0.000000 },
- {3573,3573, 0, 0, 126, 126,0.000000 },
- {3574,3574, 0, 0, 40000, 106,0.000000 },
- {3575,3575, 0, 0, 166, 166,0.000000 },
- {3576,3576, 0, 0, 80, 80,0.000000 },
- {3577,3577, 0, 0, 453, 13,0.000000 },
- {3578,3578, 0, 0, 40000, 0,0.000000 },
- {3579,3579, 0, 0, 40000, 6,0.000000 },
- {3580,3580, 0, 0, 2020, 2020,0.000000 },
- {3581,3581, 0, 0, 1646, 1646,0.000000 },
- {3582,3582, 0, 0, 166, 166,0.000000 },
- {3583,3583, 0, 0, 40000, 0,0.000000 },
- {3584,3584, 0, 0, 146, 146,0.000000 },
- {3585,3585, 0, 0, 340, 340,0.000000 },
- {3586,3586, 0, 0, 40000, 0,0.000000 },
- {3587,3587, 0, 0, 100, 13,0.000000 },
- {3588,3588, 0, 0, 5013, 5013,0.000000 },
- {3589,3589, 0, 0, 40000, 6,0.000000 },
- {3590,3590, 0, 0, 1766, 1766,0.000000 },
- {3591,3591, 0, 0, 4186, 4186,0.000000 },
- {3592,3592, 0, 0, 700, 700,0.000000 },
- {3593,3593, 0, 0, 940, 940,0.000000 },
- {3594,3594, 0, 0, 246, 246,0.000000 },
- {3595,3595, 0, 0, 40000, 6,0.000000 },
- {3596,3596, 0, 0, 40000, 6,0.000000 },
- {3597,3597, 0, 0, 40000, 6,0.000000 },
- {3598,3598, 0, 0, 40000, 0,0.000000 },
- {3599,3599, 0, 0, 40000, 306,0.000000 },
- {3600,3600, 0, 0, 40000, 53,0.000000 },
- {3601,3601, 0, 0, 40000, 6,0.000000 },
- {3602,3602, 0, 0, 40000, 233,0.000000 },
- {3603,3603, 0, 0, 120, 120,0.000000 },
- {3604,3604, 0, 0, 40000, 6,0.000000 },
- {3605,3605, 0, 0, 40000, 153,0.000000 },
- {3606,3606, 0, 0, 1086, 1086,0.000000 },
- {3607,3607, 0, 0, 1900, 1900,0.000000 },
- {3608,3608, 0, 0, 40000, 0,0.000000 },
- {3609,3609, 0, 0, 40000, 13,0.000000 },
- {3610,3610, 0, 0, 253, 253,0.000000 },
- {3611,3611, 0, 0, 40000, 6,0.000000 },
- {3612,3612, 0, 0, 40000, 126,0.000000 },
- {3613,3613, 0, 0, 3680, 3680,0.000000 },
- {3614,3614, 0, 0, 660, 660,0.000000 },
- {3615,3615, 0, 0, 40000, 206,0.000000 },
- {3616,3616, 0, 0, 40000, 106,0.000000 },
- {3617,3617, 0, 0, 546, 546,0.000000 },
- {3618,3618, 0, 0, 126, 6,0.000000 },
- {3619,3619, 0, 0, 40000, 1306,0.000000 },
- {3620,3620, 0, 0, 1240, 1240,0.000000 },
- {3621,3621, 0, 0, 1400, 1400,0.000000 },
- {3622,3622, 0, 0, 40000, 0,0.000000 },
- {3623,3623, 0, 0, 40000, 0,0.000000 },
- {3624,3624, 0, 0, 40000, 833,0.000000 },
- {3625,3625, 0, 0, 40000, 240,0.000000 },
- {3626,3626, 0, 0, 40000, 1973,0.000000 },
- {3627,3627, 0, 0, 4466, 4466,0.000000 },
- {3628,3628, 0, 0, 13, 13,0.000000 },
- {3629,3629, 0, 0, 40000, 2206,0.000000 },
- {3630,3630, 0, 0, 40000, 1180,0.000000 },
- {3631,3631, 0, 0, 4933, 4933,0.000000 },
- {3632,3632, 0, 0, 200, 200,0.000000 },
- {3633,3633, 0, 0, 1226, 1226,0.000000 },
- {3634,3634, 0, 0, 273, 273,0.000000 },
- {3635,3635, 0, 0, 353, 13,0.000000 },
- {3636,3636, 0, 0, 40000, 6,0.000000 },
- {3637,3637, 0, 0, 60, 60,0.000000 },
- {3638,3638, 0, 0, 160, 160,0.000000 },
- {3639,3639, 0, 0, 313, 313,0.000000 },
- {3640,3640, 0, 0, 46, 46,0.000000 },
- {3641,3641, 0, 0, 313, 313,0.000000 },
- {3642,3642, 0, 0, 40, 40,0.000000 },
- {3643,3643, 0, 0, 86, 86,0.000000 },
- {3644,3644, 0, 0, 46, 46,0.000000 },
- {3645,3645, 0, 0, 146, 146,0.000000 },
- {3646,3646, 0, 0, 146, 146,0.000000 },
- {3647,3647, 0, 0, 220, 220,0.000000 },
- {3648,3648, 0, 0, 86, 86,0.000000 },
- {3649,3649, 0, 0, 40000, 320,0.000000 },
- {3650,3650, 0, 0, 40000, 6,0.000000 },
- {3651,3651, 0, 0, 40000, 0,0.000000 },
- {3652,3652, 0, 0, 300, 300,0.000000 },
- {3653,3653, 0, 0, 2940, 2940,0.000000 },
- {3654,3654, 0, 0, 1233, 1233,0.000000 },
- {3655,3655, 0, 0, 3840, 3840,0.000000 },
- {3656,3656, 0, 0, 2280, 2280,0.000000 },
- {3657,3657, 0, 0, 1793, 1793,0.000000 },
- {3658,3658, 0, 0, 1120, 1120,0.000000 },
- {3659,3659, 0, 0, 1013, 1013,0.000000 },
- {3660,3660, 0, 0, 1233, 1233,0.000000 },
- {3661,3661, 0, 0, 600, 600,0.000000 },
- {3662,3662, 0, 0, 280, 280,0.000000 },
- {3663,3663, 0, 0, 266, 266,0.000000 },
- {3664,3664, 0, 0, 1740, 1740,0.000000 },
- {3665,3665, 0, 0, 246, 246,0.000000 },
- {3666,3666, 0, 0, 140, 140,0.000000 },
- {3667,3667, 0, 0, 1166, 1166,0.000000 },
- {3668,3668, 0, 0, 273, 273,0.000000 },
- {3669,3669, 0, 0, 40000, 0,0.000000 },
- {3670,3670, 0, 0, 40000, 0,0.000000 },
- {3671,3671, 0, 0, 313, 313,0.000000 },
- {3672,3672, 0, 0, 40000, 6,0.000000 },
- {3673,3673, 0, 0, 40000, 133,0.000000 },
- {3674,3674, 0, 0, 40000, 133,0.000000 },
- {3675,3675, 0, 0, 40000, 66,0.000000 },
- {3676,3676, 0, 0, 40000, 133,0.000000 },
- {3677,3677, 0, 0, 940, 940,0.000000 },
- {3678,3678, 0, 0, 760, 760,0.000000 },
- {3679,3679, 0, 0, 1200, 1200,0.000000 },
- {3680,3680, 0, 0, 566, 566,0.000000 },
- {3681,3681, 0, 0, 573, 573,0.000000 },
- {3682,3682, 0, 0, 40000, 0,0.000000 },
- {3683,3683, 0, 0, 1353, 1353,0.000000 },
- {3684,3684, 0, 0, 2226, 2226,0.000000 },
- {3685,3685, 0, 0, 866, 866,0.000000 },
- {3686,3686, 0, 0, 2293, 2293,0.000000 },
- {3687,3687, 0, 0, 2113, 2113,0.000000 },
- {3688,3688, 0, 0, 1280, 1280,0.000000 },
- {3689,3689, 0, 0, 886, 886,0.000000 },
- {3690,3690, 0, 0, 833, 833,0.000000 },
- {3691,3691, 0, 0, 886, 886,0.000000 },
- {3692,3692, 0, 0, 940, 940,0.000000 },
- {3693,3693, 0, 0, 40000, 260,0.000000 },
- {3694,3694, 0, 0, 166, 13,0.000000 },
- {3695,3695, 0, 0, 40000, 26,0.000000 },
- {3696,3696, 0, 0, 146, 146,0.000000 },
- {3697,3697, 0, 0, 40000, 86,0.000000 },
- {3698,3698, 0, 0, 940, 940,0.000000 },
- {3699,3699, 0, 0, 100, 100,0.000000 },
- {3700,3700, 0, 0, 513, 513,0.000000 },
- {3701,3701, 0, 0, 40000, 286,0.000000 },
- {3702,3702, 0, 0, 40000, 133,0.000000 },
- {3703,3703, 0, 0, 40000, 233,0.000000 },
- {3704,3704, 0, 0, 40000, 40,0.000000 },
- {3705,3705, 0, 0, 3413, 3413,0.000000 },
- {3706,3706, 0, 0, 3413, 3413,0.000000 },
- {3707,3707, 0, 0, 253, 253,0.000000 },
- {3708,3708, 0, 0, 60, 73,0.000000 },
- {3709,3709, 0, 0, 40000, 66,0.000000 },
- {3710,3710, 0, 0, 40000, 33,0.000000 },
- {3711,3711, 0, 0, 40000, 0,0.000000 },
- {3712,3712, 0, 0, 40000, 126,0.000000 },
- {3713,3713, 0, 0, 40000, 6,0.000000 },
- {3714,3714, 0, 0, 40000, 0,0.000000 },
- {3715,3715, 0, 0, 40000, 126,0.000000 },
- {3716,3716, 0, 0, 40000, 26,0.000000 },
- {3717,3717, 0, 0, 40000, 20,0.000000 },
- {3718,3718, 0, 0, 40000, 20,0.000000 },
- {3719,3719, 0, 0, 40000, 0,0.000000 },
- {3720,3720, 0, 0, 40000, 0,0.000000 },
- {3721,3721, 0, 0, 40000, 6,0.000000 },
- {3722,3722, 0, 0, 40000, 33,0.000000 },
- {3723,3723, 0, 0, 40000, 6,0.000000 },
- {3724,3724, 0, 0, 40000, 6,0.000000 },
- {3725,3725, 0, 0, 40000, 20,0.000000 },
- {3726,3726, 0, 0, 40000, 33,0.000000 },
- {3727,3727, 0, 0, 100, 100,0.000000 },
- {3728,3728, 0, 0, 40000, 26,0.000000 },
- {3729,3729, 0, 0, 40000, 26,0.000000 },
- {3730,3730, 0, 0, 40000, 53,0.000000 },
- {3731,3731, 0, 0, 40000, 0,0.000000 },
- {3732,3732, 0, 0, 40000, 0,0.000000 },
- {3733,3733, 0, 0, 40000, 26,0.000000 },
- {3734,3734, 0, 0, 40000, 13,0.000000 },
- {3735,3735, 0, 0, 40000, 6,0.000000 },
- {3736,3736, 0, 0, 3766, 3766,0.000000 },
- {3737,3737, 0, 0, 40000, 140,0.000000 },
- {3738,3738, 0, 0, 40000, 13,0.000000 },
- {3739,3739, 0, 0, 40000, 233,0.000000 },
- {3740,3740, 0, 0, 40000, 413,0.000000 },
- {3741,3741, 0, 0, 1873, 26,0.000000 },
- {3742,3742, 0, 0, 40000, 566,0.000000 },
- {3743,3743, 0, 0, 753, 753,0.000000 },
- {3744,3744, 0, 0, 1166, 13,0.000000 },
- {3745,3745, 0, 0, 40000, 566,0.000000 },
- {3746,3746, 0, 0, 40000, 53,0.000000 },
- {3747,3747, 0, 0, 1020, 1020,0.000000 },
- {3748,3748, 0, 0, 40000, 340,0.000000 },
- {3749,3749, 0, 0, 440, 440,0.000000 },
- {3750,3750, 0, 0, 40000, 106,0.000000 },
- {3751,3751, 0, 0, 2286, 2286,0.000000 },
- {3752,3752, 0, 0, 40000, 966,0.000000 },
- {3753,3753, 0, 0, 40000, 766,0.000000 },
- {3754,3754, 0, 0, 40000, 6,0.000000 },
- {3755,3755, 0, 0, 4933, 4933,0.000000 },
- {3756,3756, 0, 0, 1126, 1126,0.000000 },
- {3757,3757, 0, 0, 273, 273,0.000000 },
- {3758,3758, 0, 0, 546, 546,0.000000 },
- {3759,3759, 0, 0, 280, 280,0.000000 },
- {3760,3760, 0, 0, 40000, 6,0.000000 },
- {3761,3761, 0, 0, 40000, 6,0.000000 },
- {3762,3762, 0, 0, 40000, 0,0.000000 },
- {3763,3763, 0, 0, 1106, 1106,0.000000 },
- {3764,3764, 0, 0, 86, 86,0.000000 },
- {3765,3765, 0, 0, 280, 280,0.000000 },
- {3766,3766, 0, 0, 53, 53,0.000000 },
- {3767,3767, 0, 0, 40, 40,0.000000 },
- {3768,3768, 0, 0, 60, 60,0.000000 },
- {3769,3769, 0, 0, 253, 253,0.000000 },
- {3770,3770, 0, 0, 1213, 1213,0.000000 },
- {3771,3771, 0, 0, 293, 293,0.000000 },
- {3772,3772, 0, 0, 153, 153,0.000000 },
- {3773,3773, 0, 0, 4586, 4586,0.000000 },
- {3774,3774, 0, 0, 146, 146,0.000000 },
- {3775,3775, 0, 0, 40000, 0,0.000000 },
- {3776,3776, 0, 0, 146, 146,0.000000 },
- {3777,3777, 0, 0, 40000, 113,0.000000 },
- {3778,3778, 0, 0, 153, 153,0.000000 },
- {3779,3779, 0, 0, 1726, 13,0.000000 },
- { 738, 738, 44, 0, 40, 40,0.000000 },
- {3780,3780, 36, 0, 33, 33,0.000000 },
- {3781,3781, 32, 0, 6, 6,0.000000 },
- {2030,2030, 60, 0, 86, 86,0.000000 },
- {3782,3782, 24, 0, 6, 6,0.000000 },
- {3783,3783, 60, 0, 26, 26,0.000000 },
- {3784,3784, 44, 0, 140, 140,0.000000 },
- { 132, 132, 44, 0, 20, 20,0.000000 },
- {3785,3785, 47, 0, 153, 153,0.000000 },
- { 152, 152, 44, 0, 86, 86,0.000000 },
- {3784,3784, 50, 0, 160, 160,0.000000 },
- { 139, 139, 44, 0, 86, 86,0.000000 },
- {3784,3784, 54, 0, 160, 160,0.000000 },
- {3784,3784, 57, 0, 160, 160,0.000000 },
- {3786,3786, 60, 0, 606, 606,0.000000 },
- {3784,3784, 60, 0, 166, 166,0.000000 },
- {3787,3787, 60, 0, 606, 606,0.000000 },
- {3788,3788, 60, 0, 626, 626,0.000000 },
- {3789,3789, 60, 0, 626, 626,0.000000 },
- {3790,3790, 60, 0, 606, 606,0.000000 },
- {3791,3791, 44, 0, 300, 300,0.000000 },
- {2037,2037, 44, 0, 40, 40,0.000000 },
- { 144, 144, 44, 0, 40, 40,0.000000 },
- {2038,2038, 44, 0, 13, 13,0.000000 },
- {3792,3792, 44, 0, 33, 33,0.000000 },
- {3793,3793, 44, 0, 60, 60,0.000000 },
- {3794,3794, 45, 0, 80, 80,0.000000 },
- {3795,3795, 33, 0, 100, 100,0.000000 },
- {3796,3796, 56, 0, 153, 153,0.000000 },
- {3796,3796, 51, 0, 153, 153,0.000000 },
- {3797,3797, 44, 0, 40, 40,0.000000 },
- {3798,3798, 44, 0, 200, 200,0.000000 },
- {3534,3534, 56, 0, 73, 73,0.000000 },
- { 158, 158, 68, 0, 20, 20,0.000000 },
- {3799,3799, 51, 0, 160, 160,0.000000 },
- {3800,3800, 46, 0, 153, 153,0.000000 },
- {3801,3801, 44, 0, 160, 160,0.000000 },
- {3802,3802, 44, 0, 1233, 1233,0.000000 },
- { 152, 152, 45, 0, 80, 80,0.000000 },
- {3803,3803, 0, 0, 40000, 20,0.000000 },
- {3804,3804, 0, 0, 40000, 66,0.000000 },
- {3805,3805, 0, 0, 40000, 0,0.000000 },
- {3806,3806, 0, 0, 40000, 0,0.000000 },
- {3807,3807, 0, 0, 40000, 20,0.000000 },
- {3808,3808, 0, 0, 1226, 1226,0.000000 },
- {3809,3809, 0, 0, 546, 546,0.000000 },
- {3810,3810, 0, 0, 280, 280,0.000000 },
- {3811,3811, 0, 0, 60, 60,0.000000 },
- {3812,3812, 0, 0, 1213, 1213,0.000000 },
- {3780,3780, 45, 0, 440, 440,0.000000 },
- {3061,3061, 45, 0, 606, 606,0.000000 },
- {3813,3813, 60, 0, 20, 20,0.000000 },
- {3781,3781, 60, 0, 6, 6,0.000000 },
- {3814,3814, 44, 0, 173, 173,0.000000 },
- {3815,3815, 57, 0, 46, 46,0.000000 },
- {3816,3816, 56, 0, 73, 73,0.000000 },
- {3817,3817, 60, 0, 20, 20,0.000000 },
- {3818,3818, 60, 0, 20, 20,0.000000 },
- {3517,3517, 45, 0, 40, 40,0.000000 },
- {3819,3819, 0, 0, 820, 820,0.000000 },
- {3820,3820, 0, 0, 573, 573,0.000000 },
- {3821,3821, 0, 0, 473, 473,0.000000 },
- {3822,3822, 0, 0, 1020, 1020,0.000000 },
- {3823,3823, 0, 0, 40000, 393,0.000000 },
- {3824,3825, 0, 1, 40000, 266,0.078125 },
- {3826,3826, 0, 0, 3833, 13,0.000000 },
- {3827,3827, 0, 0, 40000, 406,0.000000 },
- {3828,1172, 0, 1, 40000, 320,0.156250 },
- {3829,3829, 0, 0, 40000, 13,0.000000 },
- {3830,3830, 0, 0, 120, 120,0.000000 },
- {3831,3831, 32, 0, 20, 20,0.000000 },
- {3832,3832, 36, 0, 46, 46,0.000000 },
- {3833,3833, 88, 0, 93, 93,0.000000 },
- {3834,3834, 0, 0, 1660, 1660,0.000000 },
- {3835,3835, 0, 0, 1746, 1746,0.000000 },
- {3836,3836, 0, 0, 1980, 1980,0.000000 },
- {3837,3837, 0, 0, 1553, 1553,0.000000 },
- {3838,3838, 0, 0, 1233, 1233,0.000000 },
- {3839,3839, 0, 0, 1980, 1980,0.000000 },
- {3840,3840, 0, 0, 940, 940,0.000000 },
- {3841,3841, 0, 0, 1740, 1740,0.000000 },
- {3842,3842, 0, 0, 40000, 133,0.000000 },
- {3843,3843, 0, 0, 40000, 26,0.000000 },
- {3844,3844, 0, 0, 40000, 60,0.000000 },
- {3845,3845, 0, 0, 40000, 320,0.000000 },
- {3846,3846, 0, 0, 40000, 53,0.000000 },
- {3847,3847, 0, 0, 40000, 160,0.000000 },
- {3848,3848, 0, 0, 40000, 106,0.000000 },
- {3849,3849, 0, 0, 1026, 1026,0.000000 },
- {3850,3850, 0, 0, 1826, 1826,0.000000 },
- {3851,3851, 0, 0, 1813, 1813,0.000000 },
- {3852,3852, 0, 0, 1013, 1013,0.000000 },
- {3853,3853, 0, 0, 40000, 0,0.000000 },
- {3854,3854, 0, 0, 40000, 53,0.000000 },
- {3855,3855, 0, 0, 40000, 53,0.000000 },
- {3856,3856, 0, 0, 4200, 4200,0.000000 },
- {3857,3857, 0, 0, 40000, 106,0.000000 },
- {3858,3858, 0, 0, 1746, 1746,0.000000 },
- {3859,3859, 0, 0, 40000, 120,0.000000 },
- {3860,3860, 0, 0, 2400, 2400,0.000000 },
- {3861,3861, 0, 0, 4606, 4606,0.000000 },
- {3862,3862, 0, 0, 1740, 1740,0.000000 },
- {3863,3863, 0, 0, 40000, 66,0.000000 },
- {3864,3864, 0, 0, 40000, 46,0.000000 },
- {3865,3865, 0, 0, 40000, 66,0.000000 },
- {3866,3866, 0, 0, 40000, 26,0.000000 },
- {3867,3867, 0, 0, 40000, 293,0.000000 },
- {3868,3868, 0, 0, 40000, 133,0.000000 },
- {3869,3869, 0, 0, 333, 333,0.000000 },
- {3870,3870, 0, 0, 993, 993,0.000000 },
- {3871,3871, 0, 0, 40000, 280,0.000000 },
- {3872,3872, 0, 0, 1766, 13,0.000000 },
- {3873,3873, 0, 0, 40000, 820,0.000000 },
- {3874,3874, 0, 0, 40000, 286,0.000000 },
- {3875,3875, 0, 0, 40000, 580,0.000000 },
- {3876,3876, 0, 0, 2300, 2300,0.000000 },
- {3877,3877, 0, 0, 40000, 146,0.000000 },
- {3878,3878, 0, 0, 40000, 6,0.000000 },
- {3879,3879, 0, 0, 40000, 66,0.000000 },
- {3880,3880, 0, 0, 40000, 6,0.000000 },
- {3881,3881, 0, 0, 40000, 6,0.000000 },
- {3882,3882, 0, 0, 40000, 126,0.000000 },
- {3883,3883, 0, 0, 40000, 33,0.000000 },
- {3884,3884, 0, 0, 40000, 53,0.000000 },
- {3885,3885, 0, 0, 40000, 93,0.000000 },
- {3886,3886, 0, 0, 40000, 73,0.000000 },
- {3887,3887, 0, 0, 40000, 66,0.000000 },
- {3888,3888, 0, 0, 40000, 86,0.000000 },
- {3889,3889, 0, 0, 40000, 46,0.000000 },
- {3890,3890, 0, 0, 3940, 13,0.000000 },
- {3891,3891, 0, 0, 40000, 33,0.000000 },
- {3892,3892, 0, 0, 40000, 53,0.000000 },
- {3893,3893, 0, 0, 40000, 53,0.000000 },
- {3894,3894, 0, 0, 40000, 73,0.000000 },
- {3895,3895, 0, 0, 40000, 126,0.000000 },
- {3896,3896, 0, 0, 40000, 60,0.000000 },
- {3897,3897, 0, 0, 40000, 106,0.000000 },
- {3898,3898, 0, 0, 40000, 6,0.000000 },
- {3899,3899, 0, 0, 40000, 266,0.000000 },
- {3900,3900, 0, 0, 40000, 53,0.000000 },
- {3901,3901, 0, 0, 40000, 233,0.000000 },
- {3902,3902, 0, 0, 1660, 180,0.000000 },
- {3903,3903, 0, 0, 40000, 566,0.000000 },
- {3904,3904, 0, 0, 40000, 100,0.000000 },
- {3905,3905, 0, 0, 593, 13,0.000000 },
- {3906,3906, 0, 0, 40000, 173,0.000000 },
- {3907,3907, 0, 0, 40000, 53,0.000000 },
- {3908,3908, 0, 0, 40000, 106,0.000000 },
- {3909,3909, 0, 0, 2133, 2133,0.000000 },
- {3910,3910, 0, 0, 40000, 846,0.000000 },
- {3911,3911, 0, 0, 40000, 773,0.000000 },
- {3912,3912, 0, 0, 1066, 1066,0.000000 },
- {3913,3913, 0, 0, 40000, 73,0.000000 },
- {3914,3914, 0, 0, 40000, 86,0.000000 },
- {3915,3915, 0, 0, 40000, 46,0.000000 },
- {3916,3916, 0, 0, 1126, 1126,0.000000 },
- {3917,3917, 0, 0, 40000, 13,0.000000 },
- {3918,3918, 0, 0, 300, 300,0.000000 },
- {3919,3919, 0, 0, 146, 146,0.000000 },
- {3920,3920, 0, 0, 140, 140,0.000000 },
- {3921,3921, 0, 0, 1920, 1920,0.000000 },
- {3922,3922, 0, 0, 40000, 0,0.000000 },
- {3923,3923, 0, 0, 533, 533,0.000000 },
- {3924,3924, 0, 0, 486, 486,0.000000 },
- {3925,3925, 0, 0, 940, 940,0.000000 },
- {3926,3926, 0, 0, 600, 600,0.000000 },
- {3927,3927, 0, 0, 253, 253,0.000000 },
- {3928,3928, 0, 0, 380, 73,0.000000 },
- {3929,3929, 0, 0, 40, 40,0.000000 },
- {3930,3930, 0, 0, 40000, 20,0.000000 },
- {3931,3931, 0, 0, 40000, 13,0.000000 },
- {3932,3932, 0, 0, 4600, 4600,0.000000 },
- {3933,3933, 0, 0, 4820, 4820,0.000000 },
- { 523, 523, 0, 0, 46, 46,0.000000 },
- {3934,3934, 0, 0, 66, 66,0.000000 },
- {3935,3935, 0, 0, 53, 53,0.000000 },
- {3936,3936, 48, 0, 26, 26,0.000000 },
- {3937,3937, 27, 0, 53, 53,0.000000 },
- {3938,3938, 40, 0, 40, 40,0.000000 },
- {3939,3939, 48, 0, 13, 13,0.000000 },
- {3938,3938, 45, 0, 46, 46,0.000000 },
- {3940,3940, 48, 0, 26, 26,0.000000 },
- {3938,3938, 47, 0, 66, 66,0.000000 },
- {3941,3941, 48, 0, 13, 13,0.000000 },
- {3938,3938, 49, 0, 73, 73,0.000000 },
- {3938,3938, 53, 0, 80, 80,0.000000 },
- {3938,3938, 56, 0, 66, 66,0.000000 },
- { 129, 129, 52, 0, 73, 73,0.000000 },
- { 130, 130, 48, 0, 40, 40,0.000000 },
- { 129, 129, 58, 0, 73, 73,0.000000 },
- { 132, 132, 47, 0, 20, 20,0.000000 },
- { 492, 492, 43, 0, 26, 26,0.000000 },
- { 132, 132, 49, 0, 20, 20,0.000000 },
- { 132, 132, 51, 0, 20, 20,0.000000 },
- { 132, 132, 54, 0, 20, 20,0.000000 },
- { 132, 132, 57, 0, 13, 13,0.000000 },
- { 492, 492, 72, 0, 140, 140,0.000000 },
- { 137, 137, 76, 0, 600, 600,0.000000 },
- { 138, 138, 84, 0, 246, 246,0.000000 },
- { 139, 139, 36, 0, 113, 113,0.000000 },
- { 140, 140, 76, 0, 586, 586,0.000000 },
- { 141, 141, 84, 0, 60, 60,0.000000 },
- { 135, 135, 83, 0, 413, 413,0.000000 },
- { 142, 142, 84, 0, 106, 106,0.000000 },
- {3942,3942, 24, 0, 600, 600,0.000000 },
- { 137, 137, 77, 0, 606, 606,0.000000 },
- { 144, 144, 60, 0, 40, 40,0.000000 },
- { 145, 145, 65, 0, 13, 13,0.000000 },
- { 146, 146, 59, 0, 40, 40,0.000000 },
- { 147, 147, 51, 0, 40, 40,0.000000 },
- { 148, 148, 45, 0, 46, 46,0.000000 },
- { 149, 149, 71, 0, 140, 140,0.000000 },
- { 150, 150, 60, 0, 146, 146,0.000000 },
- { 151, 151, 58, 0, 153, 153,0.000000 },
- { 152, 152, 53, 0, 80, 80,0.000000 },
- { 153, 153, 64, 0, 13, 13,0.000000 },
- { 154, 154, 71, 0, 273, 273,0.000000 },
- { 156, 156, 61, 0, 53, 53,0.000000 },
- { 158, 158, 48, 0, 40, 40,0.000000 },
- { 159, 159, 69, 0, 20, 20,0.000000 },
- { 160, 160, 68, 0, 20, 20,0.000000 },
- { 161, 161, 63, 0, 113, 113,0.000000 },
- { 162, 162, 74, 0, 293, 293,0.000000 },
- { 163, 163, 60, 0, 113, 113,0.000000 },
- { 164, 164, 80, 0, 440, 440,0.000000 },
- { 165, 165, 64, 0, 40, 40,0.000000 },
- { 166, 166, 69, 0, 286, 286,0.000000 },
- { 167, 167, 73, 0, 126, 126,0.000000 },
- { 168, 168, 75, 0, 20, 20,0.000000 },
- { 169, 169, 68, 0, 33, 33,0.000000 },
- { 131, 131, 48, 0, 93, 93,0.000000 },
- {3061,3061, 53, 0, 833, 833,0.000000 },
- {3943,3944, 0, 0, 546, 546,0.000000 },
- {3945,3946, 0, 0, 1813, 1813,0.000000 },
- { 174,3947, 0, 0, 1260, 1260,0.000000 },
- {3948,3949, 0, 0, 160, 160,0.000000 },
- { 9,3950, 0, 0, 1100, 1100,0.000000 },
- {3951,3952, 0, 0, 3360, 3360,0.000000 },
- {3953,3954, 0, 0, 1720, 1720,0.000000 },
- { 15,3955, 0, 0, 226, 226,0.000000 },
- {3956,3957, 0, 0, 40000, 6,0.000000 },
- {3958,3959, 0, 0, 40000, 6,0.000000 },
- {3960,3961, 0, 0, 40000, 186,0.000000 },
- {3962,3963, 0, 0, 40000, 6,0.000000 },
- {3964,3965, 0, 0, 146, 146,0.000000 },
- {3966,3965, 0, 0, 146, 146,0.000000 },
- { 31,3967, 0, 0, 3386, 3386,0.000000 },
- {3968,3969, 0, 0, 3520, 3520,0.000000 },
- {3970,3971, 0, 0, 126, 0,0.000000 },
- {3972,3971, 0, 0, 126, 0,0.000000 },
- {3973,3974, 0, 0, 1013, 1013,0.000000 },
- {3975,3976, 0, 0, 3733, 3733,0.000000 },
- {3977,3976, 0, 0, 3733, 3733,0.000000 },
- {3978,3979, 0, 0, 3020, 3020,0.000000 },
- {3980,3981, 0, 0, 686, 686,0.000000 },
- {3982,3983, 0, 0, 40000, 46,0.000000 },
- {3984,3985, 0, 0, 40000, 373,0.000000 },
- { 54,3986, 0, 0, 340, 340,0.000000 },
- {3987,3988, 0, 0, 1213, 6,0.000000 },
- {3989,3990, 0, 0, 40000, 53,0.000000 },
- {3991, 253, 0, 0, 40000, 126,0.000000 },
- {3992,3992, 0, 0, 40, 40,0.000000 },
- {3993,3993, 0, 0, 40000, 53,0.000000 },
- {3994,3995, 0, 0, 40000, 13,0.000000 },
- {3996,3997, 0, 0, 40000, 40,0.000000 },
- {3998,3999, 0, 0, 40000, 13,0.000000 },
- {1503,4000, 0, 0, 40000, 33,0.000000 },
- { 88,4001, 0, 0, 40000, 500,0.000000 },
- {3743,4002, 0, 0, 900, 900,0.000000 },
- { 92,4003, 0, 0, 1720, 13,0.000000 },
- { 93,4004, 0, 0, 1060, 80,0.000000 },
- { 94,4005, 0, 0, 40000, 53,0.000000 },
- { 96,4006, 0, 0, 1913, 533,0.000000 },
- { 103,4007, 0, 0, 1813, 1813,0.000000 },
- { 104,4008, 0, 0, 846, 846,0.000000 },
- { 105,4009, 0, 0, 900, 900,0.000000 },
- { 107,4010, 0, 0, 300, 300,0.000000 },
- { 108,4011, 0, 0, 40000, 6,0.000000 },
- { 110,4012, 0, 0, 40000, 6,0.000000 },
- { 111,4013, 0, 0, 1126, 1126,0.000000 },
- {4014,4015, 0, 0, 140, 140,0.000000 },
- { 115,4016, 0, 0, 146, 146,0.000000 },
- { 118,4017, 0, 0, 2280, 2280,0.000000 },
- { 119,4018, 0, 0, 286, 286,0.000000 },
- { 120,4019, 0, 0, 586, 586,0.000000 },
- { 121,4020, 0, 0, 4426, 4426,0.000000 },
- { 123,4021, 0, 0, 193, 193,0.000000 },
- { 124,4022, 0, 0, 146, 260,0.000000 },
- { 125,4023, 0, 0, 40000, 773,0.000000 },
- {4024,4024, 35, 0, 40, 40,0.000000 },
- {4025,4026, 38, 1, 93, 93,0.000000 },
- {4027,4028, 38, 1, 120, 120,0.000000 },
- {4029,4030, 48, 1, 73, 73,-1.906250 },
- {4031,4031, 51, 0, 26, 26,0.000000 },
- {4032,4033, 48, 1, 293, 293,-1.906250 },
- {4034,4034, 61, 1, 1873, 1873,0.093750 },
- {3369,1557, 70, 0, 906, 906,0.000000 },
- {4035,4036, 79, 1, 293, 293,0.078125 },
- {4037,4037, 62, 0, 1726, 1726,0.000000 },
- {4038,4039, 67, 1, 240, 240,0.078125 },
- {4040,4040, 62, 1, 2040, 2040,0.093750 },
- {4041,4042, 54, 1, 80, 80,0.000000 },
- {4041,4043, 48, 1, 80, 80,0.000000 },
- { 389, 389, 42, 0, 180, 180,0.000000 },
- {4044,4045, 48, 1, 80, 80,0.000000 },
- {4046,4047, 48, 1, 53, 53,0.000000 },
- {4048,4048, 16, 0, 20, 20,0.000000 },
- {4049,4049, 16, 0, 146, 146,0.000000 },
- {4050,4051, 64, 0, 646, 646,0.000000 },
- { 844, 844,244, 0, 13, 13,0.000000 },
- { 855, 855,244, 0, 246, 6,0.000000 },
- { 880, 880,232, 0, 46, 46,0.000000 },
- { 882, 882,220, 0, 5433, 5433,0.000000 },
- { 887, 887, 35, 0, 46, 46,0.000000 },
- { 884, 884, 35, 0, 73, 73,0.000000 },
- { 885, 885, 35, 0, 73, 73,0.000000 },
- { 886, 886, 35, 0, 20, 20,0.000000 },
- { 361, 361, 35, 0, 113, 113,0.000000 },
- { 767, 767, 35, 0, 760, 760,0.000000 },
- { 888, 888, 35, 0, 40, 40,0.000000 },
- {2141,2141, 35, 0, 53, 53,0.000000 },
- { 891, 891, 35, 0, 106, 106,0.000000 },
- {2142,2142, 35, 0, 53, 53,0.000000 },
- {2143,2143, 35, 0, 73, 73,0.000000 },
- {2144,2144, 35, 0, 800, 800,0.000000 },
- {2145,2145, 35, 0, 420, 420,0.000000 },
- { 376, 376, 35, 0, 146, 146,0.000000 },
- { 895, 895, 35, 0, 126, 126,0.000000 },
- {2146,2146, 35, 0, 100, 100,0.000000 },
- { 382, 382, 35, 0, 20, 20,0.000000 },
- {2147,2147, 35, 0, 20, 20,0.000000 },
- { 898, 898, 35, 0, 60, 60,0.000000 },
- { 899, 899, 35, 0, 206, 206,0.000000 },
- { 900, 900, 35, 0, 193, 193,0.000000 },
- { 871, 871, 35, 0, 120, 120,0.000000 },
- { 388, 388, 35, 0, 73, 73,0.000000 },
- { 901, 901, 35, 0, 173, 173,0.000000 },
- { 902, 902, 35, 0, 1006, 1006,0.000000 },
- { 903, 903, 35, 0, 40, 40,0.000000 },
- {3500,3500, 35, 0, 5233, 6,0.000000 },
- {4052,4052, 0, 0, 1400, 1400,0.000000 },
- {4053,4053, 0, 0, 1206, 1206,0.000000 },
- {4054,4054, 0, 0, 40000, 46,0.000000 },
- {4055,4055, 0, 0, 40000, 26,0.000000 },
- {4056,4056, 0, 0, 3600, 3600,0.000000 },
- {4057,4057, 0, 0, 40000, 6,0.000000 },
- {4058,4058, 0, 0, 960, 960,0.000000 },
- {4059,4059, 0, 0, 80, 80,0.000000 },
- {4060,4060, 0, 0, 40000, 20,0.000000 },
- {4061,4061, 0, 0, 40000, 20,0.000000 },
- {4062,4062, 0, 0, 4473, 4473,0.000000 },
- {4063,4063, 0, 0, 380, 6,0.000000 },
- {4064,4064, 0, 0, 40000, 20,0.000000 },
- {4065,4065, 0, 0, 4593, 4593,0.000000 },
- {4066,4066, 0, 0, 40000, 20,0.000000 },
- {4067,4067, 0, 0, 40000, 0,0.000000 },
- {4068,4068, 0, 0, 40, 40,0.000000 },
- {4069,4069, 0, 0, 60, 60,0.000000 },
- {4070,4070, 0, 0, 100, 100,0.000000 },
- {4071,4071, 0, 0, 40000, 40,0.000000 },
- {4072,4072, 0, 0, 126, 126,0.000000 },
- {4073,4073, 0, 0, 40, 40,0.000000 },
- {4074,4074, 0, 0, 40000, 0,0.000000 },
- {4075,4075, 0, 0, 4193, 4193,0.000000 },
- {4076,4076, 0, 0, 806, 0,0.000000 },
- {4077,4077, 0, 0, 526, 526,0.000000 },
- {4078,4078, 0, 0, 40000, 73,0.000000 },
- {4079,4079, 0, 0, 40000, 6,0.000000 },
- {4080,4080, 0, 0, 40000, 153,0.000000 },
- {4081,4081, 0, 0, 40000, 0,0.000000 },
- {4082,4082, 0, 0, 40, 6,0.000000 },
- {4083,4083, 0, 0, 3400, 0,0.000000 },
- {4084,4084, 0, 0, 2280, 0,0.000000 },
- {4085,4085, 0, 0, 40000, 426,0.000000 },
- {4086,4086, 0, 0, 1206, 1206,0.000000 },
- { 127, 127, 36, 0, 20, 20,0.000000 },
- {4087,4087, 36, 0, 6, 6,0.000000 },
- {2030,2030, 36, 0, 93, 93,0.000000 },
- {3782,3782, 48, 0, 6, 6,0.000000 },
- {3783,3783, 36, 0, 33, 33,0.000000 },
- {4088,4088, 48, 0, 246, 246,0.000000 },
- { 132, 132, 69, 0, 13, 13,0.000000 },
- {4088,4088, 52, 0, 360, 360,0.000000 },
- { 152, 152, 48, 0, 86, 86,0.000000 },
- {4088,4088, 55, 0, 493, 493,0.000000 },
- { 139, 139, 57, 0, 93, 93,0.000000 },
- {4088,4088, 58, 0, 560, 560,0.000000 },
- {4088,4088, 60, 0, 580, 580,0.000000 },
- {4089,4089, 62, 0, 840, 840,0.000000 },
- {4088,4088, 63, 0, 626, 626,0.000000 },
- { 134, 134, 70, 0, 140, 140,0.000000 },
- {4090,4090, 70, 0, 286, 286,0.000000 },
- {4091,4091, 53, 0, 613, 613,0.000000 },
- {3516,3516, 48, 0, 40, 40,0.000000 },
- {4092,4092, 84, 0, 420, 420,0.000000 },
- {4093,4093, 43, 0, 160, 160,0.000000 },
- {4094,4094, 56, 0, 326, 326,0.000000 },
- {3791,3791, 24, 0, 140, 140,0.000000 },
- { 134, 134, 65, 0, 160, 160,0.000000 },
- { 146, 146, 48, 0, 40, 40,0.000000 },
- { 146, 146, 54, 0, 40, 40,0.000000 },
- {4095,4095, 42, 0, 46, 46,0.000000 },
- {4095,4095, 39, 0, 46, 46,0.000000 },
- {3816,3816, 52, 0, 106, 106,0.000000 },
- {4096,4096, 52, 0, 200, 200,0.000000 },
- { 158, 158, 60, 0, 33, 33,0.000000 },
- { 158, 158, 66, 0, 33, 33,0.000000 },
- { 158, 158, 59, 0, 33, 33,0.000000 },
- {3538,3538, 91, 0, 273, 273,0.000000 },
- {3547,3547,109, 0, 1780, 1780,0.000000 },
- {4097,4097, 79, 0, 126, 126,0.000000 },
- {4098,4098, 0, 0, 3413, 3413,0.000000 },
- {4099,4100, 0, 1, 1613, 1613,0.031250 },
- {4101,4102, 0, 1, 2146, 2146,0.031250 },
- {4103,4104, 0, 1, 1646, 1646,0.046875 },
- {4105,4106, 0, 1, 1900, 1900,0.156250 },
- {4107,4108, 0, 1, 1473, 1473,0.046875 },
- {4109,4110, 0, 1, 1020, 1020,0.062500 },
- {4111,4112, 0, 1, 2126, 2126,0.000000 },
- {4113,4114, 0, 1, 1740, 1740,0.000000 },
- {4115,4116, 0, 1, 993, 993,0.000025 },
- {4117,4118, 0, 1, 886, 886,0.000000 },
- {4119,4120, 0, 1, 1153, 1153,0.046875 },
- {4121,4122, 0, 1, 1420, 1420,0.000000 },
- {4123,4124, 0, 1, 193, 193,0.000000 },
- {4125,4126, 0, 1, 406, 406,0.000000 },
- {4127,4128, 0, 1, 1400, 1400,0.031250 },
- {4129,4129, 0, 1, 980, 980,0.031250 },
- {4130,4131, 0, 1, 40000, 6,0.156250 },
- {4132,4133, 0, 1, 40, 13,0.078125 },
- {4134,4135, 0, 1, 7180, 13,0.156250 },
- {4136,4137, 0, 1, 40000, 180,0.031250 },
- {4138,4139, 0, 1, 40000, 46,0.062500 },
- {4140,4141, 0, 1, 40000, 46,0.140625 },
- {4142,4143, 0, 1, 40000, 6,0.000000 },
- {4144,4145, 0, 1, 40000, 153,0.109375 },
- {4146,4147, 0, 1, 920, 920,0.000000 },
- {4148,4149, 0, 1, 653, 653,0.000025 },
- {4150,4151, 0, 1, 633, 633,0.000000 },
- {4152,4153, 0, 1, 893, 893,0.046875 },
- {4154,4155, 0, 1, 440, 440,0.000000 },
- {4156,4157, 0, 1, 40000, 60,-1.906250 },
- {4158,4159, 0, 1, 40000, 60,-1.906250 },
- {4160,4161, 0, 1, 2033, 2033,0.234375 },
- {4162,4163, 0, 1, 1900, 1900,0.031250 },
- {4164,4165, 0, 1, 1453, 1453,0.000000 },
- {4166,4167, 0, 1, 2186, 2186,0.000000 },
- {4168,4169, 0, 1, 1933, 1933,0.046875 },
- {4170,4171, 0, 1, 633, 633,0.000000 },
- {4172,4173, 0, 1, 486, 486,0.000000 },
- {4174,4174, 0, 0, 313, 313,0.000000 },
- {4175,4176, 0, 1, 2533, 2533,0.078125 },
- {4177,4178, 0, 1, 2040, 13,0.000000 },
- {4179,4179, 0, 0, 40000, 66,0.000000 },
- {4180,4181, 0, 1, 40000, 60,0.000025 },
- {4182,4182, 0, 0, 40000, 133,0.000000 },
- {4183,4184, 0, 1, 40000, 173,0.078125 },
- {4185,4186, 0, 1, 333, 333,0.109375 },
- {4187,4188, 0, 1, 1813, 1813,0.031250 },
- {4189,4190, 0, 1, 1473, 1473,0.031250 },
- {4191,4192, 0, 1, 40000, 213,0.062500 },
- {4193,4194, 0, 1, 40000, 500,-0.062500 },
- {4195,4195, 0, 1, 40000, 326,0.109375 },
- {4196,4196, 0, 1, 40000, 406,0.109375 },
- {4197,4198, 0, 1, 40000, 280,0.140625 },
- {4199,4200, 0, 1, 40000, 53,0.140625 },
- {4201,4202, 0, 1, 40000, 286,0.156250 },
- {4203,4204, 0, 1, 206, 206,0.125000 },
- {4205,4206, 0, 1, 40000, 26,0.000000 },
- {4207,4208, 0, 1, 40000, 20,0.031250 },
- {4209,4209, 0, 0, 40000, 6,0.000000 },
- {4210,4210, 0, 0, 40000, 20,0.000000 },
- {4211,4212, 0, 1, 40000, 160,0.031250 },
- {4213,4214, 0, 1, 40000, 73,0.062500 },
- {4215,4216, 0, 1, 2526, 2526,0.093750 },
- {4217,4217, 0, 1, 5153, 5153,0.125000 },
- {4218,4219, 0, 1, 40000, 73,0.000000 },
- {4220,4220, 0, 0, 40000, 60,0.000000 },
- {4221,4221, 0, 0, 40000, 0,0.000000 },
- {4222,4222, 0, 0, 40000, 0,0.000000 },
- {4223,4224, 0, 1, 40000, 73,0.000000 },
- {4225,4225, 0, 0, 40000, 33,0.000000 },
- {4226,4226, 0, 0, 40000, 6,0.000000 },
- {4227,4228, 0, 1, 40000, 40,0.000000 },
- {4229,4229, 0, 0, 40000, 0,0.000000 },
- {4230,4230, 0, 0, 40000, 6,0.000000 },
- {4231,4231, 0, 0, 40000, 33,0.000000 },
- {4232,4233, 0, 1, 40000, 53,0.031250 },
- {4234,4235, 0, 1, 40000, 20,0.046875 },
- {4236,4237, 0, 1, 420, 420,0.031250 },
- {4238,4238, 0, 0, 40000, 106,0.000000 },
- {4239,4239, 0, 0, 40000, 6,0.000000 },
- {4240,4241, 0, 1, 40000, 6,0.125000 },
- {4242,4243, 0, 1, 40000, 13,0.109375 },
- {4244,4245, 0, 1, 40000, 53,0.109375 },
- {4246,4247, 0, 1, 226, 6,-0.031250 },
- {4248,4248, 0, 0, 40000, 6,0.000000 },
- {4249,4250, 0, 1, 40000, 133,0.156250 },
- {4251,4252, 0, 1, 4186, 13,0.125000 },
- {4253,4254, 0, 1, 40000, 26,0.031250 },
- {4255,4256, 0, 1, 40000, 660,0.078125 },
- {4257,4258, 0, 1, 846, 66,0.109375 },
- {4259,4260, 0, 1, 1293, 80,0.078125 },
- {4261,4262, 0, 1, 40000, 300,0.140625 },
- {4263,4264, 0, 1, 2040, 2040,0.109375 },
- {4265,4266, 0, 1, 1360, 1360,0.062500 },
- {4267,4268, 0, 1, 40000, 433,0.093750 },
- {4269,4270, 0, 1, 40000, 533,0.109375 },
- {4271,4272, 0, 1, 826, 826,0.093750 },
- {4273,4274, 0, 1, 40000, 926,0.125000 },
- {4275,4275, 0, 1, 886, 886,0.109375 },
- {4276,4277, 0, 1, 2186, 2186,-0.046875 },
- {4278,4279, 0, 1, 1486, 1486,0.125000 },
- {4280,4281, 0, 1, 40000, 393,-0.078125 },
- {4282,4283, 0, 1, 40000, 1166,0.140625 },
- {4284,4285, 0, 1, 360, 360,0.078125 },
- {4286,4287, 0, 1, 1693, 1693,0.031250 },
- {4288,4289, 0, 1, 760, 760,0.000000 },
- {4290,4291, 0, 1, 126, 126,0.031250 },
- {4292,4292, 0, 0, 300, 300,0.000000 },
- {4293,4294, 0, 1, 280, 280,0.000000 },
- {4295,4296, 0, 1, 40000, 26,0.062500 },
- {4297,4297, 0, 0, 40000, 66,0.000000 },
- {4298,4298, 0, 0, 40000, 53,0.000000 },
- {4299,4299, 0, 0, 1940, 1940,0.000000 },
- {4300,4300, 0, 0, 86, 86,0.000000 },
- {4301,4302, 0, 1, 280, 280,0.031250 },
- {4303,4303, 0, 0, 40, 40,0.000000 },
- {4304,4305, 0, 1, 53, 53,0.000000 },
- {4306,4307, 0, 1, 140, 140,0.000000 },
- {4308,4309, 0, 1, 26, 26,0.000000 },
- {4310,4311, 0, 1, 2153, 2153,0.109375 },
- {4312,4312, 0, 0, 293, 293,0.000000 },
- {4313,4314, 0, 1, 993, 26,0.000000 },
- {4315,4316, 0, 1, 5613, 5613,0.000000 },
- {4317,4317, 0, 0, 220, 220,0.000000 },
- {4318,4319, 0, 1, 10306, 526,0.000000 },
- {4320,4321, 0, 1, 1486, 13,0.000000 },
- {4322,4323, 0, 1, 40000, 660,0.000000 },
- {4324,4324, 0, 0, 120, 120,0.000000 },
- {4325,4325, 34, 0, 40, 40,0.000000 },
- {4326,4326, 28, 0, 73, 73,0.000000 },
- {4327,4328, 39, 1, 233, 233,0.000000 },
- {4327,4328, 33, 1, 193, 193,0.000000 },
- {4329,4330, 63, 1, 33, 33,0.000000 },
- {4331,4331, 15, 0, 13, 13,0.000000 },
- {4332,4332, 36, 0, 13, 13,0.000000 },
- {4332,4333, 36, 1, 133, 133,0.406250 },
- {4334,4335, 25, 1, 13, 13,0.000000 },
- {4336,4335, 25, 1, 33, 33,0.000000 },
- {4337,4338, 61, 1, 40, 40,0.000000 },
- {4339,4340, 37, 1, 53, 53,0.000000 },
- {4341,4342, 15, 1, 80, 80,0.000000 },
- {4343,4344, 48, 1, 73, 73,-1.906250 },
- {4345,4346, 19, 1, 120, 120,0.000000 },
- {4347,4347, 48, 0, 53, 53,0.000000 },
- {4348,4349, 15, 1, 33, 33,0.000000 },
- {4350,4351, 12, 1, 33, 33,0.000000 },
- {4352,4353, 11, 1, 33, 33,0.000000 },
- {4354,4353, 8, 1, 40, 40,0.000000 },
- {4355,4356, 60, 1, 246, 246,0.031250 },
- {4357,4357, 70, 0, 340, 340,0.000000 },
- {4358,4359, 80, 1, 106, 106,0.125000 },
- {4360,4360, 58, 0, 73, 73,0.000000 },
- {4361,4362, 31, 1, 313, 313,0.000000 },
- {4363,4363, 61, 0, 253, 253,0.000000 },
- {4364,4365, 41, 1, 100, 100,0.000000 },
- {4366,4367, 35, 1, 160, 160,0.000000 },
- {4368,4369, 29, 1, 40, 40,0.000000 },
- {4370,4371, 41, 1, 166, 166,0.000000 },
- {4370,4371, 37, 1, 160, 160,0.000000 },
- {4372,4373, 54, 1, 80, 80,0.000000 },
- {4372,4374, 48, 1, 80, 80,0.000000 },
- {4375,4376, 77, 1, 53, 53,0.000000 },
- {4377,4378, 72, 1, 46, 46,0.000000 },
- {4379,4379, 40, 0, 140, 140,0.000000 },
- {4380,4380, 38, 0, 73, 73,0.000000 },
- {4381,4381, 36, 0, 533, 533,0.000000 },
- {4382,4383, 60, 1, 26, 26,0.000000 },
- {4383,4384, 60, 1, 26, 26,0.000000 },
- {4385,4385, 73, 0, 60, 60,0.000000 },
- {4386,4387, 68, 1, 40, 40,0.000000 },
- {4388,4389, 18, 1, 60, 60,0.000000 },
- {4390,4391, 18, 1, 106, 106,0.000000 },
- {4392,4392, 90, 0, 80, 80,0.000000 },
- {4393,4393, 90, 0, 306, 306,0.000000 },
- {4394,4395, 64, 1, 233, 233,0.031250 },
- {4396,4397, 80, 1, 140, 140,0.031250 },
- {4398,4399, 64, 1, 606, 606,0.000000 },
- {4400,4400, 67, 0, 20, 20,0.000000 },
- {4401,4402, 50, 1, 53, 53,0.000000 },
- {4403,4403, 36, 0, 66, 66,0.000000 },
- {4404,4404, 0, 0, 40000, 20,0.000000 },
- {4405,4405, 0, 0, 40000, 0,0.000000 },
- {4406,4406, 0, 0, 360, 360,0.000000 },
- {4407,4407, 0, 0, 586, 586,0.000000 },
- {4408,4408, 0, 0, 40000, 0,0.000000 },
- {4409,4409, 0, 0, 40000, 0,0.000000 },
- {4410,4410, 0, 0, 40000, 0,0.000000 },
- {4411,4411, 0, 0, 40000, 6,0.000000 },
- {4412,4412, 0, 0, 40000, 0,0.000000 },
- {4413,4413, 0, 0, 146, 146,0.000000 },
- {4413,4413, 73, 0, 886, 886,0.000000 },
- {4414,4414, 0, 0, 40, 0,0.000000 },
- {4415,4415, 0, 0, 486, 0,0.000000 },
- {4416,4416, 0, 0, 1226, 1226,0.000000 },
- {4417,4417, 0, 0, 1480, 1480,0.000000 },
- {4418,4418, 0, 0, 46, 46,0.000000 },
- {4419,4419, 0, 0, 126, 126,0.000000 },
- {4419,4419, 12, 0, 106, 106,0.000000 },
- {4420,4420, 0, 0, 160, 160,0.000000 },
- {4420,4420, 1, 0, 153, 153,0.000000 },
- {4421,4421, 0, 0, 20, 20,0.000000 },
- {4421,4421, 23, 0, 26, 26,0.000000 },
- {4422,4422, 0, 0, 140, 140,0.000000 },
- {4423,4423, 0, 0, 486, 486,0.000000 },
- {4424,4424, 0, 0, 40000, 13,0.000000 },
- {4425,4425, 0, 0, 40000, 0,0.000000 },
- {4426,4426, 0, 0, 1226, 1226,0.000000 },
- {4427,4427, 0, 0, 766, 766,0.000000 },
- {4428,4428, 0, 0, 93, 93,0.000000 },
- {4429,4429, 0, 2, 40000, 0,0.000000 },
- {4430,4430, 0, 0, 2026, 2026,0.000000 },
- {4431,4431, 0, 0, 2026, 2026,0.000000 },
- {4432,4432, 0, 0, 1920, 1920,0.000000 },
- {4433,4433, 0, 0, 2026, 2026,0.000000 },
- {4434,4434, 0, 0, 3606, 3606,0.000000 },
- {4435,4435, 0, 0, 1226, 1226,0.000000 },
- {4436,4436, 0, 0, 873, 873,0.000000 },
- {4437,4437, 0, 0, 1766, 1766,0.000000 },
- {4438,4438, 0, 0, 4033, 4033,-2.000000 },
- {4439,4439, 0, 0, 3873, 3873,-2.000000 },
- {4440,4440, 0, 0, 300, 300,-2.000000 },
- {4441,4441, 0, 0, 993, 993,0.000000 },
- {4442,4442, 0, 0, 140, 140,0.000000 },
- {4443,4443, 0, 0, 940, 940,0.000000 },
- {4444,4444, 0, 0, 40000, 0,0.000000 },
- {4445,4445, 0, 0, 380, 380,0.000000 },
- {4446,4446, 0, 0, 40000, 0,0.000000 },
- {4447,4447, 0, 0, 40000, 0,0.000000 },
- {4448,4448, 0, 0, 960, 960,0.000000 },
- {4449,4449, 0, 0, 940, 940,0.000000 },
- {4450,4450, 0, 0, 40000, 0,-2.000000 },
- {4451,4451, 0, 0, 40000, 0,-2.000000 },
- {4452,4452, 0, 0, 160, 160,0.000000 },
- {4453,4453, 0, 0, 593, 593,0.000000 },
- {4454,4454, 0, 0, 253, 253,0.000000 },
- {4454,4454, 0, 0, 253, 253,-2.000000 },
- {4455,4455, 0, 0, 1206, 1206,0.000000 },
- {4456,4456, 0, 0, 40000, 0,-2.000000 },
- {4457,4457, 0, 0, 940, 940,-2.000000 },
- {4458,4458, 0, 0, 40000, 46,0.000000 },
- {4459,4459, 0, 0, 40000, 26,0.000000 },
- {4460,4460, 0, 0, 40000, 60,0.000000 },
- {4461,4461, 0, 0, 126, 126,0.000000 },
- {4462,4462, 0, 0, 1580, 1580,0.000000 },
- {4463,4463, 0, 0, 86, 86,0.000000 },
- {4464,4464, 0, 0, 40000, 46,-2.000000 },
- {4465,4465, 0, 0, 40000, 46,-2.000000 },
- {4466,4466, 0, 0, 40000, 240,-2.000000 },
- {4467,4467, 0, 0, 40000, 6,0.000000 },
- {4468,4468, 0, 0, 713, 713,0.000000 },
- {4469,4469, 0, 0, 40000, 73,-2.000000 },
- {4470,4470, 0, 0, 40000, 33,-2.000000 },
- {4471,4471, 0, 0, 40000, 126,-2.000000 },
- {4472,4472, 0, 0, 146, 146,0.000000 },
- {3712,3712, 0, 0, 40000, 126,-2.000000 },
- {4473,4473, 0, 0, 40000, 73,-2.000000 },
- {4474,4474, 0, 0, 40000, 0,0.000000 },
- {4475,4475, 0, 0, 40000, 0,0.000000 },
- {4476,4476, 0, 0, 40000, 0,0.000000 },
- {4477,4477, 0, 0, 40000, 20,-2.000000 },
- {4478,4478, 0, 0, 40000, 13,0.000000 },
- {4479,4479, 0, 0, 40000, 6,-2.000000 },
- {4480,4480, 0, 0, 40000, 13,-2.000000 },
- {4481,4481, 0, 0, 40000, 6,-2.000000 },
- {4482,4482, 0, 0, 40000, 6,0.000000 },
- {4483,4483, 0, 0, 40000, 0,0.000000 },
- {4484,4484, 0, 0, 40000, 20,0.000000 },
- {4485,4485, 0, 0, 40000, 0,0.000000 },
- {4486,4486, 0, 0, 4620, 4620,0.000000 },
- {4487,4487, 0, 0, 40000, 0,0.000000 },
- {4457,4457, 0, 0, 940, 940,0.000000 },
- {4488,4488, 0, 0, 40000, 480,0.000000 },
- {4489,4489, 0, 0, 100, 100,0.000000 },
- {1221,1221, 0, 0, 40000, 53,0.171875 },
- {4490,4490, 0, 0, 160, 160,0.000000 },
- {4491,4491, 0, 0, 2533, 2533,0.000000 },
- {4492,4492, 0, 0, 2506, 2506,0.000000 },
- {4493,4493, 0, 0, 613, 613,0.000000 },
- {4494,4494, 0, 0, 40000, 1120,0.000000 },
- {4495,4495, 0, 0, 40000, 360,0.000000 },
- {4496,4496, 0, 0, 40000, 1053,0.000000 },
- {4497,4497, 0, 0, 40000, 1093,0.000000 },
- {4498,4498, 0, 0, 2260, 2260,0.000000 },
- {4499,4499, 0, 0, 1226, 1226,0.000000 },
- {4500,4500, 0, 0, 993, 993,0.000000 },
- {4501,4501, 0, 0, 40000, 40,0.000000 },
- {4502,4502, 0, 0, 40000, 0,0.000000 },
- {4503,4503, 0, 0, 1206, 1206,0.000000 },
- {4504,4504, 0, 0, 106, 106,-2.000000 },
- {4505,4505, 0, 0, 246, 246,0.000000 },
- {4506,4506, 0, 0, 226, 226,0.000000 },
- {4507,4507, 0, 0, 146, 146,-2.000000 },
- {4508,4508, 0, 0, 40000, 1120,0.000000 },
- {4509,4509, 0, 0, 1866, 33,0.000000 },
- {1261,1261, 0, 0, 40000, 2140,0.000000 },
- {4510,4510, 37, 0, 160, 160,-2.000000 },
- {4511,4511, 48, 0, 13, 13,-2.000000 },
- {4512,4512, 48, 0, 80, 80,-2.000000 },
- {4513,4513, 62, 0, 40, 40,0.000000 },
- {4514,4514, 44, 0, 146, 146,0.000000 },
- {4515,4515, 80, 0, 13, 13,0.000000 },
- {4514,4514, 50, 0, 386, 386,0.000000 },
- {4516,4516, 48, 0, 13, 13,-2.000000 },
- {4514,4514, 55, 0, 246, 246,0.000000 },
- {4517,4517, 61, 0, 160, 160,0.000000 },
- {4514,4514, 58, 0, 280, 280,0.000000 },
- {4514,4514, 63, 0, 313, 313,0.000000 },
- {4518,4518, 71, 0, 300, 300,0.000000 },
- {4514,4514, 72, 0, 253, 253,0.000000 },
- {4519,4519, 70, 0, 626, 626,0.000000 },
- {4518,4518, 88, 0, 293, 293,0.000000 },
- {4520,4520, 76, 0, 606, 606,0.000000 },
- {4521,4521, 84, 0, 80, 80,0.000000 },
- {4518,4518, 68, 0, 286, 286,0.000000 },
- {4522,4522, 72, 0, 33, 33,0.000000 },
- {4523,4523, 28, 0, 253, 253,0.000000 },
- {4519,4519, 81, 0, 440, 440,0.000000 },
- {4524,4524, 58, 0, 66, 66,-2.000000 },
- {4524,4524, 55, 0, 66, 66,-2.000000 },
- {4524,4524, 44, 0, 66, 66,-2.000000 },
- {4524,4524, 49, 0, 66, 66,-2.000000 },
- {4524,4524, 40, 0, 80, 80,-2.000000 },
- {4525,4525, 55, 0, 73, 73,-2.000000 },
- {4525,4525, 48, 0, 80, 80,-2.000000 },
- {4526,4526, 52, 0, 160, 160,0.000000 },
- {4526,4526, 45, 0, 160, 160,0.000000 },
- {4527,4527, 48, 0, 46, 46,-2.000000 },
- {4528,4528, 48, 0, 20, 20,-2.000000 },
- {4529,4529, 48, 0, 153, 153,-2.000000 },
- {4504,4504, 73, 0, 53, 53,-2.000000 },
- {4504,4504, 68, 0, 53, 53,-2.000000 },
- {4504,4504, 63, 0, 73, 73,-2.000000 },
- {4530,4530,108, 0, 220, 220,0.000000 },
- {4531,4531,108, 0, 440, 440,0.000000 },
+ { 0, 0, 0, 0, 9006, 133,0 },
+ { 1, 1, 0, 0, 9206, 146,0 },
+ { 2, 2, 0, 0, 9246, 240,0 },
+ { 3, 3, 0, 0, 9440, 140,0 },
+ { 4, 4, 0, 0, 8900, 120,0 },
+ { 5, 5, 0, 0, 9400, 140,0 },
+ { 6, 6, 0, 0, 7460, 380,0 },
+ { 7, 7, 0, 0, 9226, 93,0 },
+ { 8, 8, 0, 0, 4613, 420,0 },
+ { 9, 9, 0, 0, 7286, 4713,0 },
+ { 10, 10, 0, 0, 2280, 746,0 },
+ { 11, 11, 0, 0, 9233, 240,0 },
+ { 12, 12, 0, 0, 346, 153,0 },
+ { 13, 13, 0, 0, 633, 233,0 },
+ { 14, 14, 0, 0, 4660, 1573,0 },
+ { 15, 15, 0, 0, 1166, 400,0 },
+ { 16, 16, 0, 0, 40000, 126,0 },
+ { 17, 17, 0, 0, 40000, 93,0 },
+ { 18, 18, 0, 0, 40000, 93,0 },
+ { 19, 19, 0, 0, 40000, 553,0 },
+ { 20, 20, 0, 0, 40000, 660,0 },
+ { 21, 21, 0, 0, 40000, 73,0 },
+ { 22, 22, 0, 0, 40000, 146,0 },
+ { 23, 23, 0, 0, 40000, 146,0 },
+ { 24, 24, 0, 0, 4026, 100,0 },
+ { 25, 25, 0, 0, 14286, 120,0 },
+ { 26, 26, 0, 0, 9233, 106,0 },
+ { 27, 27, 0, 0, 4480, 100,0 },
+ { 28, 28, 0, 0, 40000, 60,0 },
+ { 29, 29, 0, 0, 40000, 80,0 },
+ { 30, 30, 0, 0, 40000, 80,0 },
+ { 31, 31, 0, 0, 18226, 100,0 },
+ { 32, 32, 0, 0, 40000, 0,0 },
+ { 33, 33, 0, 0, 40000, 80,0 },
+ { 34, 34, 0, 0, 40000, 0,0 },
+ { 35, 35, 0, 0, 40000, 53,0 },
+ { 36, 36, 0, 0, 40000, 0,0 },
+ { 37, 37, 0, 0, 40000, 0,0 },
+ { 38, 38, 0, 0, 40000, 0,0 },
+ { 39, 39, 0, 0, 40000, 160,0 },
+ { 40, 40, 0, 0, 40000, 233,0 },
+ { 41, 41, 0, 0, 40000, 73,0 },
+ { 42, 42, 0, 0, 40000, 233,0 },
+ { 43, 43, 0, 0, 40000, 213,0 },
+ { 44, 44, 0, 0, 1246, 453,0 },
+ { 45, 45, 0, 0, 4580, 786,0 },
+ { 46, 46, 0, 0, 6873, 1246,0 },
+ { 47, 47, 0, 0, 40000, 100,0 },
+ { 48, 48, 0, 0, 40000, 140,0 },
+ { 49, 49, 0, 0, 40000, 393,0 },
+ { 50, 50, 0, 0, 40000, 406,0 },
+ { 51, 51, 0, 0, 40000, 373,0 },
+ { 52, 52, 0, 0, 40000, 0,0 },
+ { 53, 53, 0, 0, 40000, 360,0 },
+ { 54, 54, 0, 0, 1060, 380,0 },
+ { 55, 55, 0, 0, 40000, 80,0 },
+ { 56, 56, 0, 0, 40000, 73,0 },
+ { 57, 57, 0, 0, 40000, 66,0 },
+ { 58, 58, 0, 0, 40000, 60,0 },
+ { 59, 59, 0, 0, 40000, 73,0 },
+ { 60, 60, 0, 0, 40000, 66,0 },
+ { 61, 61, 0, 0, 40000, 86,0 },
+ { 62, 62, 0, 0, 40000, 66,0 },
+ { 63, 63, 0, 0, 40000, 73,0 },
+ { 64, 64, 0, 0, 40000, 80,0 },
+ { 65, 65, 0, 0, 40000, 80,0 },
+ { 66, 66, 0, 0, 40000, 73,0 },
+ { 67, 67, 0, 0, 40000, 73,0 },
+ { 68, 68, 0, 0, 40000, 53,0 },
+ { 69, 69, 0, 0, 40000, 73,0 },
+ { 70, 70, 0, 0, 40000, 126,0 },
+ { 71, 71, 0, 0, 40000, 73,0 },
+ { 72, 72, 0, 0, 40000, 73,0 },
+ { 73, 73, 0, 0, 40000, 73,0 },
+ { 74, 74, 0, 0, 40000, 66,0 },
+ { 75, 75, 0, 0, 40000, 153,0 },
+ { 76, 76, 0, 0, 40000, 153,0 },
+ { 77, 77, 0, 0, 40000, 146,0 },
+ { 78, 78, 0, 0, 40000, 146,0 },
+ { 79, 79, 0, 0, 40000, 66,0 },
+ { 80, 80, 0, 0, 40000, 60,0 },
+ { 81, 81, 0, 0, 40000, 86,0 },
+ { 82, 82, 0, 0, 40000, 73,0 },
+ { 83, 83, 0, 0, 40000, 66,0 },
+ { 84, 84, 0, 0, 40000, 153,0 },
+ { 85, 85, 0, 0, 40000, 233,0 },
+ { 86, 86, 0, 0, 40000, 80,0 },
+ { 87, 87, 0, 0, 40000, 400,0 },
+ { 88, 88, 0, 0, 40000, 1373,0 },
+ { 89, 89, 0, 0, 40000, 193,0 },
+ { 90, 90, 0, 0, 40000, 1273,0 },
+ { 91, 91, 0, 0, 40000, 186,0 },
+ { 92, 92, 0, 0, 40000, 86,0 },
+ { 93, 93, 0, 0, 40000, 286,0 },
+ { 94, 94, 0, 0, 40000, 140,0 },
+ { 95, 95, 0, 0, 7440, 2473,0 },
+ { 96, 96, 0, 0, 40000, 1220,0 },
+ { 97, 97, 0, 0, 4946, 2713,0 },
+ { 98, 98, 0, 0, 40000, 160,0 },
+ { 99, 99, 0, 0, 8966, 406,0 },
+ { 100, 100, 0, 0, 40000, 1353,0 },
+ { 101, 101, 0, 0, 40000, 1306,0 },
+ { 102, 102, 0, 0, 40000, 933,0 },
+ { 103, 103, 0, 0, 9086, 226,0 },
+ { 104, 104, 0, 0, 7233, 326,0 },
+ { 105, 105, 0, 0, 7286, 200,0 },
+ { 106, 106, 0, 0, 14180, 4406,0 },
+ { 107, 107, 0, 0, 1180, 406,0 },
+ { 108, 108, 0, 0, 40000, 66,0 },
+ { 109, 109, 0, 0, 40000, 213,0 },
+ { 110, 110, 0, 0, 40000, 73,0 },
+ { 111, 111, 0, 0, 4606, 413,0 },
+ { 112, 112, 0, 0, 613, 240,0 },
+ { 113, 113, 0, 0, 1166, 400,0 },
+ { 114, 114, 0, 0, 200, 353,0 },
+ { 115, 115, 0, 0, 4553, 1480,0 },
+ { 116, 116, 0, 0, 3740, 1260,0 },
+ { 117, 117, 0, 0, 7240, 2300,0 },
+ { 118, 118, 0, 0, 3020, 73,0 },
+ { 119, 119, 0, 0, 1626, 800,0 },
+ { 120, 120, 0, 0, 2466, 620,0 },
+ { 121, 121, 0, 0, 12053, 3160,0 },
+ { 122, 122, 0, 0, 466, 120,0 },
+ { 123, 123, 0, 0, 1000, 320,0 },
+ { 124, 124, 0, 0, 380, 60,0 },
+ { 125, 125, 0, 0, 40000, 200,0 },
+ { 126, 126, 0, 0, 560, 86,0 },
+ { 127, 127, 35, 0, 386, 160,0 },
+ { 128, 128, 52, 0, 126, 26,0 },
+ { 129, 129, 48, 0, 286, 126,0 },
+ { 130, 130, 58, 0, 173, 93,0 },
+ { 129, 129, 60, 0, 286, 126,0 },
+ { 131, 131, 47, 0, 520, 200,0 },
+ { 132, 132, 43, 0, 173, 93,0 },
+ { 131, 131, 49, 0, 520, 200,0 },
+ { 133, 133, 43, 0, 160, 80,0 },
+ { 131, 131, 51, 0, 526, 206,0 },
+ { 134, 134, 43, 0, 1860, 653,0 },
+ { 131, 131, 54, 0, 520, 200,0 },
+ { 131, 131, 57, 0, 520, 200,0 },
+ { 135, 135, 72, 0, 1860, 633,0 },
+ { 131, 131, 60, 0, 506, 200,0 },
+ { 136, 136, 76, 0, 1566, 546,0 },
+ { 137, 137, 84, 0, 1340, 466,0 },
+ { 138, 138, 36, 0, 1220, 433,0 },
+ { 139, 139, 65, 0, 293, 133,0 },
+ { 140, 140, 84, 0, 1333, 460,0 },
+ { 141, 141, 83, 0, 220, 113,0 },
+ { 135, 135, 84, 0, 1366, 473,0 },
+ { 142, 142, 24, 0, 1893, 633,0 },
+ { 136, 136, 77, 0, 1586, 553,0 },
+ { 143, 143, 60, 0, 173, 93,0 },
+ { 144, 144, 65, 0, 213, 126,0 },
+ { 145, 145, 59, 0, 173, 0,0 },
+ { 146, 146, 51, 0, 173, 100,0 },
+ { 147, 147, 45, 0, 260, 206,0 },
+ { 148, 148, 71, 0, 433, 180,0 },
+ { 149, 149, 60, 0, 280, 26,0 },
+ { 150, 150, 58, 0, 500, 186,0 },
+ { 151, 151, 53, 0, 513, 200,0 },
+ { 152, 152, 64, 0, 220, 86,0 },
+ { 153, 153, 71, 0, 106, 46,0 },
+ { 154, 154, 61, 0, 993, 340,0 },
+ { 155, 155, 61, 0, 1906, 640,0 },
+ { 156, 156, 44, 0, 206, 86,0 },
+ { 157, 157, 40, 0, 586, 140,0 },
+ { 158, 158, 69, 0, 126, 140,0 },
+ { 159, 159, 68, 0, 126, 140,0 },
+ { 160, 160, 63, 0, 146, 166,0 },
+ { 161, 161, 74, 0, 280, 100,0 },
+ { 162, 162, 60, 0, 1026, 320,0 },
+ { 163, 163, 80, 0, 226, 100,0 },
+ { 164, 164, 64, 0, 2713, 913,0 },
+ { 165, 165, 72, 0, 120, 66,0 },
+ { 166, 166, 73, 0, 386, 80,0 },
+ { 167, 167, 70, 0, 553, 306,0 },
+ { 168, 168, 68, 0, 126, 140,0 },
+ { 169, 169, 48, 0, 386, 373,0 },
+ { 131, 131, 53, 0, 520, 206,0 },
+ { 170, 170, 0, 0, 40000, 0,0 },
+ { 171, 171, 0, 0, 40000, 73,0 },
+ { 172, 173, 0, 4, 5886, 100,0 },
+ { 174, 175, 0, 4, 6913, 0,0 },
+ { 176, 177, 0, 4, 4873, 0,0 },
+ { 178, 178, 0, 0, 40000, 0,0 },
+ { 179, 180, 0, 4, 4653, 433,0 },
+ { 181, 181, 0, 0, 2280, 746,0 },
+ { 182, 182, 0, 0, 40000, 0,0 },
+ { 183, 184, 0, 4, 626, 0,0 },
+ { 185, 186, 0, 4, 4653, 1546,0 },
+ { 187, 187, 0, 0, 1166, 400,0 },
+ { 188, 189, 0, 4, 40000, 60,0 },
+ { 190, 191, 0, 4, 40000, 60,0 },
+ { 192, 193, 0, 4, 40000, 73,0 },
+ { 194, 194, 0, 0, 40000, 73,0 },
+ { 195, 196, 0, 4, 40000, 66,0 },
+ { 197, 198, 0, 4, 40000, 86,0 },
+ { 199, 200, 0, 4, 40000, 66,0 },
+ { 201, 202, 0, 4, 3713, 100,0 },
+ { 203, 204, 0, 4, 14753, 126,0 },
+ { 205, 206, 0, 4, 9286, 146,0 },
+ { 207, 208, 0, 4, 14713, 126,0 },
+ { 209, 210, 0, 4, 4653, 0,0 },
+ { 211, 212, 0, 4, 40000, 66,0 },
+ { 213, 213, 0, 0, 40000, 73,0 },
+ { 214, 215, 0, 4, 626, 0,0 },
+ { 216, 217, 0, 4, 4066, 100,0 },
+ { 218, 219, 0, 4, 14586, 193,0 },
+ { 220, 221, 0, 4, 2813, 106,0 },
+ { 222, 223, 0, 4, 500, 0,0 },
+ { 224, 224, 0, 0, 40000, 0,0 },
+ { 225, 226, 0, 4, 7993, 93,0 },
+ { 227, 227, 0, 0, 40000, 0,0 },
+ { 228, 228, 0, 0, 40000, 133,0 },
+ { 229, 230, 0, 4, 720, 213,0 },
+ { 231, 232, 0, 4, 40000, 146,0 },
+ { 233, 234, 0, 4, 40000, 0,0 },
+ { 235, 236, 0, 4, 1000, 340,0 },
+ { 235, 237, 0, 4, 3280, 1120,0 },
+ { 46, 238, 0, 4, 6920, 0,0 },
+ { 239, 240, 0, 4, 40000, 140,0 },
+ { 241, 242, 0, 4, 40000, 146,0 },
+ { 243, 243, 0, 0, 40000, 100,0 },
+ { 244, 244, 0, 0, 40000, 60,0 },
+ { 245, 245, 0, 0, 40000, 73,0 },
+ { 246, 247, 0, 4, 720, 106,0 },
+ { 248, 249, 0, 4, 40000, 126,0 },
+ { 250, 250, 0, 0, 40000, 0,0 },
+ { 251, 251, 0, 0, 40000, 126,0 },
+ { 252, 253, 0, 4, 40000, 66,0 },
+ { 254, 255, 0, 4, 40000, 93,0 },
+ { 256, 257, 0, 4, 40000, 73,0 },
+ { 258, 259, 0, 4, 40000, 86,0 },
+ { 260, 261, 0, 4, 40000, 93,0 },
+ { 262, 263, 0, 4, 40000, 80,0 },
+ { 264, 265, 0, 4, 40000, 200,0 },
+ { 266, 267, 0, 4, 40000, 73,0 },
+ { 268, 269, 0, 4, 40000, 80,0 },
+ { 270, 271, 0, 4, 40000, 73,0 },
+ { 272, 273, 0, 4, 40000, 126,0 },
+ { 274, 275, 0, 4, 40000, 100,0 },
+ { 276, 276, 0, 0, 40000, 113,0 },
+ { 277, 278, 0, 4, 40000, 186,0 },
+ { 279, 280, 0, 4, 40000, 160,0 },
+ { 281, 282, 0, 4, 40000, 206,0 },
+ { 283, 283, 0, 0, 40000, 80,0 },
+ { 284, 285, 0, 4, 40000, 73,0 },
+ { 286, 287, 0, 4, 40000, 73,0 },
+ { 288, 288, 0, 0, 40000, 93,0 },
+ { 289, 290, 0, 4, 40000, 66,0 },
+ { 291, 292, 0, 4, 40000, 153,0 },
+ { 293, 294, 0, 4, 40000, 153,0 },
+ { 295, 296, 0, 4, 40000, 320,0 },
+ { 88, 297, 0, 4, 40000, 1280,0 },
+ { 298, 299, 0, 4, 40000, 266,0 },
+ { 300, 301, 0, 4, 40000, 1180,0 },
+ { 302, 302, 0, 0, 40000, 286,0 },
+ { 303, 303, 0, 0, 40000, 140,0 },
+ { 304, 304, 0, 0, 13246, 2473,0 },
+ { 305, 306, 0, 4, 40000, 1073,0 },
+ { 307, 307, 0, 0, 9233, 240,0 },
+ { 308, 308, 0, 0, 1186, 406,0 },
+ { 309, 309, 0, 0, 40000, 1306,0 },
+ { 310, 310, 0, 0, 40000, 933,0 },
+ { 311, 312, 0, 4, 9146, 240,0 },
+ { 313, 314, 0, 4, 7306, 326,0 },
+ { 315, 316, 0, 4, 3586, 326,0 },
+ { 317, 318, 0, 4, 7180, 0,0 },
+ { 107, 319, 0, 4, 1180, 406,0 },
+ { 108, 320, 0, 4, 40000, 66,0 },
+ { 109, 321, 0, 4, 720, 213,0 },
+ { 322, 323, 0, 4, 40000, 73,0 },
+ { 324, 325, 0, 4, 613, 246,0 },
+ { 326, 327, 0, 4, 1213, 386,0 },
+ { 328, 328, 0, 0, 173, 106,0 },
+ { 329, 329, 0, 0, 966, 333,0 },
+ { 330, 331, 0, 4, 1906, 320,0 },
+ { 332, 332, 0, 0, 3120, 73,0 },
+ { 333, 333, 0, 0, 226, 73,0 },
+ { 334, 334, 0, 0, 6600, 806,0 },
+ { 335, 335, 0, 0, 273, 60,0 },
+ { 336, 336, 0, 0, 12053, 660,0 },
+ { 337, 337, 0, 0, 40000, 240,0 },
+ { 338, 339, 0, 6, 6, 0,0 },
+ { 340, 341, 0, 4, 560, 0,0 },
+ { 342, 342, 35, 0, 40000, 0,0 },
+ { 343, 343, 0, 0, 180, 100,0 },
+ { 344, 344, 35, 0, 340, 146,0 },
+ { 345, 345, 35, 0, 213, 33,0 },
+ { 346, 346, 50, 0, 306, 20,0 },
+ { 347, 347, 18, 0, 420, 146,0 },
+ { 348, 348, 72, 0, 173, 86,0 },
+ { 349, 349, 74, 0, 160, 93,0 },
+ { 350, 350, 35, 0, 380, 146,0 },
+ { 351, 351, 16, 0, 1206, 420,0 },
+ { 352, 352, 0, 2, 6, 0,0 },
+ { 353, 353, 38, 0, 200, 106,0 },
+ { 354, 354, 38, 0, 346, 146,0 },
+ { 355, 355, 31, 0, 406, 20,0 },
+ { 355, 355, 35, 0, 406, 66,0 },
+ { 355, 355, 38, 0, 406, 66,0 },
+ { 355, 355, 41, 0, 406, 66,0 },
+ { 355, 355, 45, 0, 306, 73,0 },
+ { 355, 355, 50, 0, 306, 73,0 },
+ { 356, 356, 36, 0, 1373, 493,0 },
+ { 357, 357, 36, 0, 146, 33,0 },
+ { 358, 358, 48, 0, 213, 86,0 },
+ { 358, 358, 36, 0, 246, 86,0 },
+ { 359, 359, 36, 0, 113, 0,0 },
+ { 360, 360, 0, 0, 133, 40,0 },
+ { 361, 361, 61, 0, 180, 26,0 },
+ { 362, 362, 96, 0, 706, 266,0 },
+ { 363, 363, 38, 0, 520, 193,0 },
+ { 127, 127, 16, 0, 620, 233,0 },
+ { 364, 365, 18, 4, 200, 0,0 },
+ { 366, 366, 30, 0, 406, 246,0 },
+ { 367, 368, 35, 4, 200, 0,0 },
+ { 129, 129, 0, 0, 353, 153,0 },
+ { 369, 369, 0, 0, 213, 13,0 },
+ { 370, 370, 88, 0, 333, 113,0 },
+ { 371, 371, 88, 0, 140, 73,0 },
+ { 372, 372, 79, 0, 2540, 1040,0 },
+ { 135, 135, 14, 0, 9213, 3066,0 },
+ { 373, 373, 46, 0, 1093, 60,0 },
+ { 374, 375,129, 4, 1200, 433,0 },
+ { 376, 376, 58, 0, 1600, 726,0 },
+ { 377, 377,164, 0, 526, 820,0 },
+ { 378, 378,142, 0, 9153, 3073,0 },
+ { 379, 379, 9, 0, 200, 100,0 },
+ { 380, 381, 35, 4, 2353, 813,0 },
+ { 382, 382, 28, 0, 1060, 120,0 },
+ { 383, 383, 46, 0, 953, 20,0 },
+ { 384, 384, 60, 0, 440, 160,0 },
+ { 384, 384, 54, 0, 513, 180,0 },
+ { 385, 385, 72, 0, 253, 120,0 },
+ { 385, 385, 67, 0, 253, 113,0 },
+ { 385, 385, 60, 0, 253, 106,0 },
+ { 386, 386, 1, 0, 966, 613,0 },
+ { 387, 387, 77, 0, 340, 86,0 },
+ { 387, 387, 72, 0, 340, 86,0 },
+ { 388, 388, 90, 0, 213, 86,0 },
+ { 389, 389, 39, 0, 266, 73,0 },
+ { 390, 390, 36, 0, 593, 73,0 },
+ { 391, 392, 35, 4, 173, 46,0 },
+ { 391, 393, 35, 4, 460, 66,0 },
+ { 394, 394, 60, 0, 173, 20,0 },
+ { 328, 328, 7, 0, 173, 0,0 },
+ { 395, 395, 90, 0, 193, 20,0 },
+ { 396, 396, 90, 0, 793, 40,0 },
+ { 397, 397, 35, 0, 253, 86,0 },
+ { 398, 399, 5, 4, 1913, 226,0 },
+ { 400, 400,103, 0, 713, 273,0 },
+ { 401, 401, 3, 0, 100, 0,0 },
+ { 169, 169, 1, 0, 466, 413,0 },
+ { 131, 131, 0, 0, 613, 226,0 },
+ { 402, 402, 36, 0, 273, 53,0 },
+ { 403, 403, 60, 0, 40000, 73,0 },
+ { 404, 404, 37, 0, 1193, 426,0 },
+ { 405, 405, 36, 0, 406, 20,0 },
+ { 406, 406, 32, 0, 146, 73,0 },
+ { 407, 407, 50, 0, 40000, 0,0 },
+ { 408, 408, 50, 0, 793, 346,0 },
+ { 409, 409, 83, 0, 120, 13,0 },
+ { 410, 410, 72, 0, 433, 0,0 },
+ { 148, 148, 59, 0, 513, 200,0 },
+ { 411, 411, 64, 0, 173, 93,0 },
+ { 411, 411, 60, 0, 173, 93,0 },
+ { 412, 412, 72, 0, 160, 93,0 },
+ { 412, 412, 62, 0, 173, 93,0 },
+ { 413, 413, 83, 0, 773, 60,0 },
+ { 414, 414, 0, 0, 40000, 80,0 },
+ { 415, 415, 0, 0, 40000, 0,0 },
+ { 416, 416, 0, 0, 40000, 73,0 },
+ { 417, 417, 0, 0, 40000, 86,0 },
+ { 418, 418, 0, 0, 40000, 0,0 },
+ { 419, 419, 0, 0, 3440, 100,0 },
+ { 420, 420, 0, 0, 3913, 420,0 },
+ { 421, 421, 0, 0, 13620, 4640,0 },
+ { 422, 422, 0, 0, 9233, 240,0 },
+ { 423, 423, 0, 0, 633, 233,0 },
+ { 424, 424, 0, 0, 4660, 1573,0 },
+ { 425, 425, 0, 0, 4480, 1413,0 },
+ { 426, 426, 0, 0, 40000, 0,0 },
+ { 427, 427, 0, 0, 40000, 86,0 },
+ { 428, 428, 60, 2, 6, 0,0 },
+ { 429, 429, 73, 0, 593, 86,0 },
+ { 429, 429, 74, 0, 593, 86,0 },
+ { 429, 429, 80, 0, 593, 86,0 },
+ { 429, 429, 84, 0, 593, 86,0 },
+ { 429, 429, 92, 0, 520, 86,0 },
+ { 430, 430, 81, 0, 786, 80,0 },
+ { 430, 430, 83, 0, 786, 80,0 },
+ { 430, 430, 95, 0, 680, 80,0 },
+ { 431, 431, 35, 0, 593, 140,0 },
+ { 432, 432, 60, 0, 213, 133,0 },
+ { 357, 357, 59, 0, 113, 0,0 },
+ { 432, 432, 44, 0, 213, 133,0 },
+ { 433, 433, 41, 0, 713, 273,0 },
+ { 434, 434, 97, 0, 113, 46,0 },
+ { 433, 433, 44, 0, 513, 206,0 },
+ { 433, 433, 48, 0, 506, 200,0 },
+ { 435, 435, 96, 0, 700, 86,0 },
+ { 433, 433, 51, 0, 520, 200,0 },
+ { 433, 433, 54, 0, 513, 206,0 },
+ { 436, 436, 40, 0, 1506, 793,0 },
+ { 433, 433, 57, 0, 380, 160,0 },
+ { 437, 437, 58, 0, 1600, 726,0 },
+ { 438, 438, 97, 0, 233, 106,0 },
+ { 439, 439, 50, 0, 186, 93,0 },
+ { 437, 437, 60, 0, 1573, 713,0 },
+ { 440, 440, 53, 0, 180, 73,0 },
+ { 441, 441, 46, 0, 173, 126,0 },
+ { 440, 440, 57, 0, 180, 40,0 },
+ { 442, 442, 42, 0, 640, 240,0 },
+ { 442, 442, 37, 0, 633, 233,0 },
+ { 443, 443, 41, 0, 626, 240,0 },
+ { 443, 443, 37, 0, 620, 233,0 },
+ { 444, 444, 77, 0, 173, 40,0 },
+ { 444, 444, 72, 0, 173, 40,0 },
+ { 445, 445, 70, 0, 233, 100,0 },
+ { 445, 445, 90, 0, 233, 93,0 },
+ { 446, 446, 46, 0, 133, 73,0 },
+ { 447, 447, 48, 0, 333, 73,0 },
+ { 448, 448, 85, 0, 106, 0,0 },
+ { 449, 449, 66, 0, 180, 26,0 },
+ { 449, 449, 61, 0, 180, 26,0 },
+ { 450, 450, 41, 0, 200, 66,0 },
+ { 451, 451, 41, 0, 253, 66,0 },
+ { 452, 452, 81, 0, 253, 26,0 },
+ { 400, 400, 81, 0, 820, 306,0 },
+ { 400, 400, 76, 0, 813, 300,0 },
+ { 359, 359, 60, 0, 100, 0,0 },
+ { 453, 453, 53, 0, 40000, 0,0 },
+ { 454, 454, 0, 2, 6, 0,0 },
+ { 455, 455, 0, 0, 200, 20,0 },
+ { 456, 456, 0, 0, 4480, 100,0 },
+ { 457, 457, 0, 0, 1180, 406,0 },
+ { 458, 458, 0, 0, 40000, 86,0 },
+ { 459, 459, 0, 0, 40000, 73,0 },
+ { 460, 460, 0, 0, 3700, 66,0 },
+ { 461, 461, 0, 0, 40000, 0,0 },
+ { 462, 462, 0, 0, 6746, 2606,0 },
+ { 463, 463, 0, 0, 40000, 213,0 },
+ { 464, 464, 0, 0, 40000, 66,0 },
+ { 465, 465, 0, 0, 40000, 100,0 },
+ { 466, 466, 0, 0, 40000, 100,0 },
+ { 467, 467, 0, 0, 5840, 806,0 },
+ { 468, 468, 0, 0, 40000, 0,0 },
+ { 469, 469, 0, 0, 40000, 0,0 },
+ { 470, 470, 0, 0, 40000, 73,0 },
+ { 471, 471, 0, 0, 40000, 133,0 },
+ { 472, 472, 0, 0, 3320, 800,0 },
+ { 473, 473, 0, 0, 40000, 173,0 },
+ { 474, 474, 0, 0, 40000, 193,0 },
+ { 475, 475, 0, 0, 2373, 800,0 },
+ { 476, 476, 0, 0, 40000, 4986,0 },
+ { 477, 477, 0, 0, 1180, 413,0 },
+ { 478, 478, 0, 0, 3673, 1200,0 },
+ { 479, 479, 0, 0, 973, 800,0 },
+ { 480, 480, 0, 0, 7233, 2286,0 },
+ { 481, 481, 0, 0, 40000, 73,0 },
+ { 482, 482, 0, 0, 2526, 73,0 },
+ { 483, 483, 0, 0, 393, 126,0 },
+ { 484, 484, 0, 0, 40000, 200,0 },
+ { 485, 485, 0, 0, 40000, 546,0 },
+ { 486, 486, 0, 0, 1186, 413,0 },
+ { 487, 487, 0, 0, 14166, 320,0 },
+ { 488, 488, 0, 0, 8326, 646,0 },
+ { 489, 489, 0, 0, 513, 206,0 },
+ { 490, 490, 0, 0, 40000, 93,0 },
+ { 491, 491, 50, 0, 1406, 353,0 },
+ { 492, 492, 37, 0, 1040, 400,0 },
+ { 493, 493, 39, 0, 406, 73,0 },
+ { 494, 494, 39, 0, 3746, 860,0 },
+ { 495, 495, 86, 0, 2133, 173,0 },
+ { 496, 496, 43, 0, 140, 66,0 },
+ { 127, 127, 24, 0, 513, 206,0 },
+ { 127, 127, 29, 0, 520, 206,0 },
+ { 497, 497, 50, 0, 340, 20,0 },
+ { 498, 498, 30, 0, 5306, 1266,0 },
+ { 498, 498, 33, 0, 3773, 886,0 },
+ { 498, 498, 38, 0, 3746, 860,0 },
+ { 498, 498, 42, 0, 3793, 906,0 },
+ { 499, 499, 24, 0, 266, 0,0 },
+ { 499, 499, 27, 0, 260, 153,0 },
+ { 499, 499, 29, 0, 260, 153,0 },
+ { 499, 499, 32, 0, 260, 153,0 },
+ { 500, 500, 32, 0, 106, 0,0 },
+ { 501, 501, 53, 0, 373, 186,0 },
+ { 501, 501, 57, 0, 380, 193,0 },
+ { 502, 502, 60, 0, 286, 133,0 },
+ { 503, 503, 55, 0, 460, 126,0 },
+ { 486, 486, 85, 0, 813, 293,0 },
+ { 504, 504, 90, 0, 1580, 546,0 },
+ { 505, 505, 84, 0, 246, 120,0 },
+ { 506, 506, 48, 0, 826, 646,0 },
+ { 507, 507, 48, 0, 266, 213,0 },
+ { 132, 132, 72, 0, 126, 66,0 },
+ { 508, 508, 72, 0, 106, 0,0 },
+ { 509, 509, 72, 0, 100, 0,0 },
+ { 510, 510, 63, 0, 1860, 633,0 },
+ { 510, 510, 65, 0, 1853, 633,0 },
+ { 511, 511, 79, 0, 1573, 553,0 },
+ { 512, 512, 38, 0, 520, 793,0 },
+ { 513, 513, 94, 0, 380, 160,0 },
+ { 514, 514, 87, 0, 433, 306,0 },
+ { 514, 514, 94, 0, 380, 273,0 },
+ { 515, 515, 80, 0, 546, 273,0 },
+ { 516, 516, 47, 0, 506, 200,0 },
+ { 517, 517, 61, 0, 286, 133,0 },
+ { 517, 517, 68, 0, 246, 120,0 },
+ { 518, 518, 61, 0, 513, 206,0 },
+ { 518, 518, 68, 0, 433, 180,0 },
+ { 499, 499, 60, 0, 220, 133,0 },
+ { 519, 519, 60, 0, 153, 46,0 },
+ { 520, 520, 36, 0, 200, 20,0 },
+ { 520, 520, 60, 0, 173, 20,0 },
+ { 521, 521, 60, 0, 173, 20,0 },
+ { 522, 522, 68, 0, 126, 26,0 },
+ { 523, 523, 71, 0, 160, 186,0 },
+ { 523, 523, 72, 0, 160, 186,0 },
+ { 524, 524,101, 0, 966, 353,0 },
+ { 525, 525, 36, 0, 3333, 480,0 },
+ { 526, 526, 25, 0, 40000, 2293,0 },
+ { 527, 527, 37, 0, 2106, 426,0 },
+ { 528, 528, 36, 0, 720, 266,0 },
+ { 528, 528, 41, 0, 713, 266,0 },
+ { 529, 529, 84, 0, 173, 60,0 },
+ { 530, 530, 54, 0, 40000, 0,0 },
+ { 481, 481, 48, 0, 40000, 73,0 },
+ { 531, 531, 0, 0, 10060, 1266,0 },
+ { 532, 532, 0, 0, 4600, 606,0 },
+ { 533, 533, 0, 0, 40000, 253,0 },
+ { 534, 534, 0, 0, 40000, 73,0 },
+ { 535, 535, 0, 0, 40000, 66,0 },
+ { 536, 536, 0, 0, 40000, 80,0 },
+ { 537, 537, 0, 0, 9413, 1393,0 },
+ { 538, 538, 0, 0, 9000, 66,0 },
+ { 539, 539, 0, 0, 40000, 0,0 },
+ { 540, 540, 0, 0, 40000, 80,0 },
+ { 541, 541, 0, 0, 40000, 120,0 },
+ { 542, 542, 0, 0, 253, 73,0 },
+ { 543, 543, 0, 0, 40000, 73,0 },
+ { 544, 544, 0, 0, 18280, 800,0 },
+ { 545, 545, 0, 0, 40000, 1133,0 },
+ { 546, 546, 0, 0, 40000, 1226,0 },
+ { 547, 547, 0, 0, 40000, 153,0 },
+ { 135, 135, 49, 0, 3633, 1186,0 },
+ { 548, 548, 35, 0, 2193, 80,0 },
+ { 549, 549, 41, 0, 73, 0,0 },
+ { 366, 366, 38, 0, 406, 246,0 },
+ { 550, 550, 39, 0, 106, 20,0 },
+ { 551, 551, 49, 0, 200, 133,0 },
+ { 408, 408, 59, 0, 780, 326,0 },
+ { 552, 552, 24, 0, 40000, 0,0 },
+ { 552, 552, 27, 0, 40000, 0,0 },
+ { 552, 552, 29, 0, 40000, 0,0 },
+ { 552, 552, 32, 0, 40000, 0,0 },
+ { 553, 553, 84, 0, 200, 33,0 },
+ { 512, 512, 79, 0, 346, 460,0 },
+ { 554, 554, 61, 0, 400, 126,0 },
+ { 554, 554, 68, 0, 353, 120,0 },
+ { 555, 555, 36, 0, 146, 86,0 },
+ { 555, 555, 60, 0, 113, 0,0 },
+ { 556, 556, 36, 0, 273, 53,0 },
+ { 115, 115, 37, 0, 4580, 1513,0 },
+ { 557, 557, 0, 0, 3806, 73,0 },
+ { 558, 558, 0, 0, 40000, 0,0 },
+ { 559, 559, 0, 0, 40000, 66,0 },
+ { 560, 560, 0, 0, 5886, 133,0 },
+ { 561, 561, 0, 0, 253, 26,0 },
+ { 562, 562, 0, 0, 3246, 753,0 },
+ { 563, 563, 0, 0, 40000, 100,0 },
+ { 564, 564, 0, 0, 1620, 366,0 },
+ { 565, 565, 0, 0, 40000, 0,0 },
+ { 566, 566, 0, 0, 40000, 0,0 },
+ { 567, 567, 0, 0, 40000, 0,0 },
+ { 568, 568, 0, 0, 40000, 80,0 },
+ { 569, 569, 0, 0, 760, 340,0 },
+ { 570, 570, 0, 0, 40000, 0,0 },
+ { 571, 571, 0, 0, 40000, 0,0 },
+ { 572, 572, 0, 0, 40000, 0,0 },
+ { 356, 356, 0, 0, 1893, 646,0 },
+ { 573, 573, 0, 0, 40000, 93,0 },
+ { 574, 574, 0, 0, 40000, 93,0 },
+ { 575, 575, 0, 0, 40000, 200,0 },
+ { 576, 576, 0, 0, 40000, 200,0 },
+ { 577, 577, 0, 0, 40000, 126,0 },
+ { 578, 578, 0, 0, 40000, 353,0 },
+ { 579, 579, 0, 0, 40000, 346,0 },
+ { 580, 580, 0, 0, 40000, 353,0 },
+ { 581, 581, 0, 0, 40000, 100,0 },
+ { 582, 582, 0, 0, 40000, 133,0 },
+ { 583, 583, 0, 0, 2286, 713,0 },
+ { 584, 584, 0, 0, 40000, 193,0 },
+ { 585, 585, 0, 0, 40000, 0,0 },
+ { 516, 516, 0, 0, 633, 240,0 },
+ { 586, 586, 0, 0, 40000, 73,0 },
+ { 587, 587, 0, 0, 40000, 73,0 },
+ { 588, 588, 0, 0, 40000, 73,0 },
+ { 498, 498, 26, 0, 5293, 1253,0 },
+ { 494, 494, 35, 0, 3800, 913,0 },
+ { 350, 350, 41, 0, 380, 153,0 },
+ { 353, 353, 48, 0, 173, 100,0 },
+ { 354, 354, 67, 0, 246, 120,0 },
+ { 502, 502, 24, 0, 340, 146,0 },
+ { 346, 346, 36, 0, 406, 73,0 },
+ { 346, 346, 38, 0, 406, 20,0 },
+ { 346, 346, 40, 0, 406, 73,0 },
+ { 346, 346, 42, 0, 406, 20,0 },
+ { 346, 346, 44, 0, 306, 20,0 },
+ { 510, 510, 55, 0, 1866, 646,0 },
+ { 346, 346, 46, 0, 306, 20,0 },
+ { 136, 136, 80, 0, 1600, 573,0 },
+ { 486, 486, 24, 0, 1193, 426,0 },
+ { 153, 153, 50, 0, 106, 40,0 },
+ { 346, 346, 24, 0, 540, 73,0 },
+ { 516, 516, 31, 0, 626, 240,0 },
+ { 498, 498, 35, 0, 3760, 880,0 },
+ { 517, 517, 60, 0, 286, 133,0 },
+ { 530, 530, 36, 0, 40000, 0,0 },
+ { 530, 530, 48, 0, 40000, 0,0 },
+ { 589, 589, 0, 0, 40000, 0,0 },
+ { 139, 139, 76, 0, 253, 106,0 },
+ { 156, 156, 48, 0, 206, 80,0 },
+ { 157, 157, 48, 0, 426, 106,0 },
+ { 165, 165, 69, 0, 120, 66,0 },
+ { 167, 167, 75, 0, 546, 306,0 },
+ { 590, 590, 0, 0, 40000, 0,0 },
+ { 591, 591, 0, 0, 15486, 1580,0 },
+ { 592, 592, 0, 0, 3446, 106,0 },
+ { 593, 593, 0, 0, 1926, 146,0 },
+ { 594, 594, 0, 0, 7293, 2380,0 },
+ { 595, 595, 0, 0, 7613, 1566,0 },
+ { 596, 596, 0, 0, 1153, 460,0 },
+ { 597, 597, 0, 0, 1166, 400,0 },
+ { 598, 598, 0, 0, 40000, 73,0 },
+ { 599, 599, 0, 0, 40000, 766,0 },
+ { 600, 600, 0, 0, 40000, 80,0 },
+ { 601, 601, 0, 0, 1840, 513,0 },
+ { 602, 602, 0, 0, 40000, 0,0 },
+ { 603, 603, 0, 0, 4480, 733,0 },
+ { 604, 604, 0, 0, 18226, 786,0 },
+ { 605, 605, 0, 0, 4333, 233,0 },
+ { 606, 606, 0, 0, 40000, 106,0 },
+ { 607, 607, 0, 0, 40000, 366,0 },
+ { 608, 608, 0, 0, 40000, 200,0 },
+ { 609, 609, 0, 0, 713, 200,0 },
+ { 610, 610, 0, 0, 8866, 1366,0 },
+ { 611, 611, 0, 0, 2300, 73,0 },
+ { 612, 612, 0, 0, 40000, 126,0 },
+ { 613, 613, 0, 0, 40000, 1413,0 },
+ { 614, 614, 0, 0, 40000, 333,0 },
+ { 615, 615, 0, 0, 40000, 333,0 },
+ { 616, 616, 0, 0, 40000, 26,0 },
+ { 617, 617, 0, 0, 40000, 40,0 },
+ { 618, 618, 0, 0, 4240, 353,0 },
+ { 619, 619, 0, 0, 40000, 0,0 },
+ { 620, 620, 0, 0, 40000, 73,0 },
+ { 621, 621, 0, 0, 9020, 60,0 },
+ { 622, 622, 0, 0, 3020, 0,0 },
+ { 623, 623, 0, 0, 40000, 60,0 },
+ { 624, 624, 0, 0, 40000, 73,0 },
+ { 625, 625, 0, 0, 40000, 60,0 },
+ { 626, 626, 0, 0, 40000, 53,0 },
+ { 627, 627, 0, 0, 40000, 0,0 },
+ { 628, 628, 0, 0, 40000, 66,0 },
+ { 629, 629, 0, 0, 40000, 66,0 },
+ { 630, 630, 0, 0, 5913, 426,0 },
+ { 631, 631, 0, 0, 40000, 246,0 },
+ { 632, 632, 0, 0, 40000, 206,0 },
+ { 633, 633, 0, 0, 40000, 0,0 },
+ { 634, 634, 0, 0, 2453, 780,0 },
+ { 635, 635, 0, 0, 4740, 240,0 },
+ { 636, 636, 0, 0, 1840, 353,0 },
+ { 637, 637, 0, 0, 40000, 86,0 },
+ { 638, 638, 0, 0, 3446, 1786,0 },
+ { 346, 346, 0, 0, 540, 20,0 },
+ { 639, 639, 0, 0, 7406, 2486,0 },
+ { 404, 404, 0, 0, 1220, 466,0 },
+ { 506, 506, 0, 0, 1000, 813,0 },
+ { 639, 639, 60, 0, 2666, 913,0 },
+ { 639, 639, 79, 0, 1366, 486,0 },
+ { 640, 640, 65, 0, 2053, 646,0 },
+ { 486, 486, 31, 0, 1206, 440,0 },
+ { 486, 486, 36, 0, 1200, 433,0 },
+ { 640, 640, 72, 0, 1713, 520,0 },
+ { 136, 136, 79, 0, 1580, 560,0 },
+ { 148, 148, 57, 0, 520, 206,0 },
+ { 150, 150, 53, 0, 500, 193,0 },
+ { 641, 641, 84, 0, 226, 66,0 },
+ { 520, 520, 66, 0, 173, 20,0 },
+ { 642, 642, 31, 0, 40000, 113,0 },
+ { 642, 642, 29, 0, 40000, 113,0 },
+ { 356, 356, 31, 0, 1366, 486,0 },
+ { 356, 356, 19, 0, 1866, 633,0 },
+ { 643, 643, 31, 0, 40000, 73,0 },
+ { 643, 643, 29, 0, 40000, 73,0 },
+ { 644, 644, 31, 0, 2286, 400,0 },
+ { 644, 644, 35, 0, 2313, 420,0 },
+ { 644, 644, 40, 0, 2353, 433,0 },
+ { 644, 644, 47, 0, 1860, 346,0 },
+ { 516, 516, 32, 0, 626, 240,0 },
+ { 516, 516, 43, 0, 506, 200,0 },
+ { 495, 495, 26, 0, 3180, 240,0 },
+ { 495, 495, 44, 0, 2553, 206,0 },
+ { 496, 496, 26, 0, 160, 73,0 },
+ { 496, 496, 51, 0, 146, 66,0 },
+ { 496, 496, 39, 0, 160, 73,0 },
+ { 495, 495, 30, 0, 3180, 240,0 },
+ { 645, 645, 44, 0, 1880, 653,0 },
+ { 645, 645, 43, 0, 1886, 653,0 },
+ { 646, 646, 0, 0, 2393, 833,0 },
+ { 647, 647, 0, 0, 4693, 26,0 },
+ { 648, 648, 0, 0, 2306, 773,0 },
+ { 649, 649, 0, 0, 40000, 120,0 },
+ { 650, 650, 0, 0, 40000, 66,0 },
+ { 651, 651, 0, 0, 5866, 1206,0 },
+ { 652, 652, 0, 0, 40000, 426,0 },
+ { 653, 653, 0, 0, 1873, 633,0 },
+ { 654, 654, 0, 0, 40000, 66,0 },
+ { 655, 655, 0, 0, 40000, 73,0 },
+ { 656, 656, 0, 0, 40000, 73,0 },
+ { 657, 657, 0, 0, 40000, 0,0 },
+ { 658, 658, 0, 0, 2040, 380,0 },
+ { 659, 659, 0, 0, 40000, 73,0 },
+ { 660, 660, 0, 0, 3720, 1260,0 },
+ { 661, 661, 0, 0, 4080, 1046,0 },
+ { 662, 662, 0, 0, 8693, 4666,0 },
+ { 663, 663, 0, 0, 1926, 73,0 },
+ { 664, 664, 0, 0, 8326, 646,0 },
+ { 665, 665, 0, 0, 40000, 240,0 },
+ { 666, 666, 0, 0, 40000, 226,0 },
+ { 667, 667, 0, 0, 40000, 220,0 },
+ { 668, 668, 0, 0, 40000, 0,0 },
+ { 669, 669, 0, 0, 40000, 193,0 },
+ { 670, 670, 0, 0, 880, 20,0 },
+ { 671, 671, 0, 0, 4873, 120,0 },
+ { 672, 672, 0, 0, 40000, 413,0 },
+ { 673, 673, 0, 0, 700, 106,0 },
+ { 674, 674, 0, 0, 700, 100,0 },
+ { 675, 675, 0, 0, 40000, 126,0 },
+ { 676, 676, 0, 0, 8113, 806,0 },
+ { 677, 677, 0, 0, 8900, 80,0 },
+ { 678, 678, 0, 0, 1893, 653,0 },
+ { 679, 679, 0, 0, 3973, 206,0 },
+ { 680, 680, 0, 0, 40000, 173,0 },
+ { 681, 681, 0, 0, 40000, 73,0 },
+ { 682, 682, 0, 0, 40000, 93,0 },
+ { 683, 683, 0, 0, 1606, 640,0 },
+ { 684, 684, 0, 0, 15486, 1580,0 },
+ { 685, 685, 0, 0, 40000, 346,0 },
+ { 686, 686, 0, 0, 40000, 786,0 },
+ { 687, 687, 0, 0, 386, 240,0 },
+ { 688, 688, 0, 0, 40000, 2066,0 },
+ { 689, 689, 0, 0, 15453, 73,0 },
+ { 690, 690, 0, 0, 1206, 240,0 },
+ { 691, 691, 0, 0, 8866, 1366,0 },
+ { 692, 692, 0, 0, 5913, 2253,0 },
+ { 693, 693, 0, 0, 773, 106,0 },
+ { 694, 694, 0, 0, 3793, 73,0 },
+ { 695, 695, 0, 0, 40000, 73,0 },
+ { 645, 645, 0, 0, 3633, 1180,0 },
+ { 696, 696, 0, 0, 40000, 80,0 },
+ { 697, 697, 0, 0, 40000, 0,0 },
+ { 698, 698, 0, 0, 40000, 66,0 },
+ { 699, 699, 0, 0, 40000, 66,0 },
+ { 700, 700, 0, 0, 106, 0,0 },
+ { 701, 701, 0, 0, 40000, 200,0 },
+ { 702, 702, 0, 0, 3913, 73,0 },
+ { 703, 703, 0, 0, 40000, 73,0 },
+ { 704, 704, 0, 0, 40000, 73,0 },
+ { 705, 705, 0, 0, 40000, 73,0 },
+ { 706, 706, 0, 0, 40000, 66,0 },
+ { 707, 707, 0, 0, 40000, 313,0 },
+ { 708, 708, 0, 0, 40000, 100,0 },
+ { 709, 709, 0, 0, 40000, 213,0 },
+ { 710, 710, 0, 0, 40000, 53,0 },
+ { 711, 711, 0, 0, 40000, 40,0 },
+ { 712, 712, 0, 0, 40000, 73,0 },
+ { 713, 713, 0, 0, 40000, 140,0 },
+ { 714, 714, 0, 0, 40000, 606,0 },
+ { 715, 715, 0, 0, 40000, 226,0 },
+ { 716, 716, 0, 0, 3746, 1273,0 },
+ { 717, 717, 0, 0, 40000, 80,0 },
+ { 718, 718, 0, 0, 2360, 806,0 },
+ { 719, 719, 0, 0, 1186, 420,0 },
+ { 720, 720, 0, 0, 12533, 1953,0 },
+ { 721, 721, 0, 0, 973, 1280,0 },
+ { 722, 722, 0, 0, 40000, 426,0 },
+ { 723, 723, 0, 0, 40000, 53,0 },
+ { 724, 724, 0, 0, 40000, 66,0 },
+ { 725, 725, 0, 0, 1246, 73,0 },
+ { 726, 726, 0, 0, 3726, 1246,0 },
+ { 727, 727, 0, 0, 2346, 813,0 },
+ { 728, 728, 0, 0, 1206, 433,0 },
+ { 507, 507, 0, 0, 306, 246,0 },
+ { 512, 512, 0, 0, 526, 840,0 },
+ { 729, 729, 0, 0, 14793, 4933,0 },
+ { 730, 730, 0, 0, 14640, 4806,0 },
+ { 731, 731, 0, 0, 5233, 633,0 },
+ { 732, 732, 0, 0, 40000, 2513,0 },
+ { 733, 733, 0, 0, 40000, 820,0 },
+ { 734, 734, 0, 0, 40000, 0,0 },
+ { 735, 735, 0, 0, 1726, 793,0 },
+ { 736, 736, 0, 0, 513, 20,0 },
+ { 737, 737, 0, 2, 6, 0,0 },
+ { 738, 738, 38, 0, 1020, 413,0 },
+ { 739, 739, 44, 0, 220, 33,0 },
+ { 500, 500, 58, 0, 100, 0,0 },
+ { 740, 740, 24, 0, 513, 206,0 },
+ { 741, 741, 60, 0, 220, 26,0 },
+ { 736, 736, 44, 0, 286, 20,0 },
+ { 742, 742, 25, 0, 626, 246,0 },
+ { 743, 743, 60, 0, 146, 86,0 },
+ { 742, 742, 30, 0, 626, 240,0 },
+ { 377, 377, 60, 0, 446, 626,0 },
+ { 742, 742, 33, 0, 620, 226,0 },
+ { 744, 744, 60, 0, 220, 113,0 },
+ { 742, 742, 35, 0, 620, 233,0 },
+ { 742, 742, 37, 0, 633, 246,0 },
+ { 745, 745, 0, 0, 1880, 640,0 },
+ { 742, 742, 40, 0, 640, 260,0 },
+ { 746, 746,102, 0, 960, 300,0 },
+ { 747, 747, 80, 0, 1106, 126,0 },
+ { 377, 377, 0, 0, 500, 760,0 },
+ { 748, 748, 56, 0, 100, 0,0 },
+ { 749, 749, 0, 0, 973, 1300,0 },
+ { 746, 746,100, 0, 960, 340,0 },
+ { 750, 750, 40, 0, 626, 240,0 },
+ { 750, 750, 35, 0, 626, 240,0 },
+ { 751, 751, 29, 0, 206, 106,0 },
+ { 750, 750, 29, 0, 633, 240,0 },
+ { 750, 750, 22, 0, 640, 233,0 },
+ { 500, 500, 0, 0, 106, 0,0 },
+ { 752, 752, 0, 0, 206, 26,0 },
+ { 753, 753, 84, 0, 166, 20,0 },
+ { 754, 754, 84, 0, 1580, 553,0 },
+ { 755, 755, 0, 0, 633, 233,0 },
+ { 755, 755, 71, 0, 440, 180,0 },
+ { 755, 755, 53, 0, 513, 200,0 },
+ { 755, 755, 48, 0, 520, 206,0 },
+ { 756, 756, 95, 0, 286, 20,0 },
+ { 757, 757, 95, 0, 1880, 20,0 },
+ { 758, 758, 0, 0, 14413, 333,0 },
+ { 759, 759, 0, 0, 14453, 360,0 },
+ { 760, 760, 0, 0, 14940, 353,0 },
+ { 761, 761, 0, 0, 7286, 340,0 },
+ { 762, 762, 0, 0, 14700, 60,0 },
+ { 763, 763, 0, 0, 14506, 340,0 },
+ { 764, 764, 0, 0, 14706, 200,0 },
+ { 765, 765, 0, 0, 40000, 0,0 },
+ { 766, 766, 0, 0, 2900, 426,0 },
+ { 767, 767, 0, 0, 2986, 753,0 },
+ { 768, 768, 0, 0, 1706, 680,0 },
+ { 769, 769, 0, 0, 14646, 1253,0 },
+ { 770, 770, 0, 0, 1713, 486,0 },
+ { 771, 771, 0, 0, 966, 346,0 },
+ { 772, 772, 0, 0, 3453, 766,0 },
+ { 773, 773, 0, 0, 2866, 486,0 },
+ { 774, 774, 0, 0, 40000, 73,0 },
+ { 775, 775, 0, 0, 40000, 73,0 },
+ { 776, 776, 0, 0, 40000, 166,0 },
+ { 777, 777, 0, 0, 40000, 126,0 },
+ { 778, 778, 0, 0, 40000, 113,0 },
+ { 779, 779, 0, 0, 40000, 113,0 },
+ { 780, 780, 0, 0, 40000, 93,0 },
+ { 781, 781, 0, 0, 40000, 200,0 },
+ { 782, 782, 0, 0, 7186, 93,0 },
+ { 783, 783, 0, 0, 6406, 120,0 },
+ { 784, 784, 0, 0, 40000, 0,0 },
+ { 785, 785, 0, 0, 40000, 0,0 },
+ { 786, 786, 0, 0, 1220, 73,0 },
+ { 787, 787, 0, 0, 40000, 0,0 },
+ { 788, 788, 0, 0, 17566, 66,0 },
+ { 789, 789, 0, 0, 2333, 26,0 },
+ { 790, 790, 0, 0, 4560, 153,0 },
+ { 791, 791, 0, 0, 40000, 0,0 },
+ { 792, 792, 0, 0, 40000, 0,0 },
+ { 793, 793, 0, 0, 40000, 0,0 },
+ { 794, 794, 0, 0, 2506, 126,0 },
+ { 795, 795, 0, 0, 2513, 126,0 },
+ { 796, 796, 0, 0, 40000, 0,0 },
+ { 797, 797, 0, 0, 3386, 80,0 },
+ { 798, 798, 0, 0, 40000, 100,0 },
+ { 799, 799, 0, 0, 40000, 100,0 },
+ { 800, 800, 0, 0, 40000, 120,0 },
+ { 801, 801, 0, 0, 40000, 0,0 },
+ { 802, 802, 0, 0, 40000, 200,0 },
+ { 803, 803, 0, 0, 1080, 180,0 },
+ { 804, 804, 0, 0, 3620, 1166,0 },
+ { 805, 805, 0, 0, 1186, 393,0 },
+ { 806, 806, 0, 0, 40000, 213,0 },
+ { 807, 807, 0, 0, 40000, 426,0 },
+ { 808, 808, 0, 0, 40000, 146,0 },
+ { 809, 809, 0, 0, 40000, 146,0 },
+ { 810, 810, 0, 0, 40000, 60,0 },
+ { 811, 811, 0, 0, 40000, 113,0 },
+ { 812, 812, 0, 0, 40000, 93,0 },
+ { 813, 813, 0, 0, 1186, 153,0 },
+ { 814, 814, 0, 0, 40000, 0,0 },
+ { 815, 815, 0, 0, 40000, 80,0 },
+ { 816, 816, 0, 0, 40000, 80,0 },
+ { 817, 817, 0, 0, 40000, 46,0 },
+ { 818, 818, 0, 0, 40000, 0,0 },
+ { 819, 819, 0, 0, 40000, 66,0 },
+ { 820, 820, 0, 0, 40000, 126,0 },
+ { 821, 821, 0, 0, 40000, 213,0 },
+ { 822, 822, 0, 0, 40000, 80,0 },
+ { 823, 823, 0, 0, 40000, 73,0 },
+ { 824, 824, 0, 0, 40000, 73,0 },
+ { 825, 825, 0, 0, 40000, 100,0 },
+ { 826, 826, 0, 0, 40000, 93,0 },
+ { 827, 827, 0, 0, 40000, 73,0 },
+ { 828, 828, 0, 0, 40000, 73,0 },
+ { 829, 829, 0, 0, 40000, 80,0 },
+ { 830, 830, 0, 0, 40000, 80,0 },
+ { 831, 831, 0, 0, 40000, 80,0 },
+ { 832, 832, 0, 0, 40000, 73,0 },
+ { 833, 833, 0, 0, 40000, 80,0 },
+ { 834, 834, 0, 0, 40000, 86,0 },
+ { 835, 835, 0, 0, 40000, 100,0 },
+ { 836, 836, 0, 0, 40000, 100,0 },
+ { 837, 837, 0, 0, 40000, 140,0 },
+ { 838, 838, 0, 0, 40000, 73,0 },
+ { 839, 839, 0, 0, 40000, 0,0 },
+ { 840, 840, 0, 0, 40000, 93,0 },
+ { 841, 841, 0, 0, 40000, 0,0 },
+ { 842, 842, 0, 0, 40000, 0,0 },
+ { 843, 843, 0, 0, 40000, 73,0 },
+ { 844, 844, 0, 0, 40000, 66,0 },
+ { 845, 845, 0, 0, 40000, 0,0 },
+ { 846, 846, 0, 0, 40000, 193,0 },
+ { 847, 847, 0, 0, 40000, 340,0 },
+ { 848, 848, 0, 0, 40000, 233,0 },
+ { 849, 849, 0, 0, 40000, 80,0 },
+ { 850, 850, 0, 0, 40000, 186,0 },
+ { 851, 851, 0, 0, 9973, 426,0 },
+ { 852, 852, 0, 0, 40000, 200,0 },
+ { 853, 853, 0, 0, 40000, 400,0 },
+ { 854, 854, 0, 0, 14633, 200,0 },
+ { 855, 855, 0, 0, 40000, 333,0 },
+ { 856, 856, 0, 0, 4620, 800,0 },
+ { 857, 857, 0, 0, 8940, 386,0 },
+ { 858, 858, 0, 0, 8966, 740,0 },
+ { 859, 859, 0, 0, 40000, 273,0 },
+ { 860, 860, 0, 0, 40000, 126,0 },
+ { 861, 861, 0, 0, 40000, 400,0 },
+ { 862, 862, 0, 0, 4480, 213,0 },
+ { 863, 863, 0, 0, 633, 100,0 },
+ { 864, 864, 0, 0, 3740, 353,0 },
+ { 865, 865, 0, 0, 2333, 406,0 },
+ { 866, 866, 0, 0, 1933, 566,0 },
+ { 867, 867, 0, 0, 40000, 93,0 },
+ { 868, 868, 0, 0, 40000, 106,0 },
+ { 869, 869, 0, 0, 40000, 100,0 },
+ { 870, 870, 0, 0, 3093, 240,0 },
+ { 871, 871, 0, 0, 513, 93,0 },
+ { 872, 872, 0, 0, 700, 180,0 },
+ { 361, 361, 0, 0, 373, 40,0 },
+ { 873, 873, 0, 0, 1046, 446,0 },
+ { 874, 874, 0, 0, 1886, 520,0 },
+ { 875, 875, 0, 0, 1226, 366,0 },
+ { 876, 876, 0, 0, 4193, 73,0 },
+ { 877, 877, 0, 0, 826, 120,0 },
+ { 878, 878, 0, 0, 280, 146,0 },
+ { 879, 879, 0, 0, 5266, 806,0 },
+ { 880, 880, 0, 0, 386, 80,0 },
+ { 881, 881, 0, 0, 40000, 100,0 },
+ { 882, 882, 0, 0, 40000, 413,0 },
+ { 883, 883, 0, 0, 40000, 0,0 },
+ { 884, 884, 36, 0, 233, 80,0 },
+ { 885, 885, 48, 0, 193, 93,0 },
+ { 885, 885, 36, 0, 226, 100,0 },
+ { 886, 886, 36, 0, 113, 0,0 },
+ { 887, 887, 32, 0, 133, 40,0 },
+ { 767, 767, 96, 0, 1760, 480,0 },
+ { 888, 888, 30, 0, 246, 40,0 },
+ { 889, 889, 35, 0, 420, 140,0 },
+ { 890, 890, 60, 0, 240, 60,0 },
+ { 884, 884, 59, 0, 146, 20,0 },
+ { 890, 890, 44, 0, 240, 60,0 },
+ { 891, 891, 41, 0, 713, 273,0 },
+ { 892, 892, 47, 0, 173, 93,0 },
+ { 891, 891, 44, 0, 513, 206,0 },
+ { 891, 891, 48, 0, 506, 200,0 },
+ { 893, 893, 62, 0, 1926, 93,0 },
+ { 891, 891, 51, 0, 520, 200,0 },
+ { 891, 891, 54, 0, 513, 206,0 },
+ { 894, 894, 40, 0, 1280, 793,0 },
+ { 891, 891, 57, 0, 380, 160,0 },
+ { 895, 895, 97, 0, 233, 106,0 },
+ { 896, 896, 50, 0, 220, 93,0 },
+ { 376, 376, 60, 0, 1573, 713,0 },
+ { 897, 897, 53, 0, 126, 73,0 },
+ { 898, 898, 46, 0, 173, 133,0 },
+ { 897, 897, 57, 0, 126, 33,0 },
+ { 899, 899, 42, 0, 626, 233,0 },
+ { 899, 899, 37, 0, 633, 240,0 },
+ { 900, 900, 41, 0, 626, 240,0 },
+ { 900, 900, 37, 0, 626, 240,0 },
+ { 871, 871, 77, 0, 173, 40,0 },
+ { 871, 871, 72, 0, 173, 40,0 },
+ { 388, 388, 70, 0, 213, 86,0 },
+ { 901, 901, 39, 0, 260, 26,0 },
+ { 902, 902, 36, 0, 1093, 73,0 },
+ { 903, 903, 46, 0, 120, 73,0 },
+ { 904, 904, 48, 0, 766, 80,0 },
+ { 905, 905, 85, 0, 126, 26,0 },
+ { 361, 361, 66, 0, 180, 26,0 },
+ { 906, 906, 41, 0, 193, 73,0 },
+ { 907, 907, 41, 0, 333, 106,0 },
+ { 908, 908, 81, 0, 160, 26,0 },
+ { 400, 400, 10, 0, 1186, 413,0 },
+ { 886, 886, 60, 0, 100, 0,0 },
+ { 873, 873, 53, 0, 846, 360,0 },
+ { 909, 909, 0, 0, 5593, 340,0 },
+ { 910, 910, 0, 0, 14646, 346,0 },
+ { 911, 911, 0, 0, 6826, 280,0 },
+ { 912, 912, 0, 0, 7000, 306,0 },
+ { 913, 913, 0, 0, 8793, 133,0 },
+ { 914, 914, 0, 0, 14680, 346,0 },
+ { 915, 915, 0, 0, 7246, 126,0 },
+ { 916, 916, 0, 0, 40000, 0,0 },
+ { 917, 917, 0, 0, 1866, 433,0 },
+ { 362, 362, 0, 0, 1106, 340,0 },
+ { 918, 918, 0, 0, 1053, 273,0 },
+ { 919, 919, 0, 0, 14513, 1213,0 },
+ { 920, 920, 0, 0, 1886, 646,0 },
+ { 921, 921, 0, 0, 926, 313,0 },
+ { 922, 922, 0, 0, 2340, 806,0 },
+ { 923, 923, 0, 0, 2966, 553,0 },
+ { 924, 924, 0, 0, 40000, 66,0 },
+ { 925, 925, 0, 0, 40000, 73,0 },
+ { 926, 926, 0, 0, 40000, 0,0 },
+ { 927, 927, 0, 0, 40000, 126,0 },
+ { 928, 928, 0, 0, 40000, 113,0 },
+ { 929, 929, 0, 0, 40000, 113,0 },
+ { 930, 930, 0, 0, 40000, 93,0 },
+ { 931, 931, 0, 0, 40000, 113,0 },
+ { 932, 932, 0, 0, 7200, 86,0 },
+ { 933, 933, 0, 0, 5373, 106,0 },
+ { 934, 934, 0, 0, 40000, 0,0 },
+ { 935, 935, 0, 0, 40000, 0,0 },
+ { 936, 936, 0, 0, 2380, 73,0 },
+ { 937, 937, 0, 0, 40000, 0,0 },
+ { 938, 938, 0, 0, 40000, 0,0 },
+ { 939, 939, 0, 0, 6013, 53,0 },
+ { 940, 940, 0, 0, 3713, 126,0 },
+ { 941, 941, 0, 0, 17566, 26,0 },
+ { 942, 942, 0, 0, 40000, 0,0 },
+ { 943, 943, 0, 0, 40000, 0,0 },
+ { 944, 944, 0, 0, 2506, 126,0 },
+ { 945, 945, 0, 0, 3733, 73,0 },
+ { 946, 946, 0, 0, 40000, 0,0 },
+ { 947, 947, 0, 0, 3386, 80,0 },
+ { 948, 948, 0, 0, 40000, 100,0 },
+ { 949, 949, 0, 0, 40000, 100,0 },
+ { 950, 950, 0, 0, 40000, 113,0 },
+ { 951, 951, 0, 0, 40000, 0,0 },
+ { 952, 952, 0, 0, 40000, 200,0 },
+ { 953, 953, 0, 0, 1140, 213,0 },
+ { 954, 954, 0, 0, 2140, 400,0 },
+ { 955, 955, 0, 0, 813, 240,0 },
+ { 956, 956, 0, 0, 40000, 100,0 },
+ { 957, 957, 0, 0, 40000, 426,0 },
+ { 958, 958, 0, 0, 40000, 0,0 },
+ { 959, 959, 0, 0, 40000, 146,0 },
+ { 960, 960, 0, 0, 40000, 120,0 },
+ { 961, 961, 0, 0, 40000, 93,0 },
+ { 962, 962, 0, 0, 1193, 153,0 },
+ { 963, 963, 0, 0, 40000, 46,0 },
+ { 964, 964, 0, 0, 40000, 80,0 },
+ { 965, 965, 0, 0, 40000, 80,0 },
+ { 966, 966, 0, 0, 40000, 20,0 },
+ { 967, 967, 0, 0, 40000, 0,0 },
+ { 968, 968, 0, 0, 40000, 93,0 },
+ { 969, 969, 0, 0, 40000, 86,0 },
+ { 970, 970, 0, 0, 40000, 213,0 },
+ { 971, 971, 0, 0, 40000, 80,0 },
+ { 972, 972, 0, 0, 40000, 73,0 },
+ { 973, 973, 0, 0, 40000, 0,0 },
+ { 974, 974, 0, 0, 40000, 93,0 },
+ { 975, 975, 0, 0, 40000, 73,0 },
+ { 976, 976, 0, 0, 40000, 73,0 },
+ { 977, 977, 0, 0, 40000, 66,0 },
+ { 978, 978, 0, 0, 40000, 66,0 },
+ { 979, 979, 0, 0, 40000, 100,0 },
+ { 980, 980, 0, 0, 40000, 73,0 },
+ { 981, 981, 0, 0, 40000, 73,0 },
+ { 982, 982, 0, 0, 40000, 80,0 },
+ { 983, 983, 0, 0, 40000, 100,0 },
+ { 984, 984, 0, 0, 40000, 100,0 },
+ { 985, 985, 0, 0, 40000, 100,0 },
+ { 986, 986, 0, 0, 40000, 80,0 },
+ { 987, 987, 0, 0, 40000, 73,0 },
+ { 988, 988, 0, 0, 40000, 0,0 },
+ { 989, 989, 0, 0, 40000, 86,0 },
+ { 990, 990, 0, 0, 40000, 0,0 },
+ { 991, 991, 0, 0, 40000, 0,0 },
+ { 992, 992, 0, 0, 40000, 80,0 },
+ { 993, 993, 0, 0, 40000, 86,0 },
+ { 994, 994, 0, 0, 40000, 0,0 },
+ { 995, 995, 0, 0, 40000, 0,0 },
+ { 996, 996, 0, 0, 40000, 333,0 },
+ { 997, 997, 0, 0, 40000, 180,0 },
+ { 998, 998, 0, 0, 40000, 80,0 },
+ { 999, 999, 0, 0, 40000, 120,0 },
+ {1000,1000, 0, 0, 10006, 460,0 },
+ {1001,1001, 0, 0, 40000, 186,0 },
+ {1002,1002, 0, 0, 40000, 400,0 },
+ {1003,1003, 0, 0, 20333, 260,0 },
+ {1004,1004, 0, 0, 40000, 373,0 },
+ {1005,1005, 0, 0, 4520, 400,0 },
+ {1006,1006, 0, 0, 8213, 306,0 },
+ {1007,1007, 0, 0, 8646, 360,0 },
+ {1008,1008, 0, 0, 40000, 160,0 },
+ {1009,1009, 0, 0, 40000, 133,0 },
+ {1010,1010, 0, 0, 40000, 400,0 },
+ {1011,1011, 0, 0, 4473, 193,0 },
+ {1012,1012, 0, 0, 1813, 0,0 },
+ {1013,1013, 0, 0, 3726, 353,0 },
+ {1014,1014, 0, 0, 4400, 373,0 },
+ {1015,1015, 0, 0, 953, 166,0 },
+ {1016,1016, 0, 0, 40000, 73,0 },
+ {1017,1017, 0, 0, 40000, 100,0 },
+ {1018,1018, 0, 0, 40000, 100,0 },
+ {1019,1019, 0, 0, 3100, 240,0 },
+ { 444, 444, 0, 0, 513, 93,0 },
+ {1020,1020, 0, 0, 626, 180,0 },
+ { 449, 449, 0, 0, 373, 80,0 },
+ { 453, 453, 0, 0, 40000, 0,0 },
+ {1021,1021, 0, 0, 1020, 340,0 },
+ {1022,1022, 0, 0, 1200, 366,0 },
+ {1023,1023, 0, 0, 4193, 73,0 },
+ {1024,1024, 0, 0, 820, 120,0 },
+ {1025,1025, 0, 0, 680, 213,0 },
+ {1026,1026, 0, 0, 5260, 806,0 },
+ {1027,1027, 0, 0, 9193, 86,0 },
+ {1028,1028, 0, 0, 40000, 100,0 },
+ {1029,1029, 0, 0, 40000, 426,0 },
+ {1030,1030, 0, 0, 40000, 260,0 },
+ {1031,1031, 0, 0, 3480, 66,0 },
+ {1032,1032, 32, 0, 133, 46,0 },
+ {1033,1033, 30, 0, 200, 40,0 },
+ {1034,1034, 96, 0, 146, 73,0 },
+ {1035,1035, 60, 0, 553, 186,0 },
+ {1036,1036, 0, 0, 13193, 260,0 },
+ {1037,1037, 0, 0, 40000, 100,0 },
+ {1038,1038, 0, 0, 7980, 66,0 },
+ {1039,1039, 0, 0, 40000, 0,0 },
+ {1040,1040, 0, 0, 980, 340,0 },
+ {1041,1041, 0, 0, 7413, 2480,0 },
+ {1042,1042, 0, 0, 2906, 520,0 },
+ {1043,1043, 0, 0, 40000, 73,0 },
+ {1044,1044, 0, 0, 40000, 53,0 },
+ {1045,1045, 0, 0, 40000, 113,0 },
+ {1046,1046, 0, 0, 5380, 113,0 },
+ {1047,1047, 0, 0, 40000, 0,0 },
+ {1048,1048, 0, 0, 2366, 73,0 },
+ {1049,1049, 0, 0, 40000, 0,0 },
+ {1050,1050, 0, 0, 18293, 80,0 },
+ {1051,1051, 0, 0, 18466, 146,0 },
+ {1052,1052, 0, 0, 9220, 73,0 },
+ {1053,1053, 0, 0, 40000, 240,0 },
+ {1054,1054, 0, 0, 40000, 0,0 },
+ {1055,1055, 0, 0, 1086, 126,0 },
+ {1056,1056, 0, 0, 3766, 73,0 },
+ {1057,1057, 0, 0, 1186, 226,0 },
+ {1058,1058, 0, 0, 3373, 73,0 },
+ {1059,1059, 0, 0, 40000, 246,0 },
+ {1060,1060, 0, 0, 340, 220,0 },
+ {1061,1061, 0, 0, 1186, 386,0 },
+ {1062,1062, 0, 0, 40000, 253,0 },
+ {1063,1063, 0, 0, 40000, 440,0 },
+ {1064,1064, 0, 0, 40000, 46,0 },
+ {1065,1065, 0, 0, 40000, 80,0 },
+ {1066,1066, 0, 0, 40000, 126,0 },
+ {1067,1067, 0, 0, 40000, 133,0 },
+ {1068,1068, 0, 0, 40000, 93,0 },
+ {1069,1069, 0, 0, 40000, 86,0 },
+ {1070,1070, 0, 0, 40000, 93,0 },
+ {1071,1071, 0, 0, 40000, 66,0 },
+ {1072,1072, 0, 0, 40000, 93,0 },
+ {1073,1073, 0, 0, 40000, 73,0 },
+ {1074,1074, 0, 0, 40000, 173,0 },
+ {1075,1075, 0, 0, 586, 193,0 },
+ {1076,1076, 0, 0, 40000, 146,0 },
+ {1077,1077, 0, 0, 18460, 73,0 },
+ {1078,1078, 0, 0, 846, 93,0 },
+ {1079,1079, 0, 0, 40000, 0,0 },
+ {1080,1080, 0, 0, 40000, 86,0 },
+ {1081,1081, 0, 0, 40000, 0,0 },
+ {1082,1082, 0, 0, 40000, 353,0 },
+ {1083,1083, 0, 0, 40000, 300,0 },
+ {1084,1084, 0, 0, 40000, 320,0 },
+ {1085,1085, 0, 0, 9920, 1553,0 },
+ {1086,1086, 0, 0, 40000, 386,0 },
+ {1087,1087, 0, 0, 40000, 0,0 },
+ {1088,1088, 0, 0, 9980, 873,0 },
+ {1089,1089, 0, 0, 40000, 386,0 },
+ {1090,1090, 0, 0, 966, 126,0 },
+ {1091,1091, 0, 0, 40000, 820,0 },
+ {1092,1092, 0, 0, 8620, 366,0 },
+ {1093,1093, 0, 0, 40000, 826,0 },
+ {1094,1094, 0, 0, 40000, 433,0 },
+ {1095,1095, 0, 0, 633, 73,0 },
+ {1096,1096, 0, 0, 3693, 126,0 },
+ {1097,1097, 0, 0, 40000, 0,0 },
+ {1098,1098, 0, 0, 40000, 153,0 },
+ {1099,1099, 0, 0, 40000, 0,0 },
+ {1100,1100, 0, 0, 40000, 0,0 },
+ {1101,1101, 0, 0, 40000, 306,0 },
+ {1102,1102, 0, 0, 3666, 3093,0 },
+ {1103,1103, 0, 0, 1873, 653,0 },
+ {1104,1104, 0, 0, 40000, 0,0 },
+ {1105,1105, 0, 0, 11293, 886,0 },
+ {1106,1106, 0, 0, 40000, 546,0 },
+ { 430, 430, 0, 0, 1146, 80,0 },
+ {1107,1107, 35, 0, 580, 80,0 },
+ {1090,1090, 77, 0, 280, 60,0 },
+ {1090,1090, 72, 0, 280, 60,0 },
+ {1108,1108, 0, 0, 10180, 600,0 },
+ {1109,1109, 0, 0, 10053, 353,0 },
+ {1110,1111, 0, 1, 9940, 480,0 },
+ {1112,1113, 0, 1, 10620, 473,0.03125 },
+ {1114,1114, 0, 0, 40000, 0,0 },
+ {1115,1116, 0, 1, 9833, 220,0 },
+ {1117,1117, 0, 0, 10286, 473,0 },
+ {1118,1118, 0, 0, 7686, 93,0 },
+ {1119,1119, 0, 0, 7220, 613,0 },
+ {1120,1120, 0, 0, 11513, 1666,0 },
+ {1121,1121, 0, 0, 5200, 1700,0 },
+ {1122,1122, 0, 0, 10173, 626,0 },
+ {1123,1123, 0, 0, 1206, 380,0 },
+ {1124,1124, 0, 0, 1953, 866,0 },
+ {1125,1125, 0, 0, 4686, 1586,0 },
+ {1126,1126, 0, 0, 3786, 893,0 },
+ {1127,1127, 0, 0, 40000, 126,0 },
+ {1128,1128, 0, 0, 40000, 120,0 },
+ {1129,1130, 0, 1, 40000, 146,0.15625 },
+ {1131,1131, 0, 0, 40000, 433,0 },
+ {1132,1132, 0, 0, 40000, 133,0 },
+ {1133,1134, 0, 1, 40000, 126,-0.046875 },
+ {1135,1135, 0, 0, 40000, 113,0 },
+ {1136,1137, 0, 1, 40000, 253,2.5e-05 },
+ {1138,1138, 0, 0, 18440, 240,0 },
+ {1139,1139, 0, 0, 5213, 886,0 },
+ {1140,1140, 0, 0, 1446, 113,0 },
+ {1141,1141, 0, 0, 5233, 106,0 },
+ {1142,1142, 0, 0, 5286, 266,0 },
+ {1143,1143, 0, 0, 40000, 66,0 },
+ {1144,1144, 0, 0, 40000, 66,0 },
+ {1145,1145, 0, 0, 10593, 106,0 },
+ {1146,1146, 0, 0, 2733, 160,0 },
+ {1147,1147, 0, 0, 10313, 93,0 },
+ {1148,1148, 0, 0, 40000, 0,0 },
+ {1149,1150, 0, 1, 40000, 0,-0.03125 },
+ {1151,1151, 0, 0, 40000, 53,0 },
+ {1152,1152, 0, 0, 10560, 246,0 },
+ {1153,1153, 0, 0, 2700, 153,0 },
+ {1154,1154, 0, 1, 40000, 100,-0.15625 },
+ {1155,1155, 0, 0, 40000, 73,0 },
+ {1156,1156, 0, 0, 40000, 220,0 },
+ {1157,1157, 0, 0, 40000, 140,0 },
+ {1158,1158, 0, 0, 40000, 380,0 },
+ {1159,1160, 0, 1, 40000, 400,0.171875 },
+ {1161,1161, 0, 0, 40000, 0,0 },
+ {1162,1162, 0, 0, 40000, 0,0 },
+ {1163,1163, 0, 0, 4733, 906,0 },
+ {1164,1165, 0, 1, 40000, 393,-0.125 },
+ {1166,1167, 0, 1, 40000, 366,0.078125 },
+ {1168,1168, 0, 1, 40000, 2453,-0.078125 },
+ {1169,1170, 0, 1, 40000, 546,0.0625 },
+ {1171,1172, 0, 1, 40000, 786,0.15625 },
+ {1173,1173, 0, 0, 40000, 0,0 },
+ {1174,1174, 0, 0, 40000, 513,0 },
+ {1175,1176, 0, 1, 2300, 533,0 },
+ {1177,1177, 0, 0, 40000, 80,0 },
+ {1178,1178, 0, 0, 40000, 60,0 },
+ {1179,1179, 0, 0, 40000, 0,0 },
+ {1180,1180, 0, 0, 10653, 86,0 },
+ {1181,1182, 0, 1, 40000, 0,2.5e-05 },
+ {1183,1184, 0, 1, 40000, 86,0.046875 },
+ {1185,1186, 0, 1, 40000, 0,0.09375 },
+ {1187,1188, 0, 1, 40000, 0,0.09375 },
+ {1189,1189, 0, 0, 40000, 133,0 },
+ {1190,1190, 0, 0, 40000, 140,0 },
+ {1191,1191, 0, 0, 40000, 73,0 },
+ {1192,1192, 0, 0, 40000, 60,0 },
+ {1193,1193, 0, 0, 40000, 106,0 },
+ {1194,1194, 0, 0, 40000, 93,0 },
+ {1195,1195, 0, 0, 40000, 66,0 },
+ {1196,1196, 0, 0, 40000, 93,0 },
+ {1197,1197, 0, 0, 40000, 60,0 },
+ {1198,1198, 0, 0, 40000, 66,0 },
+ {1199,1199, 0, 0, 40000, 120,0 },
+ {1200,1200, 0, 0, 40000, 100,0 },
+ {1201,1201, 0, 0, 40000, 86,0 },
+ {1202,1202, 0, 0, 40000, 0,0 },
+ {1203,1203, 0, 0, 40000, 233,0 },
+ {1204,1204, 0, 0, 40000, 100,0 },
+ {1205,1206, 0, 1, 40000, 266,0.03125 },
+ {1207,1208, 0, 1, 40000, 260,-2.5e-05 },
+ {1209,1209, 0, 0, 40000, 146,0 },
+ {1210,1211, 0, 1, 40000, 60,0.03125 },
+ {1212,1212, 0, 0, 40000, 53,0 },
+ {1213,1214, 0, 1, 40000, 706,-0.09375 },
+ {1215,1216, 0, 1, 40000, 660,-0.046875 },
+ {1217,1217, 0, 0, 40000, 133,0 },
+ {1218,1219, 0, 1, 40000, 426,0.03125 },
+ {1220,1220, 0, 1, 40000, 0,0.03125 },
+ {1221,1222, 0, 1, 40000, 260,0.171875 },
+ {1223,1223, 0, 0, 40000, 0,0 },
+ {1224,1224, 0, 0, 6100, 1580,0 },
+ {1225,1150, 0, 1, 40000, 73,-0.03125 },
+ {1226,1226, 0, 0, 40000, 1580,0 },
+ {1227,1227, 0, 0, 40000, 40,0 },
+ {1228,1229, 0, 1, 40000, 113,0.125 },
+ {1230,1230, 0, 0, 2666, 846,0 },
+ {1231,1232, 0, 1, 40000, 0,-0.03125 },
+ {1233,1234, 0, 1, 9233, 2413,-0.1875 },
+ {1235,1235, 0, 0, 40000, 1020,0 },
+ {1236,1236, 0, 0, 40000, 0,0 },
+ {1237,1237, 0, 0, 9633, 3073,0 },
+ {1238,1238, 0, 0, 40000, 0,0 },
+ {1239,1239, 0, 0, 2446, 386,0 },
+ {1240,1241, 0, 1, 3113, 1133,0 },
+ {1242,1242, 0, 0, 18473, 813,0 },
+ {1243,1243, 0, 0, 1206, 660,0 },
+ {1244,1244, 0, 0, 40000, 153,0 },
+ {1245,1245, 0, 0, 40000, 160,0 },
+ {1246,1246, 0, 0, 40000, 133,0 },
+ {1247,1247, 0, 0, 8660, 2386,0 },
+ {1248,1248, 0, 0, 293, 106,0 },
+ {1249,1249, 0, 0, 40000, 433,0 },
+ {1250,1250, 0, 0, 426, 80,0 },
+ {1251,1251, 0, 0, 973, 360,0 },
+ {1252,1252, 0, 0, 573, 153,0 },
+ {1253,1253, 0, 0, 3746, 126,0 },
+ {1254,1254, 0, 0, 2313, 73,0 },
+ {1255,1255, 0, 0, 1473, 106,0 },
+ {1256,1256, 0, 0, 1500, 320,0 },
+ {1257,1257, 0, 0, 5280, 1593,0 },
+ {1258,1258, 0, 0, 40000, 60,0 },
+ {1259,1259, 0, 0, 40000, 146,0 },
+ {1260,1260, 29, 0, 40000, 300,0 },
+ {1261,1261, 65, 0, 40000, 2040,0 },
+ {1262,1262, 0, 0, 626, 240,0 },
+ {1263,1263, 25, 0, 626, 226,0 },
+ {1264,1264, 83, 0, 180, 80,0 },
+ {1265,1265, 32, 0, 260, 140,0 },
+ {1266,1266, 60, 0, 40000, 0,0 },
+ {1267,1267, 36, 0, 286, 40,0 },
+ {1268,1268, 27, 0, 573, 80,0 },
+ {1269,1269, 31, 0, 693, 106,0 },
+ {1270,1270, 21, 0, 500, 146,0 },
+ {1270,1270, 26, 0, 493, 140,0 },
+ {1270,1270, 28, 0, 500, 146,0 },
+ {1271,1271, 60, 0, 2420, 1080,0 },
+ {1270,1270, 32, 0, 413, 126,0 },
+ {1272,1272, 60, 0, 806, 300,0 },
+ {1273,1273, 96, 0, 1146, 493,0 },
+ {1274,1274, 72, 0, 1246, 586,0 },
+ {1275,1275, 79, 0, 286, 106,0 },
+ {1276,1276, 69, 0, 1193, 1046,0 },
+ {1277,1277, 71, 0, 340, 93,0 },
+ {1278,1278, 22, 0, 1880, 653,0 },
+ {1279,1279, 55, 0, 246, 120,0 },
+ {1279,1279, 48, 0, 286, 133,0 },
+ {1280,1280, 0, 0, 40, 0,0 },
+ {1281,1281, 49, 2, 40, 0,0 },
+ {1282,1282, 73, 0, 166, 33,0 },
+ {1282,1282, 68, 0, 166, 33,0 },
+ {1282,1282, 61, 0, 200, 40,0 },
+ {1283,1283, 0, 0, 40, 0,0 },
+ {1284,1284, 0, 0, 40000, 100,0 },
+ {1285,1285, 0, 0, 40000, 60,0 },
+ {1286,1286, 0, 0, 40000, 0,0 },
+ {1287,1287, 0, 0, 10460, 153,0 },
+ {1288,1289, 0, 1, 40000, 0,0 },
+ {1290,1290, 0, 0, 40000, 0,0 },
+ {1291,1292, 36, 1, 353, 153,0 },
+ {1293,1293, 69, 0, 1206, 1060,0 },
+ {1294,1294, 0, 0, 40000, 0,0 },
+ {1295,1295, 0, 0, 40000, 73,0 },
+ {1296,1296, 0, 0, 40000, 0,0 },
+ {1297,1297, 22, 0, 1880, 653,0 },
+ {1298,1298, 0, 0, 40000, 73,0 },
+ {1299,1299, 0, 0, 3913, 420,0 },
+ {1300,1300, 0, 0, 9233, 240,0 },
+ {1301,1301, 0, 0, 4660, 1573,0 },
+ {1302,1302, 0, 0, 1166, 400,0 },
+ {1303,1303, 0, 0, 40000, 126,0 },
+ {1304,1304, 0, 0, 40000, 93,0 },
+ {1305,1305, 0, 0, 40000, 93,0 },
+ {1306,1306, 0, 0, 40000, 553,0 },
+ {1307,1307, 0, 0, 40000, 660,0 },
+ {1308,1308, 0, 0, 40000, 73,0 },
+ {1309,1309, 0, 0, 40000, 146,0 },
+ {1310,1310, 0, 0, 40000, 146,0 },
+ {1311,1311, 0, 0, 4026, 100,0 },
+ {1312,1312, 0, 0, 18226, 100,0 },
+ {1313,1313, 0, 0, 40000, 0,0 },
+ {1314,1314, 0, 0, 40000, 73,0 },
+ {1315,1315, 0, 0, 40000, 140,0 },
+ {1316,1316, 0, 0, 40000, 393,0 },
+ {1317,1317, 0, 0, 40000, 406,0 },
+ {1318,1318, 0, 0, 40000, 373,0 },
+ {1319,1319, 0, 0, 40000, 0,0 },
+ {1320,1320, 0, 0, 40000, 360,0 },
+ {1321,1321, 0, 0, 1060, 380,0 },
+ {1322,1322, 0, 0, 40000, 66,0 },
+ {1323,1323, 0, 0, 40000, 66,0 },
+ {1324,1324, 0, 0, 40000, 86,0 },
+ {1325,1325, 0, 0, 40000, 73,0 },
+ { 260, 260, 0, 0, 40000, 80,0 },
+ {1326,1326, 0, 0, 40000, 80,0 },
+ {1327,1327, 0, 0, 40000, 73,0 },
+ {1328,1328, 0, 0, 40000, 73,0 },
+ {1329,1329, 0, 0, 40000, 153,0 },
+ {1330,1330, 0, 0, 40000, 153,0 },
+ {1331,1331, 0, 0, 40000, 146,0 },
+ {1332,1332, 0, 0, 40000, 146,0 },
+ {1333,1333, 0, 0, 40000, 73,0 },
+ {1334,1334, 0, 0, 40000, 153,0 },
+ {1335,1335, 0, 0, 40000, 233,0 },
+ {1336,1336, 0, 0, 40000, 400,0 },
+ {1337,1337, 0, 0, 40000, 1373,0 },
+ {1338,1338, 0, 0, 40000, 193,0 },
+ {1339,1339, 0, 0, 40000, 1273,0 },
+ {1340,1340, 0, 0, 40000, 186,0 },
+ {1341,1341, 0, 0, 40000, 86,0 },
+ {1342,1342, 0, 0, 7440, 2473,0 },
+ {1343,1343, 0, 0, 40000, 160,0 },
+ {1344,1344, 0, 0, 8966, 406,0 },
+ {1345,1345, 0, 0, 40000, 1353,0 },
+ {1346,1346, 0, 0, 14180, 4406,0 },
+ { 378, 378, 84, 0, 1333, 460,0 },
+ {1347,1347, 24, 0, 1893, 633,0 },
+ {1348,1348, 44, 0, 206, 86,0 },
+ {1349,1349, 40, 0, 586, 140,0 },
+ {1350,1350, 60, 0, 1026, 320,0 },
+ {1351,1351, 0, 0, 6560, 33,0 },
+ {1352,1352, 0, 0, 7373, 2453,0 },
+ {1353,1353, 0, 0, 4660, 1573,0 },
+ {1354,1354, 0, 0, 40000, 346,0 },
+ {1355,1355, 0, 0, 7126, 86,0 },
+ {1356,1356, 0, 0, 40000, 213,0 },
+ {1357,1357, 0, 0, 1180, 340,0 },
+ {1358,1358, 0, 0, 3893, 1466,0 },
+ {1359,1359, 0, 0, 2053, 1173,0 },
+ {1360,1360, 0, 0, 40000, 200,0 },
+ {1361,1361, 0, 0, 40000, 353,0 },
+ {1362,1362, 0, 0, 40000, 273,0 },
+ {1363,1363, 0, 0, 40000, 433,0 },
+ {1364,1364, 0, 0, 1940, 426,0 },
+ {1365,1365, 0, 0, 40000, 80,0 },
+ {1366,1366, 0, 0, 40000, 106,0 },
+ {1367,1367, 0, 0, 40000, 60,0 },
+ {1368,1368, 0, 0, 40000, 140,0 },
+ {1369,1369, 0, 0, 40000, 93,0 },
+ {1370,1370, 0, 0, 40000, 73,0 },
+ {1371,1371, 0, 0, 40000, 73,0 },
+ {1372,1372, 0, 0, 40000, 93,0 },
+ {1373,1373, 0, 0, 40000, 73,0 },
+ {1374,1374, 0, 0, 40000, 80,0 },
+ {1375,1375, 0, 0, 40000, 746,0 },
+ {1376,1376, 0, 0, 2360, 813,0 },
+ {1377,1377, 0, 0, 340, 146,0 },
+ {1378,1378, 35, 0, 713, 273,0 },
+ {1379,1379, 49, 0, 173, 93,0 },
+ {1377,1377, 48, 0, 286, 126,0 },
+ {1380,1380, 58, 0, 173, 100,0 },
+ {1377,1377, 60, 0, 286, 133,0 },
+ {1381,1381, 47, 0, 973, 360,0 },
+ {1382,1382, 60, 0, 146, 86,0 },
+ {1381,1381, 49, 0, 966, 333,0 },
+ {1383,1383, 72, 0, 506, 206,0 },
+ {1381,1381, 51, 0, 953, 340,0 },
+ {1384,1384, 84, 0, 1340, 480,0 },
+ {1381,1381, 54, 0, 986, 360,0 },
+ {1381,1381, 57, 0, 980, 346,0 },
+ {1385,1385, 72, 0, 1573, 440,0 },
+ {1381,1381, 60, 0, 953, 340,0 },
+ {1386,1386, 36, 0, 2673, 900,0 },
+ {1387,1387, 93, 0, 233, 106,0 },
+ {1388,1388, 72, 0, 966, 353,0 },
+ {1389,1389, 84, 0, 1366, 473,0 },
+ {1390,1390, 36, 0, 1326, 446,0 },
+ {1391,1391, 64, 0, 220, 86,0 },
+ {1392,1392, 68, 0, 126, 220,0 },
+ {1393,1393, 0, 0, 4513, 640,0 },
+ {1394,1394, 0, 0, 40000, 353,0 },
+ {1395,1395, 0, 0, 40000, 73,0 },
+ {1396,1396, 0, 0, 2040, 380,0 },
+ {1397,1397, 0, 0, 40000, 240,0 },
+ {1398,1398, 0, 0, 3246, 753,0 },
+ {1399,1399, 0, 0, 40000, 66,0 },
+ {1400,1400, 0, 0, 40000, 0,0 },
+ {1401,1401, 0, 0, 40000, 0,0 },
+ {1402,1402, 0, 0, 7720, 1260,0 },
+ {1403,1403, 0, 0, 213, 6420,0 },
+ {1404,1404, 0, 0, 40000, 66,0 },
+ {1405,1405, 0, 0, 40000, 73,0 },
+ {1406,1406, 0, 0, 40000, 93,0 },
+ {1407,1407, 0, 0, 1606, 640,0 },
+ {1408,1408, 0, 0, 15486, 1580,0 },
+ {1409,1409, 0, 0, 40000, 353,0 },
+ {1410,1410, 0, 0, 40000, 2066,0 },
+ {1411,1411, 0, 0, 40000, 0,0 },
+ {1412,1412, 0, 0, 15453, 73,0 },
+ {1413,1413, 0, 0, 3726, 1240,0 },
+ {1414,1414, 0, 0, 40000, 86,0 },
+ {1415,1415, 0, 0, 40000, 200,0 },
+ {1416,1416, 0, 0, 40000, 53,0 },
+ {1417,1417, 0, 0, 40000, 73,0 },
+ {1418,1418, 0, 0, 40000, 66,0 },
+ {1419,1419, 0, 0, 40000, 26,0 },
+ {1420,1420, 0, 0, 40000, 53,0 },
+ {1421,1421, 0, 0, 40000, 40,0 },
+ {1422,1422, 0, 0, 40000, 126,0 },
+ {1423,1423, 0, 0, 40000, 0,0 },
+ {1424,1424, 0, 0, 13653, 0,0 },
+ {1425,1425, 0, 0, 12533, 1953,0 },
+ {1426,1426, 0, 0, 973, 1280,0 },
+ {1427,1427, 0, 0, 40000, 426,0 },
+ {1428,1428, 0, 0, 40000, 53,0 },
+ {1429,1429, 0, 0, 40000, 66,0 },
+ {1430,1430, 0, 0, 526, 840,0 },
+ {1431,1431, 0, 0, 286, 1293,0 },
+ {1432,1432, 0, 0, 14726, 4920,0 },
+ {1433,1433, 0, 0, 5233, 633,0 },
+ {1434,1434, 0, 0, 13226, 2500,0 },
+ { 740, 740, 0, 0, 513, 200,0 },
+ {1435,1435, 0, 0, 40000, 5666,0 },
+ { 739, 739, 48, 0, 213, 20,0 },
+ { 500, 500, 55, 0, 100, 0,0 },
+ { 740, 740, 60, 0, 226, 113,0 },
+ { 500, 500, 41, 0, 106, 0,0 },
+ {1436,1436, 84, 0, 160, 26,0 },
+ {1437,1437, 84, 0, 386, 493,0 },
+ { 500, 500, 48, 0, 100, 0,0 },
+ {1438,1438, 15, 0, 340, 140,0 },
+ { 752, 752, 49, 0, 173, 20,0 },
+ {1438,1438, 16, 0, 346, 146,0 },
+ {1438,1438, 12, 0, 340, 140,0 },
+ { 740, 740, 55, 0, 220, 113,0 },
+ { 752, 752, 18, 0, 206, 20,0 },
+ { 752, 752, 15, 0, 200, 20,0 },
+ { 752, 752, 17, 0, 206, 20,0 },
+ {1439,1440, 0, 4, 40000, 0,0 },
+ {1441,1442, 0, 4, 7360, 200,0 },
+ {1443,1444, 0, 4, 11840, 320,0 },
+ {1445,1446, 0, 4, 9920, 326,0 },
+ {1447,1448, 0, 4, 10213, 0,0 },
+ {1449,1450, 0, 4, 7440, 2486,0 },
+ { 181,1451, 0, 4, 2360, 733,0 },
+ {1452,1453, 0, 4, 9260, 240,0 },
+ {1454,1455, 0, 4, 40000, 0,0 },
+ {1456,1457, 0, 4, 660, 126,0 },
+ {1458,1459, 0, 4, 40000, 66,0 },
+ { 190,1460, 0, 4, 40000, 60,0 },
+ { 192,1461, 0, 4, 40000, 73,0 },
+ {1462,1463, 0, 4, 40000, 353,0 },
+ {1464,1465, 0, 4, 40000, 353,0 },
+ {1466,1467, 0, 4, 40000, 66,0 },
+ {1468,1469, 0, 4, 40000, 46,0 },
+ { 35,1470, 0, 4, 40000, 46,0 },
+ { 36,1471, 0, 4, 320, 0,0 },
+ {1472,1473, 0, 4, 320, 0,0 },
+ {1474,1475, 0, 4, 7986, 93,0 },
+ { 39,1476, 0, 4, 1053, 226,0 },
+ {1477,1476, 0, 4, 1060, 226,0 },
+ {1478,1479, 0, 4, 40000, 453,0 },
+ { 50,1480, 0, 4, 40000, 400,0 },
+ {1481,1482, 0, 4, 40000, 133,0 },
+ {1483,1484, 0, 4, 40000, 0,0 },
+ {1485,1486, 0, 4, 40000, 226,0 },
+ { 55,1487, 0, 4, 40000, 100,0 },
+ {1488,1489, 0, 4, 40000, 93,0 },
+ {1490,1491, 0, 4, 40000, 73,0 },
+ {1492,1493, 0, 4, 40000, 73,0 },
+ {1494,1495, 0, 4, 40000, 73,0 },
+ {1496,1497, 0, 4, 40000, 80,0 },
+ {1496,1498, 0, 4, 40000, 73,0 },
+ {1499,1500, 0, 4, 40000, 66,0 },
+ {1501,1502, 0, 4, 40000, 146,0 },
+ {1503,1504, 0, 4, 40000, 93,0 },
+ {1505,1506, 0, 4, 40000, 73,0 },
+ { 86,1507, 0, 4, 40000, 80,0 },
+ {1508,1509, 0, 4, 40000, 0,0 },
+ {1510,1511, 0, 4, 40000, 60,0 },
+ {1512,1513, 0, 4, 40000, 0,0 },
+ {1514,1515, 0, 4, 40000, 0,0 },
+ {1516,1517, 0, 4, 40000, 773,0 },
+ {1518,1519, 0, 4, 5346, 2973,0 },
+ {1520,1521, 0, 4, 40000, 406,0 },
+ {1522,1523, 0, 4, 9080, 360,0 },
+ {1524,1525, 0, 4, 40000, 1200,0 },
+ {1526,1527, 0, 4, 40000, 800,0 },
+ {1528,1529, 0, 4, 40000, 960,0 },
+ { 111,1530, 0, 4, 1200, 433,0 },
+ {1531,1532, 0, 4, 226, 386,0 },
+ { 115,1533, 0, 4, 2433, 0,0 },
+ {1534,1535, 0, 4, 1873, 646,0 },
+ {1536,1537, 0, 4, 3013, 53,0 },
+ {1538,1539, 0, 4, 1560, 720,0 },
+ {1540, 339, 0, 6, 6, 0,0 },
+ {1541, 339, 0, 6, 6, 0,0 },
+ {1542,1543, 0, 4, 993, 93,0 },
+ {1544,1545, 0, 4, 293, 86,0 },
+ {1546,1547, 0, 4, 40000, 153,0 },
+ { 364, 365, 44, 4, 120, 0,0 },
+ { 129,1548, 48, 4, 173, 0,0 },
+ { 367, 368, 58, 4, 173, 0,0 },
+ { 129,1549, 60, 4, 173, 0,0 },
+ {1550,1551, 48, 4, 520, 200,0 },
+ { 132,1552, 43, 4, 173, 0,0 },
+ {1550,1551, 49, 4, 520, 200,0 },
+ {1553,1554, 43, 4, 160, 80,0 },
+ {1550,1551, 51, 4, 513, 0,0 },
+ { 134,1555, 43, 4, 1733, 0,0 },
+ {1550,1551, 54, 4, 506, 0,0 },
+ {1550,1551, 57, 4, 506, 0,0 },
+ { 380, 381, 72, 4, 1580, 0,0 },
+ {1550,1551, 60, 4, 520, 0,0 },
+ {1556,1557, 70, 4, 826, 306,0 },
+ { 374, 375, 60, 4, 973, 0,0 },
+ {1558,1559, 36, 4, 1233, 0,0 },
+ {1560,1561, 65, 4, 293, 133,0 },
+ {1562,1563, 84, 4, 1360, 0,0 },
+ {1564,1565, 59, 4, 380, 0,0 },
+ {1566,1567, 84, 4, 1593, 566,0 },
+ {1568,1569, 35, 4, 1353, 473,0 },
+ {1570,1571, 44, 4, 413, 0,0 },
+ {1572,1573, 67, 4, 246, 0,0 },
+ {1574,1575, 66, 4, 293, 0,0 },
+ { 145,1576, 59, 4, 146, 0,0 },
+ {1577,1578, 51, 4, 360, 0,0 },
+ {1579,1580, 45, 4, 246, 0,0 },
+ {1581,1582, 71, 4, 433, 0,0 },
+ { 149,1583, 60, 4, 280, 0,0 },
+ {1584,1585, 58, 4, 173, 0,0 },
+ {1586,1587, 53, 4, 173, 0,0 },
+ { 397,1588, 64, 4, 220, 80,0 },
+ {1589,1590, 71, 4, 106, 53,0 },
+ {1591,1592, 61, 4, 1000, 340,0 },
+ {1593,1594, 61, 4, 1000, 340,0 },
+ { 391, 392, 48, 4, 160, 46,0 },
+ { 391, 393, 48, 4, 380, 60,0 },
+ {1595,1596, 69, 4, 120, 0,0 },
+ { 159,1597, 68, 4, 120, 0,0 },
+ { 159,1597, 63, 4, 140, 0,0 },
+ {1598,1599, 74, 4, 893, 273,0 },
+ {1600,1601, 60, 4, 1013, 306,0 },
+ {1602,1603, 80, 4, 220, 0,0 },
+ {1604,1605, 64, 4, 1366, 0,0 },
+ {1606,1607, 69, 4, 120, 73,0 },
+ { 398, 399, 55, 4, 1540, 193,0 },
+ {1608,1609, 75, 4, 1573, 0,0 },
+ {1610,1611, 68, 4, 120, 0,0 },
+ {1612,1613, 48, 4, 360, 0,0 },
+ {1614,1615, 53, 4, 606, 0,0 },
+ {1616,1616, 0, 0, 40000, 1586,0 },
+ {1617,1617, 0, 0, 40000, 1226,0 },
+ {1618,1618, 0, 0, 4546, 766,0 },
+ {1619,1619, 0, 0, 40000, 420,0 },
+ {1620,1620, 0, 0, 40000, 1573,0 },
+ {1621,1621, 0, 0, 3326, 806,0 },
+ {1622,1622, 0, 0, 40000, 746,0 },
+ {1623,1623, 0, 0, 40000, 900,0 },
+ {1624,1624, 0, 0, 12166, 1573,0 },
+ {1625,1625, 0, 0, 40000, 80,0 },
+ {1626,1626, 0, 0, 40000, 80,0 },
+ {1627,1627, 0, 0, 40000, 80,0 },
+ {1628,1628, 0, 0, 40000, 2713,0 },
+ {1629,1629, 0, 0, 40000, 86,0 },
+ {1630,1630, 0, 0, 40000, 80,0 },
+ {1631,1631, 0, 0, 40000, 80,0 },
+ {1632,1632, 0, 0, 40000, 813,0 },
+ {1633,1633, 0, 0, 40000, 80,0 },
+ {1634,1634, 0, 0, 40000, 80,0 },
+ {1635,1635, 0, 0, 40000, 80,0 },
+ {1636,1636, 0, 0, 40000, 193,0 },
+ {1637,1637, 0, 0, 2920, 733,0 },
+ {1638,1638, 0, 0, 40000, 373,0 },
+ {1639,1639, 0, 0, 2286, 226,0 },
+ {1640,1640, 0, 0, 40000, 226,0 },
+ {1641,1641, 0, 0, 40000, 226,0 },
+ {1642,1642, 0, 0, 40000, 433,0 },
+ {1643,1643, 0, 0, 40000, 813,0 },
+ {1644,1644, 0, 0, 40000, 80,0 },
+ {1645,1645, 0, 0, 40000, 80,0 },
+ {1646,1646, 0, 0, 40000, 80,0 },
+ {1647,1647, 0, 0, 40000, 80,0 },
+ {1648,1648, 0, 0, 40000, 80,0 },
+ {1649,1649, 0, 0, 40000, 80,0 },
+ {1650,1650, 0, 0, 40000, 146,0 },
+ {1651,1651, 0, 0, 40000, 1280,0 },
+ {1652,1652, 0, 0, 40000, 513,0 },
+ {1653,1653, 0, 0, 40000, 313,0 },
+ {1654,1654, 0, 0, 40000, 773,0 },
+ {1655,1655, 0, 0, 7400, 2480,0 },
+ {1656,1656, 0, 0, 3760, 1253,0 },
+ {1657,1657, 0, 0, 40000, 380,0 },
+ {1658,1658, 0, 0, 40000, 333,0 },
+ {1659,1659, 0, 0, 40000, 2926,0 },
+ {1660,1660, 0, 0, 40000, 5666,0 },
+ {1661,1661, 0, 0, 40000, 1613,0 },
+ {1662,1662, 0, 0, 3746, 1273,0 },
+ {1663,1663, 0, 0, 13653, 0,0 },
+ {1664,1664, 0, 0, 4640, 1553,0 },
+ {1665,1665, 0, 0, 40000, 680,0 },
+ {1666,1666, 0, 0, 6393, 426,0 },
+ {1667,1667, 0, 0, 40000, 713,0 },
+ {1668,1668, 12, 0, 166, 20,0 },
+ {1669,1669, 48, 0, 460, 193,0 },
+ { 736, 736, 52, 0, 286, 20,0 },
+ {1670,1670, 48, 0, 506, 200,0 },
+ {1670,1670, 36, 0, 713, 260,0 },
+ { 377, 377, 84, 0, 386, 493,0 },
+ { 730, 730, 95, 0, 1886, 653,0 },
+ {1669,1669, 84, 0, 386, 166,0 },
+ { 755, 755, 20, 0, 633, 240,0 },
+ { 755, 755, 22, 0, 626, 240,0 },
+ { 755, 755, 24, 0, 633, 246,0 },
+ {1671,1671, 0, 0, 2233, 220,0 },
+ {1672,1672, 0, 0, 2233, 240,0 },
+ {1673,1673, 0, 0, 2233, 206,0 },
+ {1674,1674, 0, 0, 2126, 173,0 },
+ {1675,1675, 0, 0, 7473, 73,0 },
+ {1676,1676, 0, 0, 40000, 0,0 },
+ {1677,1677, 0, 0, 3493, 193,0 },
+ {1678,1678, 0, 0, 1746, 73,0 },
+ {1679,1679, 0, 0, 1013, 400,0 },
+ {1680,1680, 0, 0, 3473, 1560,0 },
+ {1681,1681, 0, 0, 1073, 40,0 },
+ {1682,1682, 0, 0, 40000, 380,0 },
+ {1683,1683, 0, 0, 1166, 400,0 },
+ {1684,1684, 0, 0, 606, 146,0 },
+ {1685,1685, 0, 0, 4553, 1486,0 },
+ {1686,1686, 0, 0, 1126, 80,0 },
+ {1687,1687, 0, 0, 40000, 73,0 },
+ {1688,1688, 0, 0, 40000, 60,0 },
+ {1689,1689, 0, 0, 40000, 66,0 },
+ {1690,1690, 0, 0, 40000, 73,0 },
+ {1691,1691, 0, 0, 40000, 73,0 },
+ {1692,1692, 0, 0, 40000, 73,0 },
+ {1693,1693, 0, 0, 40000, 73,0 },
+ {1694,1694, 0, 0, 6380, 53,0 },
+ {1695,1695, 0, 0, 6380, 60,0 },
+ {1696,1696, 0, 0, 40000, 53,0 },
+ {1697,1697, 0, 0, 40000, 0,0 },
+ {1698,1698, 0, 0, 1880, 80,0 },
+ {1699,1699, 0, 0, 40000, 60,0 },
+ {1700,1700, 0, 0, 40000, 60,0 },
+ {1701,1701, 0, 0, 1460, 80,0 },
+ {1702,1702, 0, 0, 40000, 73,0 },
+ {1703,1703, 0, 0, 40000, 0,0 },
+ {1704,1704, 0, 0, 40000, 146,0 },
+ {1705,1705, 0, 0, 40000, 66,0 },
+ {1706,1706, 0, 0, 40000, 73,0 },
+ {1707,1707, 0, 0, 40000, 160,0 },
+ {1708,1708, 0, 0, 40000, 73,0 },
+ {1709,1709, 0, 0, 40000, 193,0 },
+ {1710,1710, 0, 0, 3740, 1260,0 },
+ {1711,1711, 0, 0, 40000, 180,0 },
+ {1712,1712, 0, 0, 40000, 173,0 },
+ {1713,1713, 0, 0, 40000, 113,0 },
+ {1714,1714, 0, 0, 40000, 86,0 },
+ {1715,1715, 0, 0, 1853, 633,0 },
+ {1716,1716, 0, 0, 40000, 0,0 },
+ {1717,1717, 0, 0, 1066, 306,0 },
+ {1718,1718, 0, 0, 40000, 86,0 },
+ {1719,1719, 0, 0, 40000, 586,0 },
+ {1720,1720, 0, 0, 40000, 86,0 },
+ {1721,1721, 0, 0, 40000, 93,0 },
+ {1722,1722, 0, 0, 40000, 373,0 },
+ {1723,1723, 0, 0, 40000, 113,0 },
+ {1724,1724, 0, 0, 40000, 353,0 },
+ {1725,1725, 0, 0, 420, 73,0 },
+ {1726,1726, 0, 0, 40000, 66,0 },
+ {1727,1727, 0, 0, 40000, 53,0 },
+ {1728,1728, 0, 0, 40000, 66,0 },
+ {1729,1729, 0, 0, 40000, 100,0 },
+ {1730,1730, 0, 0, 40000, 93,0 },
+ {1731,1731, 0, 0, 40000, 0,0 },
+ {1732,1732, 0, 0, 40000, 73,0 },
+ {1733,1733, 0, 0, 40000, 80,0 },
+ {1734,1734, 0, 0, 40000, 80,0 },
+ {1735,1735, 0, 0, 40000, 80,0 },
+ {1736,1736, 0, 0, 40000, 80,0 },
+ {1737,1737, 0, 0, 40000, 80,0 },
+ {1738,1738, 0, 0, 40000, 73,0 },
+ {1739,1739, 0, 0, 40000, 73,0 },
+ {1740,1740, 0, 0, 40000, 106,0 },
+ {1741,1741, 0, 0, 40000, 73,0 },
+ {1742,1742, 0, 0, 40000, 73,0 },
+ {1743,1743, 0, 0, 40000, 80,0 },
+ {1744,1744, 0, 0, 40000, 0,0 },
+ {1745,1745, 0, 0, 40000, 80,0 },
+ {1746,1746, 0, 0, 40000, 66,0 },
+ {1747,1747, 0, 0, 40000, 73,0 },
+ {1748,1748, 0, 0, 40000, 0,0 },
+ {1749,1749, 0, 0, 40000, 80,0 },
+ {1750,1750, 0, 0, 40000, 66,0 },
+ {1751,1751, 0, 0, 40000, 73,0 },
+ {1752,1752, 0, 0, 40000, 80,0 },
+ {1753,1753, 0, 0, 40000, 33,0 },
+ {1754,1754, 0, 0, 40000, 0,0 },
+ {1755,1755, 0, 0, 40000, 266,0 },
+ {1756,1756, 0, 0, 40000, 160,0 },
+ {1757,1757, 0, 0, 40000, 93,0 },
+ {1758,1758, 0, 0, 40000, 660,0 },
+ {1759,1759, 0, 0, 40000, 1453,0 },
+ {1760,1760, 0, 0, 40000, 660,0 },
+ {1761,1761, 0, 0, 40000, 120,0 },
+ {1762,1762, 0, 0, 40000, 140,0 },
+ {1763,1763, 0, 0, 9820, 393,0 },
+ {1764,1764, 0, 0, 40000, 73,0 },
+ {1765,1765, 0, 0, 3620, 1166,0 },
+ {1766,1766, 0, 0, 40000, 0,0 },
+ {1767,1767, 0, 0, 40000, 0,0 },
+ {1768,1768, 0, 0, 40000, 813,0 },
+ {1769,1769, 0, 0, 40000, 0,0 },
+ {1770,1770, 0, 0, 40000, 2386,0 },
+ {1771,1771, 0, 0, 4380, 400,0 },
+ {1772,1772, 0, 0, 853, 0,0 },
+ {1773,1773, 0, 0, 3700, 93,0 },
+ {1774,1774, 0, 0, 1580, 300,0 },
+ {1775,1775, 0, 0, 453, 140,0 },
+ {1776,1776, 0, 0, 40000, 66,0 },
+ {1777,1777, 0, 0, 40000, 73,0 },
+ {1778,1778, 0, 0, 40000, 206,0 },
+ {1779,1779, 0, 0, 4646, 1560,0 },
+ {1780,1780, 0, 0, 353, 146,0 },
+ {1781,1781, 0, 0, 1300, 400,0 },
+ {1782,1782, 0, 0, 4593, 1546,0 },
+ {1783,1783, 0, 0, 613, 226,0 },
+ {1784,1784, 0, 0, 626, 233,0 },
+ {1785,1785, 0, 0, 3020, 66,0 },
+ {1786,1786, 0, 0, 1093, 186,0 },
+ {1787,1787, 0, 0, 6053, 1240,0 },
+ {1788,1788, 0, 0, 633, 126,0 },
+ {1789,1789, 0, 0, 40000, 66,0 },
+ {1790,1790, 0, 0, 40000, 73,0 },
+ {1791,1791, 0, 0, 40000, 1253,0 },
+ {1792,1792, 0, 0, 626, 246,0 },
+ {1793,1793, 48, 0, 293, 120,0 },
+ {1794,1794, 48, 0, 100, 0,0 },
+ {1795,1795, 60, 0, 240, 133,0 },
+ {1796,1796, 60, 0, 160, 66,0 },
+ {1797,1797, 70, 0, 140, 33,0 },
+ {1798,1798, 51, 0, 526, 206,0 },
+ {1799,1799, 60, 0, 173, 93,0 },
+ {1798,1798, 54, 0, 520, 200,0 },
+ {1800,1800, 60, 0, 153, 80,0 },
+ {1798,1798, 56, 0, 520, 206,0 },
+ {1801,1801, 60, 0, 673, 206,0 },
+ {1798,1798, 61, 0, 506, 200,0 },
+ {1798,1798, 63, 0, 513, 206,0 },
+ {1802,1802, 48, 0, 673, 200,0 },
+ {1798,1798, 68, 0, 440, 180,0 },
+ {1803,1803, 60, 0, 1873, 653,0 },
+ {1804,1804, 60, 0, 673, 200,0 },
+ {1805,1805, 66, 0, 306, 120,0 },
+ {1806,1806, 60, 0, 673, 200,0 },
+ { 379, 379, 59, 0, 173, 93,0 },
+ {1802,1802, 64, 0, 673, 206,0 },
+ {1807,1807, 48, 0, 1006, 20,0 },
+ {1808,1808, 56, 0, 120, 40,0 },
+ {1809,1809, 53, 0, 286, 133,0 },
+ {1810,1810, 65, 0, 106, 0,0 },
+ {1811,1811, 49, 0, 293, 133,0 },
+ {1811,1811, 43, 0, 293, 133,0 },
+ { 386, 386, 65, 0, 1013, 673,0 },
+ { 386, 386, 60, 0, 1000, 660,0 },
+ {1812,1812, 70, 0, 260, 113,0 },
+ {1812,1812, 65, 0, 306, 120,0 },
+ {1813,1813, 60, 0, 246, 106,0 },
+ {1814,1814, 60, 0, 193, 120,0 },
+ {1815,1815, 56, 0, 206, 13,0 },
+ {1816,1816, 53, 0, 433, 73,0 },
+ {1817,1817, 60, 0, 220, 113,0 },
+ {1818,1818, 48, 0, 300, 66,0 },
+ {1819,1819, 69, 0, 126, 0,0 },
+ { 328, 328, 67, 0, 140, 93,0 },
+ { 328, 328, 62, 0, 153, 100,0 },
+ {1820,1820, 65, 0, 433, 100,0 },
+ {1821,1821, 60, 0, 426, 100,0 },
+ {1822,1822, 63, 0, 113, 46,0 },
+ {1823,1823, 63, 0, 1866, 653,0 },
+ {1824,1824, 67, 0, 273, 60,0 },
+ {1825,1825, 60, 0, 973, 360,0 },
+ {1825,1825, 72, 0, 806, 273,0 },
+ { 401, 401, 62, 0, 46, 0,0 },
+ {1826,1826, 48, 0, 126, 66,0 },
+ {1827,1827, 53, 0, 980, 353,0 },
+ {1828,1828, 60, 0, 293, 133,0 },
+ {1829,1829, 60, 0, 160, 20,0 },
+ {1830,1830, 60, 0, 126, 86,0 },
+ {1831,1831, 60, 0, 173, 93,0 },
+ {1832,1832, 0, 0, 40000, 106,0 },
+ {1833,1833, 0, 0, 3780, 73,0 },
+ {1834,1834, 0, 0, 3820, 1666,0 },
+ {1835,1835, 0, 0, 40000, 73,0 },
+ {1836,1836, 0, 0, 40000, 333,0 },
+ {1837,1837, 0, 0, 40000, 220,0 },
+ {1838,1838, 0, 0, 40000, 0,0 },
+ {1839,1839, 0, 0, 40000, 53,0 },
+ {1840,1840, 0, 0, 40000, 60,0 },
+ {1841,1841, 0, 0, 5913, 2306,0 },
+ {1842,1842, 0, 0, 7713, 2466,0 },
+ { 525, 525, 0, 0, 4660, 660,0 },
+ {1843,1843, 0, 0, 40000, 313,0 },
+ {1844,1844, 0, 0, 40000, 0,0 },
+ {1845,1845, 0, 0, 40000, 0,0 },
+ {1846,1846, 0, 0, 1246, 453,0 },
+ {1847,1847, 0, 0, 9600, 1580,0 },
+ {1848,1848, 0, 0, 40000, 106,0 },
+ {1849,1849, 0, 0, 2040, 400,0 },
+ {1850,1850, 0, 0, 40000, 73,0 },
+ {1851,1851, 0, 0, 4220, 620,0 },
+ {1852,1852, 0, 0, 40000, 0,0 },
+ {1853,1853, 0, 0, 40000, 433,0 },
+ {1854,1854, 0, 0, 40000, 66,0 },
+ {1855,1855, 0, 0, 40000, 46,0 },
+ {1856,1856, 0, 0, 40000, 240,0 },
+ {1857,1857, 0, 0, 40000, 313,0 },
+ {1858,1858, 0, 0, 40000, 26,0 },
+ {1859,1859, 0, 0, 40000, 0,0 },
+ {1860,1860, 0, 0, 40000, 73,0 },
+ {1861,1861, 0, 0, 6940, 66,0 },
+ {1862,1862, 0, 0, 40000, 0,0 },
+ {1863,1863, 0, 0, 40000, 60,0 },
+ {1864,1864, 0, 0, 8140, 1440,0 },
+ {1865,1865, 0, 0, 40000, 0,0 },
+ {1866,1866, 0, 0, 40000, 613,0 },
+ {1867,1867, 0, 0, 40000, 0,0 },
+ {1868,1868, 0, 0, 633, 233,0 },
+ {1869,1869, 0, 0, 40000, 226,0 },
+ {1870,1870, 0, 0, 2280, 746,0 },
+ {1871,1871, 0, 0, 1940, 633,0 },
+ {1872,1872, 0, 0, 4220, 620,0 },
+ {1873,1873, 0, 0, 40000, 133,0 },
+ {1874,1874, 41, 0, 380, 153,0 },
+ {1875,1875, 70, 0, 106, 0,0 },
+ {1876,1876, 60, 0, 380, 206,0 },
+ {1877,1877, 80, 0, 100, 0,0 },
+ {1878,1878, 84, 0, 120, 0,0 },
+ {1879,1879, 72, 0, 500, 433,0 },
+ {1880,1880, 84, 0, 860, 553,0 },
+ { 128, 128, 70, 0, 106, 0,0 },
+ { 132, 132, 60, 0, 146, 86,0 },
+ {1881,1882, 0, 4, 40000, 260,0 },
+ {1883,1883, 0, 0, 40000, 0,0 },
+ {1884,1885, 0, 4, 40000, 73,0 },
+ {1886,1887, 0, 4, 40000, 86,0 },
+ {1888,1889, 0, 4, 40000, 73,0 },
+ {1890,1890, 0, 0, 40000, 300,0 },
+ {1891,1891, 0, 0, 40000, 693,0 },
+ {1892,1892, 0, 0, 40000, 586,0 },
+ {1893,1893, 0, 0, 40000, 286,0 },
+ {1894,1894, 0, 0, 1620, 773,0 },
+ {1895,1895, 0, 0, 40000, 0,0 },
+ {1896,1896, 0, 0, 40000, 193,0 },
+ {1897,1897, 0, 0, 1873, 820,0 },
+ {1898,1898, 0, 0, 4520, 753,0 },
+ {1899,1899, 0, 0, 40000, 0,0 },
+ {1900,1900, 0, 0, 40000, 220,0 },
+ {1901,1901, 0, 0, 40000, 133,0 },
+ {1902,1902, 0, 0, 40000, 73,0 },
+ {1903,1903, 0, 0, 40000, 0,0 },
+ {1904,1904, 0, 0, 7326, 2420,0 },
+ {1905,1905, 0, 0, 1186, 446,0 },
+ {1906,1906, 0, 0, 40000, 553,0 },
+ {1907,1907, 0, 0, 40000, 293,0 },
+ {1908,1908, 0, 0, 40000, 586,0 },
+ {1909,1909, 0, 0, 2326, 793,0 },
+ { 501, 501, 0, 0, 480, 226,0 },
+ {1910,1910, 0, 0, 40000, 93,0 },
+ {1911,1911, 0, 0, 620, 226,0 },
+ {1912,1912, 0, 0, 2373, 800,0 },
+ {1913,1913, 0, 0, 40000, 4986,0 },
+ {1914,1914, 0, 0, 626, 240,0 },
+ { 511, 511, 0, 0, 2326, 800,0 },
+ {1915,1915, 0, 0, 340, 146,0 },
+ {1910,1910, 60, 0, 40000, 93,0 },
+ { 511, 511, 72, 0, 1566, 546,0 },
+ {1915,1915, 84, 0, 246, 120,0 },
+ {1916,1916, 0, 0, 40000, 0,0 },
+ {1917,1917, 0, 0, 2713, 666,0 },
+ {1918,1918, 0, 0, 40000, 0,0 },
+ {1919,1919, 0, 0, 40000, 46,0 },
+ {1920,1920, 0, 0, 40000, 0,0 },
+ {1921,1921, 0, 0, 40000, 53,0 },
+ {1922,1922, 0, 0, 40000, 33,0 },
+ {1923,1923, 0, 0, 2073, 193,0 },
+ {1924,1924, 0, 0, 40000, 146,0 },
+ {1925,1925, 0, 0, 40000, 100,0 },
+ {1926,1926, 0, 0, 40000, 93,0 },
+ {1927,1927, 0, 0, 40000, 73,0 },
+ {1928,1928, 0, 0, 40000, 540,0 },
+ {1929,1929, 0, 0, 40000, 520,0 },
+ {1930,1930, 0, 0, 40000, 506,0 },
+ {1931,1931, 0, 0, 7406, 200,0 },
+ {1932,1932, 0, 0, 5906, 133,0 },
+ {1933,1933, 0, 0, 7426, 240,0 },
+ {1934,1934, 0, 0, 7426, 240,0 },
+ {1935,1935, 0, 0, 40000, 66,0 },
+ {1936,1936, 0, 0, 40000, 66,0 },
+ {1937,1937, 0, 0, 40000, 53,0 },
+ {1938,1938, 0, 0, 40000, 66,0 },
+ {1939,1939, 0, 0, 40000, 66,0 },
+ {1940,1940, 0, 0, 40000, 53,0 },
+ {1941,1941, 0, 0, 40000, 2146,0 },
+ {1942,1942, 0, 0, 40000, 1126,0 },
+ {1943,1943, 0, 0, 40000, 1020,0 },
+ {1944,1944, 0, 0, 40000, 433,0 },
+ {1945,1945, 0, 0, 40000, 0,0 },
+ {1946,1946, 0, 0, 40000, 140,0 },
+ {1947,1947, 0, 0, 4660, 660,0 },
+ {1948,1948, 0, 0, 40000, 66,0 },
+ {1949,1949, 0, 0, 40000, 4193,0 },
+ {1950,1950, 0, 0, 7713, 2466,0 },
+ {1951,1951, 0, 0, 40000, 73,0 },
+ {1952,1952, 0, 0, 8100, 2093,0 },
+ {1953,1953, 0, 0, 40000, 86,0 },
+ {1954,1954, 0, 0, 40000, 80,0 },
+ {1955,1955, 0, 0, 4113, 1526,0 },
+ {1956,1956, 0, 0, 40000, 66,0 },
+ {1957,1957, 0, 0, 40000, 100,0 },
+ {1958,1958, 0, 0, 40000, 213,0 },
+ {1959,1959, 0, 0, 40000, 100,0 },
+ {1960,1960, 0, 0, 1186, 100,0 },
+ {1961,1961, 0, 0, 40000, 433,0 },
+ {1962,1962, 0, 0, 40000, 146,0 },
+ {1963,1963, 0, 0, 40000, 400,0 },
+ {1964,1964, 0, 0, 40000, 66,0 },
+ {1965,1965, 0, 0, 40000, 193,0 },
+ {1966,1966, 0, 0, 1153, 100,0 },
+ {1967,1967, 0, 0, 4800, 1400,0 },
+ {1968,1968, 0, 0, 2906, 713,0 },
+ {1969,1969, 0, 0, 40000, 73,0 },
+ {1970,1970, 0, 0, 2280, 746,0 },
+ {1971,1971, 0, 0, 40000, 66,0 },
+ {1972,1972, 0, 0, 40000, 86,0 },
+ {1973,1973, 0, 0, 40000, 86,0 },
+ {1974,1974, 0, 0, 40000, 66,0 },
+ {1975,1975, 0, 0, 40000, 66,0 },
+ {1976,1976, 0, 0, 40000, 66,0 },
+ {1977,1977, 0, 0, 40000, 46,0 },
+ {1978,1978, 0, 0, 40000, 73,0 },
+ {1979,1979, 0, 0, 40000, 73,0 },
+ {1980,1980, 0, 0, 40000, 66,0 },
+ {1981,1981, 0, 0, 40000, 66,0 },
+ {1982,1982, 0, 0, 40000, 66,0 },
+ {1983,1983, 0, 0, 40000, 73,0 },
+ {1984,1984, 0, 0, 40000, 73,0 },
+ {1985,1985, 0, 0, 40000, 253,0 },
+ {1986,1986, 0, 0, 40000, 126,0 },
+ {1987,1987, 0, 0, 40000, 126,0 },
+ {1988,1988, 0, 0, 40000, 66,0 },
+ {1989,1989, 0, 0, 40000, 66,0 },
+ {1990,1990, 0, 0, 40000, 53,0 },
+ {1991,1991, 0, 0, 40000, 140,0 },
+ {1992,1992, 0, 0, 40000, 40,0 },
+ {1993,1993, 0, 0, 40000, 73,0 },
+ {1994,1994, 0, 0, 40000, 66,0 },
+ {1995,1995, 0, 0, 40000, 73,0 },
+ {1996,1996, 0, 0, 40000, 73,0 },
+ {1997,1997, 0, 0, 40000, 73,0 },
+ {1998,1998, 0, 0, 40000, 73,0 },
+ {1999,1999, 0, 0, 40000, 66,0 },
+ {2000,2000, 0, 0, 40000, 433,0 },
+ {2001,2001, 0, 0, 40000, 433,0 },
+ {2002,2002, 0, 0, 2440, 706,0 },
+ {2003,2003, 0, 0, 13960, 4800,0 },
+ {2004,2004, 0, 0, 7393, 2480,0 },
+ {2005,2005, 0, 0, 7220, 2073,0 },
+ {2006,2006, 0, 0, 633, 233,0 },
+ {2007,2007, 0, 0, 2326, 780,0 },
+ {2008,2008, 0, 0, 40000, 73,0 },
+ {2009,2009, 0, 0, 40000, 106,0 },
+ {2010,2010, 0, 0, 40000, 126,0 },
+ {2011,2011, 0, 0, 40000, 386,0 },
+ {2012,2012, 0, 0, 40000, 66,0 },
+ {2013,2013, 0, 0, 6893, 1273,0 },
+ {2014,2014, 0, 0, 2546, 633,0 },
+ {2015,2015, 0, 0, 206, 106,0 },
+ {2016,2016, 0, 0, 213, 113,0 },
+ {2017,2017, 0, 0, 360, 140,0 },
+ {2018,2018, 0, 0, 1013, 193,0 },
+ {2019,2019, 0, 0, 266, 66,0 },
+ {2020,2020, 0, 0, 1880, 660,0 },
+ {2021,2021, 0, 0, 286, 206,0 },
+ {2022,2022, 0, 0, 3706, 1353,0 },
+ {2023,2023, 0, 0, 1106, 380,0 },
+ {2024,2024, 0, 0, 13220, 2466,0 },
+ {2025,2025, 0, 0, 333, 26,0 },
+ {2026,2026, 0, 0, 7346, 2440,0 },
+ {2027,2027, 0, 0, 1273, 453,0 },
+ { 352, 352, 51, 2, 6, 0,0 },
+ {2028,2028, 35, 0, 700, 253,0 },
+ {2028,2028, 36, 0, 706, 266,0 },
+ {2029,2029, 47, 0, 100, 0,0 },
+ {2030,2030, 38, 0, 346, 140,0 },
+ {2019,2019, 39, 0, 220, 106,0 },
+ {2031,2031, 45, 0, 286, 133,0 },
+ { 492, 492, 41, 0, 1040, 406,0 },
+ {2032,2032, 42, 0, 220, 106,0 },
+ {2033,2033, 44, 0, 500, 193,0 },
+ { 492, 492, 48, 0, 833, 346,0 },
+ {2034,2034, 46, 0, 1866, 646,0 },
+ { 492, 492, 53, 0, 873, 386,0 },
+ { 167, 167, 56, 0, 646, 353,0 },
+ {2035,2035, 61, 0, 366, 146,0 },
+ {2036,2036, 56, 0, 1346, 473,0 },
+ {2037,2037, 60, 0, 213, 126,0 },
+ { 144, 144, 59, 0, 213, 0,0 },
+ {2038,2038, 59, 0, 106, 0,0 },
+ { 169, 169, 51, 0, 380, 366,0 },
+ { 169, 169, 45, 0, 380, 366,0 },
+ {2039,2039, 72, 0, 246, 20,0 },
+ {2040,2040, 60, 0, 280, 20,0 },
+ {2041,2041, 58, 0, 373, 360,0 },
+ {2042,2042, 53, 0, 380, 366,0 },
+ {2043,2043, 73, 0, 120, 26,0 },
+ { 158, 158, 75, 0, 126, 140,0 },
+ {2044,2044, 0, 0, 6786, 1073,0 },
+ {2045,2045, 0, 0, 2046, 473,0 },
+ {2046,2046, 0, 0, 3746, 1273,0 },
+ {2047,2047, 0, 0, 1200, 3086,0 },
+ {2048,2048, 0, 0, 1200, 3080,0 },
+ {2049,2049, 0, 0, 40000, 2453,0 },
+ {2050,2050, 0, 0, 40000, 413,0 },
+ {2051,2051, 0, 0, 980, 2553,0 },
+ {2052,2052, 0, 0, 40000, 2420,0 },
+ {2053,2053, 0, 0, 40000, 2506,0 },
+ {2054,2054, 0, 0, 40000, 380,0 },
+ {2055,2055, 0, 0, 40000, 660,0 },
+ {2056,2056, 0, 0, 40000, 73,0 },
+ {2057,2057, 0, 0, 40000, 333,0 },
+ {2058,2058, 0, 0, 833, 146,0 },
+ {2059,2059, 0, 0, 1686, 620,0 },
+ {2060,2060, 0, 0, 40000, 73,0 },
+ {2061,2061, 0, 0, 40000, 0,0 },
+ {2062,2062, 0, 0, 1873, 633,0 },
+ {2063,2063, 0, 0, 40000, 380,0 },
+ {2064,2064, 0, 0, 366, 286,0 },
+ {2065,2065, 0, 0, 8866, 1366,0 },
+ {2066,2066, 0, 0, 40000, 1513,0 },
+ {2067,2067, 0, 0, 40000, 333,0 },
+ {2068,2068, 0, 0, 9600, 1573,0 },
+ {2069,2069, 0, 0, 3293, 746,0 },
+ {2070,2070, 0, 0, 40000, 53,0 },
+ {2071,2071, 0, 0, 40000, 73,0 },
+ {2072,2072, 0, 0, 40000, 73,0 },
+ {2073,2073, 0, 0, 40000, 240,0 },
+ {2074,2074, 0, 0, 40000, 240,0 },
+ {2075,2075, 0, 0, 40000, 140,0 },
+ {2076,2076, 0, 0, 40000, 113,0 },
+ {2077,2077, 0, 0, 40000, 240,0 },
+ {2078,2078, 0, 0, 3613, 1146,0 },
+ {2079,2079, 0, 0, 40000, 126,0 },
+ {2080,2080, 0, 0, 40000, 0,0 },
+ {2081,2081, 0, 0, 40000, 633,0 },
+ {2082,2082, 0, 0, 40000, 453,0 },
+ {2083,2083, 0, 0, 40000, 1146,0 },
+ {2084,2084, 0, 0, 40000, 3600,0 },
+ {2085,2085, 0, 0, 40000, 1586,0 },
+ {2086,2086, 0, 0, 40000, 1586,0 },
+ {2087,2087, 0, 0, 40000, 1586,0 },
+ {2088,2088, 0, 0, 40000, 1646,0 },
+ {2089,2089, 0, 0, 40000, 1580,0 },
+ {2090,2090, 0, 0, 40000, 4393,0 },
+ {2091,2091, 0, 0, 40000, 4540,0 },
+ {2092,2092, 0, 0, 21373, 6160,0 },
+ {2093,2093, 0, 0, 40000, 633,0 },
+ {2094,2094, 0, 0, 18420, 6146,0 },
+ {2095,2095, 0, 0, 2306, 813,0 },
+ {2096,2096, 0, 0, 2813, 333,0 },
+ {2097,2097, 0, 0, 3106, 600,0 },
+ {2098,2098, 0, 0, 1026, 1580,0 },
+ {2099,2099, 0, 0, 1873, 346,0 },
+ {2100,2100, 0, 0, 40000, 73,0 },
+ {2101,2101, 0, 0, 40000, 73,0 },
+ {2102,2102, 0, 0, 1200, 1906,0 },
+ {2103,2103, 0, 0, 980, 1313,0 },
+ {2104,2104, 0, 0, 200, 20,0 },
+ {2105,2105, 0, 0, 640, 253,0 },
+ {2106,2106, 0, 0, 3120, 240,0 },
+ {2107,2107, 0, 0, 753, 146,0 },
+ {2108,2108, 0, 0, 40000, 3060,0 },
+ {2109,2109, 0, 0, 40000, 233,0 },
+ {2110,2110, 0, 0, 40000, 246,0 },
+ {2111,2111, 0, 0, 40000, 240,0 },
+ { 752, 752, 60, 0, 173, 20,0 },
+ { 755, 755, 12, 0, 626, 240,0 },
+ {2112,2112, 89, 0, 113, 0,0 },
+ {2113,2113, 89, 0, 700, 266,0 },
+ { 755, 755, 14, 0, 626, 240,0 },
+ { 755, 755, 16, 0, 626, 246,0 },
+ {2114,2114, 84, 0, 1593, 553,0 },
+ { 755, 755, 19, 0, 626, 240,0 },
+ {2115,2115, 38, 0, 220, 166,0 },
+ {2116,2116, 36, 0, 1686, 760,0 },
+ { 755, 755, 28, 0, 626, 240,0 },
+ { 755, 755, 26, 0, 626, 240,0 },
+ { 755, 755, 35, 0, 633, 246,0 },
+ { 755, 755, 30, 0, 626, 240,0 },
+ {2117,2117, 60, 0, 180, 53,0 },
+ {2104,2104, 60, 0, 173, 20,0 },
+ {2104,2104, 55, 0, 173, 20,0 },
+ { 730, 730, 94, 0, 1886, 660,0 },
+ {2118,2118, 0, 0, 1226, 73,0 },
+ {2119,2119, 0, 0, 40000, 0,0 },
+ {2120,2120, 0, 0, 40000, 146,0 },
+ {2121,2121, 0, 0, 40000, 80,0 },
+ {2122,2122, 0, 0, 40000, 80,0 },
+ {2123,2123, 0, 0, 40000, 0,0 },
+ {2124,2124, 0, 0, 40000, 126,0 },
+ {2125,2125, 0, 0, 40000, 213,0 },
+ {2126,2126, 0, 0, 40000, 80,0 },
+ {2127,2127, 0, 0, 40000, 73,0 },
+ {2128,2128, 0, 0, 40000, 73,0 },
+ {2129,2129, 0, 0, 40000, 73,0 },
+ {2130,2130, 0, 0, 40000, 80,0 },
+ {2131,2131, 0, 0, 40000, 73,0 },
+ {2132,2132, 0, 0, 40000, 73,0 },
+ {2133,2133, 0, 0, 40000, 66,0 },
+ {2134,2134, 0, 0, 40000, 186,0 },
+ {2135,2135, 0, 0, 9966, 426,0 },
+ {2136,2136, 0, 0, 40000, 400,0 },
+ {2137,2137, 0, 0, 40000, 326,0 },
+ {2138,2138, 0, 0, 386, 80,0 },
+ {2139,2139, 0, 0, 40000, 246,0 },
+ {2140,2140, 0, 0, 3473, 73,0 },
+ {2141,2141, 60, 0, 160, 66,0 },
+ {2141,2141, 44, 0, 160, 60,0 },
+ {2142,2142, 47, 0, 173, 93,0 },
+ {2143,2143, 47, 0, 186, 80,0 },
+ {2144,2144, 62, 0, 1933, 93,0 },
+ {2145,2145, 93, 0, 1146, 473,0 },
+ {2146,2146, 50, 0, 286, 93,0 },
+ {2145,2145, 40, 0, 2013, 840,0 },
+ {2147,2147, 60, 0, 106, 73,0 },
+ { 898, 898, 60, 0, 173, 133,0 },
+ {2147,2147, 57, 0, 106, 73,0 },
+ { 900, 900, 42, 0, 620, 240,0 },
+ { 900, 900, 38, 0, 626, 240,0 },
+ { 908, 908, 88, 0, 160, 26,0 },
+ {2148,2148, 0, 0, 9440, 140,0 },
+ {2149,2149, 0, 0, 40000, 73,0 },
+ {2150,2150, 0, 0, 4613, 420,0 },
+ {2151,2151, 0, 0, 40000, 86,0 },
+ {2152,2152, 0, 0, 40000, 406,0 },
+ {2153,2153, 0, 0, 40000, 440,0 },
+ {2154,2154, 0, 0, 4340, 133,0 },
+ {2155,2155, 0, 0, 4460, 706,0 },
+ {2156,2156, 0, 0, 40000, 73,0 },
+ {2157,2157, 0, 0, 4660, 1573,0 },
+ {2158,2158, 0, 0, 966, 333,0 },
+ {2159,2159, 0, 0, 1933, 640,0 },
+ { 136, 136, 0, 0, 2326, 786,0 },
+ { 168, 168, 0, 0, 286, 366,0 },
+ { 164, 164, 0, 0, 7373, 2460,0 },
+ { 167, 167, 0, 0, 793, 426,0 },
+ {2160,2160, 65, 0, 166, 73,0 },
+ {2161,2161, 21, 0, 480, 146,0 },
+ {2162, 173, 0, 4, 4220, 80,0 },
+ {2163,2164, 0, 4, 4640, 3066,0 },
+ {2165,2166, 0, 4, 7273, 3920,0 },
+ {2167,2168, 0, 4, 3766, 1253,0 },
+ {2169,2170, 0, 4, 6266, 2400,0 },
+ {2171,2172, 0, 4, 18213, 0,0 },
+ {2173,2174, 0, 4, 40000, 713,0 },
+ {2175,2174, 0, 4, 40000, 733,0 },
+ {2176, 299, 0, 4, 40000, 273,0 },
+ {2177,2178, 0, 4, 40000, 66,0 },
+ {2179,2180, 0, 4, 40000, 393,0 },
+ {2181,2182, 0, 4, 40000, 413,0 },
+ {2183,2184, 0, 4, 7406, 200,0 },
+ { 127, 127, 65, 0, 226, 120,0 },
+ { 127, 127, 72, 0, 180, 100,0 },
+ { 364, 365, 52, 4, 120, 0,0 },
+ {2185,2186, 60, 4, 173, 0,0 },
+ {1550,1551, 47, 4, 520, 0,0 },
+ {1556,1557, 76, 4, 833, 0,0 },
+ { 374, 375, 84, 4, 813, 0,0 },
+ {1564,1565, 83, 4, 220, 0,0 },
+ {1568,1569, 24, 4, 1840, 620,0 },
+ {1556,1557, 77, 4, 820, 300,0 },
+ {1572,1573, 60, 4, 286, 0,0 },
+ {1574,1575, 65, 4, 293, 0,0 },
+ { 391, 392, 44, 4, 160, 53,0 },
+ { 391, 393, 40, 4, 460, 66,0 },
+ {1606,1607, 72, 4, 120, 73,0 },
+ { 398, 399, 73, 4, 1293, 173,0 },
+ {1608,1609, 70, 4, 1580, 0,0 },
+ {2187,2187, 0, 0, 40000, 353,0 },
+ {2188,2188, 0, 0, 40000, 333,0 },
+ {2189,2189, 0, 0, 5913, 2306,0 },
+ {2190,2190, 0, 0, 7720, 1260,0 },
+ {2191,2191, 0, 0, 213, 6420,0 },
+ {2192,2192, 0, 0, 40000, 380,0 },
+ {2193,2193, 0, 0, 1153, 760,0 },
+ {2194,2194, 0, 0, 40000, 66,0 },
+ {2195,2195, 0, 0, 4440, 66,0 },
+ {2196,2196, 0, 0, 40000, 73,0 },
+ {2197,2197, 0, 0, 40000, 53,0 },
+ {2198,2198, 0, 0, 40000, 60,0 },
+ {2199,2199, 0, 0, 40000, 60,0 },
+ {2200,2200, 0, 0, 8133, 1433,0 },
+ { 528, 528, 0, 0, 966, 346,0 },
+ {2201,2201, 0, 0, 40000, 126,0 },
+ {2202,2202, 0, 0, 286, 1293,0 },
+ {2203,2203, 0, 0, 40000, 0,0 },
+ {2204,2204, 41, 0, 246, 20,0 },
+ {2205,2205, 84, 0, 160, 26,0 },
+ {2206,2206, 72, 0, 440, 180,0 },
+ { 741, 741, 48, 0, 220, 26,0 },
+ {2207,2207, 0, 0, 2126, 173,0 },
+ {2208,2208, 0, 0, 40000, 0,0 },
+ {2209,2209, 0, 0, 40000, 380,0 },
+ {2210,2210, 0, 0, 4553, 1486,0 },
+ {2211,2211, 0, 0, 40000, 73,0 },
+ {2212,2212, 0, 0, 40000, 73,0 },
+ {2213,2213, 0, 0, 1460, 80,0 },
+ {2214,2214, 0, 0, 40000, 66,0 },
+ {2215,2215, 0, 0, 40000, 186,0 },
+ {2216,2216, 0, 0, 40000, 180,0 },
+ {2217,2217, 0, 0, 40000, 173,0 },
+ {2218,2218, 0, 0, 40000, 113,0 },
+ {2219,2219, 0, 0, 40000, 86,0 },
+ {2220,2220, 0, 0, 40000, 373,0 },
+ {2221,2221, 0, 0, 40000, 113,0 },
+ {2222,2222, 0, 0, 40000, 353,0 },
+ {2223,2223, 0, 0, 40000, 66,0 },
+ {2224,2224, 0, 0, 40000, 53,0 },
+ {2225,2225, 0, 0, 40000, 66,0 },
+ {2226,2226, 0, 0, 40000, 100,0 },
+ {2227,2227, 0, 0, 40000, 73,0 },
+ {2228,2228, 0, 0, 40000, 73,0 },
+ {2229,2229, 0, 0, 40000, 66,0 },
+ {2230,2230, 0, 0, 40000, 66,0 },
+ {2231,2231, 0, 0, 40000, 80,0 },
+ {2232,2232, 0, 0, 40000, 66,0 },
+ {2233,2233, 0, 0, 40000, 80,0 },
+ {2234,2234, 0, 0, 40000, 660,0 },
+ {2235,2235, 0, 0, 40000, 120,0 },
+ {2236,2236, 0, 0, 9820, 393,0 },
+ {2237,2237, 0, 0, 40000, 73,0 },
+ {2238,2238, 0, 0, 3620, 1166,0 },
+ {2239,2239, 0, 0, 40000, 0,0 },
+ {2240,2240, 0, 0, 40000, 0,0 },
+ {2241,2241, 0, 0, 3020, 66,0 },
+ {2242,2242, 0, 0, 6053, 1240,0 },
+ {2243,2243, 0, 0, 633, 126,0 },
+ {2244,2244, 0, 0, 40000, 66,0 },
+ {2245,2245, 0, 0, 40000, 73,0 },
+ {2246,2246, 0, 0, 626, 246,0 },
+ {2247,2247, 60, 0, 173, 93,0 },
+ {2248,2248, 60, 0, 673, 206,0 },
+ {2249,2249, 48, 0, 673, 200,0 },
+ {2250,2250, 60, 0, 1873, 653,0 },
+ {2251,2251, 60, 0, 673, 200,0 },
+ {2252,2252, 66, 0, 306, 120,0 },
+ {2253,2253, 60, 0, 673, 200,0 },
+ {2249,2249, 64, 0, 673, 206,0 },
+ {2254,2254, 60, 0, 246, 106,0 },
+ {2255,2255, 60, 0, 193, 120,0 },
+ {2256,2256, 56, 0, 206, 13,0 },
+ {2257,2257, 53, 0, 433, 73,0 },
+ {2258,2258, 60, 0, 220, 113,0 },
+ {2259,2259, 48, 0, 300, 66,0 },
+ {2260,2260, 67, 0, 273, 60,0 },
+ {2261,2261, 60, 0, 973, 360,0 },
+ {2261,2261, 72, 0, 806, 273,0 },
+ {2262,2262, 60, 0, 173, 93,0 },
+ {2263,2263, 0, 0, 2493, 866,0 },
+ {2264,2264, 24, 0, 173, 93,0 },
+ {2265,2265, 36, 0, 140, 0,0 },
+ { 343, 343, 36, 0, 146, 80,0 },
+ { 347, 347, 0, 0, 353, 133,0 },
+ { 347, 347, 12, 0, 420, 146,0 },
+ {2266,2266, 12, 0, 346, 100,0 },
+ {2267,2267, 24, 0, 106, 46,0 },
+ {2267,2267, 36, 0, 100, 0,0 },
+ {2268,2268, 0, 0, 1006, 293,0 },
+ {2266,2266, 24, 0, 293, 93,0 },
+ {2269,2269, 88, 0, 1106, 120,0 },
+ {2270,2270, 88, 0, 666, 120,0 },
+ {2271,2271, 13, 0, 760, 360,0 },
+ { 351, 351, 0, 0, 966, 346,0 },
+ {2271,2271, 15, 0, 760, 420,0 },
+ {2272,2272, 0, 0, 4513, 640,0 },
+ {2273,2273, 0, 0, 15486, 1580,0 },
+ {2274,2274, 0, 0, 6940, 66,0 },
+ {2275,2275, 0, 0, 6866, 2380,0 },
+ {2276,2276, 0, 0, 7613, 1566,0 },
+ {2277,2277, 0, 0, 1186, 420,0 },
+ {2278,2278, 0, 0, 1166, 400,0 },
+ {2279,2279, 0, 0, 40000, 2940,0 },
+ {2280,2280, 0, 0, 40000, 0,0 },
+ {2281,2281, 0, 0, 18226, 786,0 },
+ {2282,2282, 0, 0, 40000, 0,0 },
+ {2283,2283, 0, 0, 713, 200,0 },
+ {2284,2284, 0, 0, 40000, 126,0 },
+ {2285,2285, 0, 0, 40000, 353,0 },
+ {2286,2286, 0, 0, 40000, 333,0 },
+ {2287,2287, 0, 0, 40000, 0,0 },
+ {2288,2288, 0, 0, 40000, 0,0 },
+ {2289,2289, 0, 0, 40000, 0,0 },
+ {2290,2290, 0, 0, 40000, 0,0 },
+ {2291,2291, 0, 0, 40000, 73,0 },
+ {2292,2292, 0, 0, 40000, 66,0 },
+ {2293,2293, 0, 0, 15893, 153,0 },
+ {2294,2294, 0, 0, 40000, 253,0 },
+ {2295,2295, 0, 0, 2813, 333,0 },
+ {2296,2296, 0, 0, 40000, 3920,0 },
+ {2297,2297, 79, 0, 113, 0,0 },
+ {2297,2297, 72, 0, 126, 140,0 },
+ {2298,2298, 72, 0, 100, 26,0 },
+ {2298,2298, 79, 0, 100, 0,0 },
+ { 554, 554, 60, 0, 400, 126,0 },
+ {2299,2299, 72, 0, 793, 173,0 },
+ {2300,2300, 84, 0, 226, 66,0 },
+ { 555, 555, 66, 0, 113, 0,0 },
+ {2301,2302, 35, 4, 2333, 800,0 },
+ {2303,2304, 52, 4, 120, 0,0 },
+ {2305,1548, 48, 4, 173, 0,0 },
+ {1595,1595, 58, 0, 146, 166,0 },
+ {2305,1548, 60, 4, 173, 0,0 },
+ {2306,2307, 47, 4, 1893, 700,0 },
+ {2306,2307, 43, 4, 1953, 740,0 },
+ {2306,2307, 49, 4, 1880, 686,0 },
+ {2306,2307, 51, 4, 1886, 706,0 },
+ {2306,2307, 54, 4, 1906, 720,0 },
+ {2306,2307, 57, 4, 1900, 720,0 },
+ {2306,2307, 72, 4, 1593, 606,0 },
+ {2306,2307, 60, 4, 1900, 720,0 },
+ {2306,2307, 76, 4, 1593, 606,0 },
+ {2306,2307, 84, 4, 1593, 613,0 },
+ {2306,2307, 36, 4, 2386, 920,0 },
+ {1560,2308, 65, 4, 293, 213,0 },
+ {2309,2310, 84, 4, 1373, 306,0 },
+ {1564,1564, 83, 0, 220, 113,0 },
+ { 380, 381, 84, 4, 1593, 566,0 },
+ {1568,1568, 24, 0, 1833, 613,0 },
+ {2306,2307, 77, 4, 1593, 606,0 },
+ {2311,2312, 60, 4, 286, 0,0 },
+ {2313,2314, 65, 4, 513, 0,0 },
+ {2315,2315, 59, 0, 106, 0,0 },
+ {2316,2316, 51, 0, 386, 373,0 },
+ {1612,1612, 45, 0, 393, 380,0 },
+ {2317,2317, 71, 0, 446, 180,0 },
+ {2318,2318, 60, 0, 280, 20,0 },
+ {2319,2319, 58, 0, 393, 373,0 },
+ {2320,2320, 53, 0, 393, 380,0 },
+ { 397, 397, 64, 0, 220, 86,0 },
+ {2321,2321, 71, 0, 106, 46,0 },
+ {2322,2322, 61, 0, 986, 340,0 },
+ {2323,2323, 61, 0, 1893, 633,0 },
+ {2324, 392, 44, 4, 166, 46,0 },
+ {2324, 393, 40, 4, 460, 60,0 },
+ {1595,1595, 69, 0, 126, 140,0 },
+ {1595,1595, 68, 0, 126, 140,0 },
+ {1595,1595, 63, 0, 146, 166,0 },
+ {2325,2326, 74, 4, 380, 106,0 },
+ {2327,2328, 60, 4, 1026, 333,0 },
+ {2329,2330, 80, 4, 40000, 0,0 },
+ {2331,2332, 64, 4, 1900, 640,0 },
+ { 397, 397, 72, 0, 193, 80,0 },
+ {2333,2334, 78, 4, 820, 0,0 },
+ {1608,1609, 82, 4, 1580, 0,0 },
+ {2315,2315, 48, 0, 106, 0,0 },
+ {2316,2316, 53, 0, 386, 373,0 },
+ {2335,2335, 0, 0, 3586, 1133,0 },
+ {2336,2337, 0, 4, 1186, 420,0 },
+ {2338,2339, 0, 4, 40000, 320,0 },
+ {2340,2340, 0, 0, 8826, 1346,0 },
+ {2341,2341, 0, 0, 3440, 753,0 },
+ {2342,2342, 0, 0, 40000, 360,0 },
+ {2343,2343, 0, 0, 40000, 413,0 },
+ {2344,2345, 0, 4, 40000, 60,0 },
+ {2346,2346, 0, 0, 40000, 60,0 },
+ {2347,2348, 0, 4, 40000, 126,0 },
+ {2349,2350, 0, 4, 40000, 73,0 },
+ {2351,2352, 0, 4, 40000, 73,0 },
+ {2353,2354, 0, 4, 40000, 86,0 },
+ {2355,2356, 0, 4, 40000, 453,0 },
+ {2357,2357, 14, 0, 186, 20,0 },
+ {2358,2358, 35, 0, 246, 73,0 },
+ {2357,2357, 19, 0, 166, 26,0 },
+ {2359,2359, 43, 0, 286, 133,0 },
+ {2360,2360, 41, 0, 300, 113,0 },
+ {2360,2360, 43, 0, 253, 106,0 },
+ {2360,2360, 45, 0, 240, 100,0 },
+ {2360,2360, 47, 0, 240, 100,0 },
+ {2361,2362, 0, 4, 14720, 333,0 },
+ {2363,2363, 0, 0, 7373, 1246,0 },
+ {2364,2364, 0, 0, 4900, 233,0 },
+ {2365,2365, 0, 0, 5106, 606,0 },
+ {2366,2366, 0, 0, 1333, 153,0 },
+ {2367,2367, 0, 0, 2093, 840,0 },
+ {2368,2368, 0, 0, 3700, 226,0 },
+ {2369,2369, 0, 0, 3546, 0,0 },
+ {2370,2370, 0, 0, 4606, 420,0 },
+ {2371,2371, 0, 0, 14366, 606,0 },
+ {2372,2372, 0, 0, 40000, 426,0 },
+ {2373,2373, 0, 0, 3700, 200,0 },
+ {2374,2374, 0, 0, 880, 440,0 },
+ {2375,2375, 0, 0, 4660, 660,0 },
+ {2376,2376, 0, 0, 3600, 1153,0 },
+ {2377,2377, 0, 0, 40000, 73,0 },
+ {2378,2378, 0, 0, 40000, 53,0 },
+ {2379,2379, 0, 0, 40000, 333,0 },
+ {2380,2380, 0, 0, 40000, 73,0 },
+ {2381,2381, 0, 0, 40000, 73,0 },
+ {2382,2382, 0, 0, 40000, 66,0 },
+ {2383,2383, 0, 0, 40000, 73,0 },
+ {2384,2384, 0, 0, 40000, 73,0 },
+ {2385,2385, 0, 0, 840, 226,0 },
+ {2386,2386, 0, 0, 2093, 86,0 },
+ {2387,2387, 0, 0, 906, 73,0 },
+ { 402, 402, 0, 0, 273, 60,0 },
+ {2388,2388, 0, 0, 40000, 820,0 },
+ {2389,2389, 0, 0, 4740, 93,0 },
+ {2390,2390, 0, 0, 706, 106,0 },
+ {2391,2391, 0, 0, 40000, 0,0 },
+ {2392,2392, 0, 0, 3840, 2306,0 },
+ {2393,2393, 0, 0, 3400, 493,0 },
+ {2394,2394, 0, 0, 40000, 53,0 },
+ {2395,2395, 0, 0, 40000, 133,0 },
+ {2396,2397, 0, 4, 3093, 1400,0 },
+ {2398,2398, 0, 0, 1080, 580,0 },
+ {2399,2400, 0, 4, 2220, 400,0 },
+ {2401,2401, 0, 0, 40000, 193,0 },
+ {2402,2402, 0, 0, 40000, 60,0 },
+ {2403,2404, 0, 4, 40000, 146,0 },
+ {2405,2406, 0, 4, 40000, 133,0 },
+ {2407,2408, 0, 4, 40000, 66,0 },
+ {2409,2409, 0, 0, 40000, 0,0 },
+ {2410,2410, 0, 0, 40000, 73,0 },
+ {2411,2411, 0, 0, 40000, 66,0 },
+ {2412,2413, 0, 4, 40000, 153,0 },
+ {2414,2414, 0, 0, 40000, 126,0 },
+ {2415,2416, 0, 4, 40000, 466,0 },
+ {2417,2418, 0, 4, 40000, 113,0 },
+ {2419,2420, 0, 4, 1280, 73,0 },
+ {2421,2422, 0, 4, 1113, 146,0 },
+ {2423,2424, 0, 4, 3660, 113,0 },
+ {2425,2426, 0, 4, 40000, 80,0 },
+ {2427,2427, 33, 0, 300, 246,0 },
+ {2428,2429, 38, 4, 53, 0,0 },
+ {2430,2430, 38, 0, 106, 0,0 },
+ {2431,2431, 38, 0, 340, 20,0 },
+ {2432,2432, 40, 0, 73, 0,0 },
+ {2433,2434, 41, 4, 300, 0,0 },
+ {2435,2435, 0, 0, 133, 73,0 },
+ {2435,2435, 41, 0, 133, 73,0 },
+ {2360,2360, 48, 0, 240, 100,0 },
+ {2436,2436, 17, 0, 4620, 1553,0 },
+ {2360,2360, 50, 0, 240, 100,0 },
+ {2435,2435, 45, 0, 126, 66,0 },
+ {2437,2437,254, 2, 6, 0,0 },
+ {2438,2438, 60, 0, 226, 93,0 },
+ {2439,2439, 56, 0, 233, 93,0 },
+ {2440,2440, 60, 0, 140, 66,0 },
+ {2440,2440, 55, 0, 140, 60,0 },
+ {2441,2441, 63, 0, 286, 126,0 },
+ {2442,2442, 57, 0, 173, 93,0 },
+ {2443,2443, 0, 0, 40000, 280,0 },
+ {2444,2444, 0, 0, 40000, 0,0 },
+ {2445,2445, 0, 0, 40000, 746,0 },
+ {2446,2446, 0, 0, 40000, 353,0 },
+ {2447,2447, 0, 0, 40000, 1173,0 },
+ {2448,2448, 0, 0, 40000, 146,0 },
+ {2449,2449, 0, 0, 40000, 1160,0 },
+ {2450,2450, 0, 0, 40000, 353,0 },
+ {2451,2451, 0, 0, 18313, 6046,0 },
+ {2452,2452, 0, 0, 1206, 420,0 },
+ { 752, 752, 55, 0, 173, 20,0 },
+ {2453,2453, 0, 0, 2860, 806,0 },
+ {2454,2454, 0, 0, 2506, 126,0 },
+ {2455,2455, 0, 0, 520, 93,0 },
+ {2456,2456, 0, 0, 1420, 160,0 },
+ {2457,2457, 0, 0, 40000, 53,0 },
+ {2458,2458, 0, 0, 9106, 100,0 },
+ {2459,2459, 0, 0, 3706, 100,0 },
+ {2460,2460, 0, 0, 17933, 100,0 },
+ {2461,2461, 0, 0, 40000, 0,0 },
+ {2462,2462, 0, 0, 40000, 66,0 },
+ {2463,2463, 0, 0, 40000, 0,0 },
+ { 884, 884, 0, 0, 306, 73,0 },
+ { 884, 884, 28, 0, 306, 73,0 },
+ {2464,2464, 29, 0, 226, 93,0 },
+ { 886, 886, 31, 0, 113, 0,0 },
+ { 360, 360, 32, 0, 133, 40,0 },
+ { 361, 361, 33, 0, 286, 80,0 },
+ {2453,2453, 34, 0, 2873, 813,0 },
+ { 888, 888, 29, 0, 246, 46,0 },
+ { 886, 886, 55, 0, 100, 0,0 },
+ { 890, 890, 48, 0, 240, 60,0 },
+ { 884, 884, 58, 0, 146, 26,0 },
+ {2465,2465, 45, 0, 173, 93,0 },
+ {2465,2465, 43, 0, 173, 93,0 },
+ {2466,2466, 73, 0, 1633, 86,0 },
+ {2467,2467, 72, 0, 866, 553,0 },
+ {2468,2468, 76, 0, 1380, 0,0 },
+ {2467,2467, 84, 0, 873, 560,0 },
+ {2468,2468, 36, 0, 1933, 880,0 },
+ {2469,2469, 65, 0, 300, 120,0 },
+ {2470,2470, 83, 0, 193, 86,0 },
+ {2471,2471, 50, 0, 966, 126,0 },
+ {2468,2468, 77, 0, 1373, 620,0 },
+ { 897, 897, 55, 0, 126, 40,0 },
+ {2472,2472, 60, 0, 180, 140,0 },
+ { 897, 897, 50, 0, 126, 40,0 },
+ {2473,2473, 42, 0, 633, 240,0 },
+ {2473,2473, 46, 0, 513, 200,0 },
+ {2474,2474, 71, 0, 433, 180,0 },
+ {2474,2474, 60, 0, 513, 206,0 },
+ {2455,2455, 58, 0, 220, 46,0 },
+ {2455,2455, 53, 0, 286, 60,0 },
+ {2475,2475, 91, 0, 186, 100,0 },
+ {2476,2476, 61, 0, 226, 26,0 },
+ {2477,2477, 61, 0, 886, 73,0 },
+ {2478,2478, 44, 0, 120, 73,0 },
+ {2479,2479, 40, 0, 933, 73,0 },
+ {2480,2480, 69, 0, 146, 33,0 },
+ { 361, 361, 68, 0, 153, 26,0 },
+ { 361, 361, 63, 0, 180, 26,0 },
+ {2481,2481, 74, 0, 153, 73,0 },
+ {2482,2482, 60, 0, 280, 100,0 },
+ { 908, 908, 80, 0, 160, 26,0 },
+ {2483,2483, 64, 0, 986, 353,0 },
+ {2483,2483, 73, 0, 813, 306,0 },
+ {2483,2483, 70, 0, 820, 306,0 },
+ { 886, 886, 68, 0, 93, 0,0 },
+ { 886, 886, 48, 0, 106, 0,0 },
+ {2484,2484, 0, 0, 40000, 0,0 },
+ {2485,2485, 0, 0, 3226, 753,0 },
+ {2486,2486, 0, 0, 1773, 553,0 },
+ {2487,2487, 0, 0, 7473, 2460,0 },
+ {2488,2488, 0, 0, 40000, 0,0 },
+ {2489,2489, 0, 0, 40000, 353,0 },
+ {2490,2490, 0, 0, 40000, 206,0 },
+ {2491,2491, 0, 0, 40000, 86,0 },
+ {2492,2492, 0, 0, 4740, 86,0 },
+ {2493,2493, 0, 0, 6193, 193,0 },
+ {2494,2494, 0, 0, 6200, 240,0 },
+ {2495,2495, 0, 0, 40000, 0,0 },
+ {2496,2496, 0, 0, 1586, 73,0 },
+ {2497,2497, 0, 0, 560, 73,0 },
+ {2498,2498, 0, 0, 40000, 480,0 },
+ {2499,2499, 0, 0, 40000, 80,0 },
+ {2500,2500, 0, 0, 40000, 66,0 },
+ {2501,2501, 0, 0, 40000, 380,0 },
+ {2502,2502, 0, 0, 280, 100,0 },
+ {2503,2503, 0, 0, 6193, 233,0 },
+ {2504,2504, 0, 0, 40000, 380,0 },
+ {2505,2505, 0, 0, 40000, 0,0 },
+ {2506,2506, 0, 0, 40000, 380,0 },
+ {2507,2507, 0, 0, 40000, 200,0 },
+ {2508,2508, 0, 0, 40000, 320,0 },
+ {2509,2509, 0, 0, 40000, 126,0 },
+ {2510,2510, 0, 0, 40000, 293,0 },
+ {2511,2511, 0, 0, 40000, 0,0 },
+ {2512,2512, 0, 0, 40000, 40,0 },
+ {2513,2513, 0, 0, 40000, 106,0 },
+ {2514,2514, 0, 0, 3846, 73,0 },
+ {2515,2515, 0, 0, 40000, 0,0 },
+ {2516,2516, 0, 0, 40000, 73,0 },
+ {2517,2517, 0, 0, 40000, 533,0 },
+ {2518,2518, 0, 0, 40000, 1020,0 },
+ {2519,2519, 0, 0, 40000, 73,0 },
+ {2520,2520, 0, 0, 40000, 53,0 },
+ {2521,2521, 0, 0, 6153, 1433,0 },
+ {2522,2522, 0, 0, 18813, 773,0 },
+ {2523,2523, 0, 0, 40000, 433,0 },
+ {2524,2524, 0, 0, 40000, 0,0 },
+ {2525,2525, 0, 0, 40000, 133,0 },
+ {2526,2526, 0, 0, 4486, 73,0 },
+ { 346, 346, 30, 0, 540, 33,0 },
+ { 346, 346, 31, 0, 406, 20,0 },
+ { 346, 346, 32, 0, 406, 20,0 },
+ { 346, 346, 33, 0, 406, 73,0 },
+ { 346, 346, 34, 0, 406, 20,0 },
+ { 346, 346, 35, 0, 406, 20,0 },
+ { 346, 346, 37, 0, 406, 73,0 },
+ { 346, 346, 39, 0, 406, 73,0 },
+ { 346, 346, 41, 0, 406, 20,0 },
+ { 346, 346, 43, 0, 306, 20,0 },
+ { 346, 346, 45, 0, 306, 20,0 },
+ { 346, 346, 47, 0, 306, 20,0 },
+ { 346, 346, 48, 0, 306, 20,0 },
+ { 346, 346, 49, 0, 306, 20,0 },
+ { 512, 512, 84, 0, 353, 466,0 },
+ {2206,2206, 84, 0, 440, 180,0 },
+ {2527,2527, 55, 0, 100, 0,0 },
+ {2528,2528, 36, 0, 400, 160,0 },
+ {2529,2529, 38, 0, 313, 226,0 },
+ {2530,2530, 60, 0, 286, 133,0 },
+ {2531,2531, 38, 0, 200, 100,0 },
+ {2532,2532, 17, 0, 6186, 240,0 },
+ {2532,2532, 18, 0, 6186, 240,0 },
+ {2532,2532, 19, 0, 6193, 233,0 },
+ {2532,2532, 20, 0, 6193, 193,0 },
+ {2532,2532, 21, 0, 6193, 193,0 },
+ {2532,2532, 22, 0, 6193, 193,0 },
+ {2532,2532, 23, 0, 6193, 193,0 },
+ {2532,2532, 24, 0, 6193, 193,0 },
+ {2532,2532, 25, 0, 6193, 193,0 },
+ {2532,2532, 26, 0, 6193, 193,0 },
+ {2532,2532, 27, 0, 6193, 253,0 },
+ {2532,2532, 28, 0, 6193, 246,0 },
+ {2532,2532, 29, 0, 6193, 246,0 },
+ {2533,2533, 84, 0, 433, 180,0 },
+ {2534,2534, 48, 0, 280, 93,0 },
+ {2535,2535, 65, 0, 1166, 360,0 },
+ {2536,2536, 65, 0, 1853, 633,0 },
+ {2537,2537, 55, 0, 453, 366,0 },
+ {2537,2537, 41, 0, 540, 433,0 },
+ { 346, 346, 63, 0, 240, 66,0 },
+ { 346, 346, 55, 0, 240, 66,0 },
+ {2538,2538, 55, 0, 2586, 200,0 },
+ {2538,2538, 53, 0, 2586, 200,0 },
+ {2534,2534, 50, 0, 280, 93,0 },
+ { 506, 506, 84, 0, 693, 566,0 },
+ { 506, 506, 74, 0, 693, 560,0 },
+ { 504, 504, 84, 0, 1566, 546,0 },
+ { 504, 504, 74, 0, 1586, 560,0 },
+ {2539,2539, 84, 0, 440, 20,0 },
+ {2540,2540, 74, 0, 126, 26,0 },
+ {1911,1911, 48, 0, 500, 180,0 },
+ {1911,1911, 36, 0, 606, 220,0 },
+ {2541,2541, 74, 0, 686, 560,0 },
+ {2542,2542, 0, 0, 7313, 13,0 },
+ {2543,2543, 0, 0, 40000, 1306,0 },
+ {2544,2544, 0, 0, 40000, 0,0 },
+ {2545,2545, 0, 0, 4613, 13,0 },
+ {2546,2547, 0, 4, 6933, 133,0 },
+ {2548,2549, 0, 4, 40000, 86,0 },
+ {2550,2550, 0, 0, 9233, 100,0 },
+ {2551,2552, 0, 4, 4640, 73,0 },
+ {2553,2553, 0, 0, 40000, 73,0 },
+ {2554,2554, 0, 0, 40000, 0,0 },
+ {2555,2556, 0, 4, 40000, 73,0 },
+ {2557,2557, 0, 0, 40000, 60,0 },
+ {2558,1467, 0, 4, 40000, 66,0 },
+ {2559,2560, 0, 4, 40000, 40,0 },
+ {2561,2561, 0, 0, 40000, 186,0 },
+ {2562,2562, 0, 0, 4026, 66,0 },
+ {2563,2564, 0, 4, 14586, 80,0 },
+ {2565,2565, 0, 0, 40000, 0,0 },
+ {2566,2567, 0, 4, 40000, 40,0 },
+ {2568,2568, 0, 0, 4020, 73,0 },
+ {2569,2569, 0, 0, 40000, 0,0 },
+ {2570,2570, 0, 0, 40000, 0,0 },
+ {2571,2572, 0, 4, 40000, 126,0 },
+ {2573,2574, 0, 4, 40000, 100,0 },
+ {2575,2575, 0, 0, 40000, 213,0 },
+ { 229,2576, 0, 4, 40000, 166,0 },
+ {2577,2577, 0, 0, 7366, 53,0 },
+ { 239,2578, 0, 4, 40000, 133,0 },
+ {2579,2579, 0, 0, 40000, 80,0 },
+ {2580,2580, 0, 0, 40000, 140,0 },
+ {2581,2582, 0, 4, 16980, 1173,0 },
+ {2583,2584, 0, 4, 726, 100,0 },
+ {2585,2586, 0, 4, 40000, 73,0 },
+ {2587,2588, 0, 4, 40000, 73,0 },
+ {2589,2589, 0, 0, 40000, 60,0 },
+ {2590,2590, 0, 0, 40000, 80,0 },
+ {2591,2592, 0, 4, 40000, 73,0 },
+ {2593,2594, 0, 4, 40000, 60,0 },
+ {2595,2595, 0, 0, 40000, 66,0 },
+ {2596,2597, 0, 4, 40000, 66,0 },
+ {2598,2599, 0, 4, 40000, 60,0 },
+ {2600,2601, 0, 4, 40000, 173,0 },
+ {2602,2602, 0, 0, 40000, 60,0 },
+ {2603,2603, 0, 0, 40000, 73,0 },
+ {2604,2604, 0, 0, 40000, 93,0 },
+ {2605,2606, 0, 4, 40000, 73,0 },
+ {2607,2607, 0, 0, 40000, 66,0 },
+ {2608,2609, 0, 4, 40000, 66,0 },
+ {2610,2610, 0, 0, 40000, 86,0 },
+ {2611,2611, 0, 0, 40000, 60,0 },
+ {2612,2612, 0, 0, 14286, 73,0 },
+ {2613,2613, 0, 0, 40000, 0,0 },
+ {2614,2615, 0, 4, 40000, 73,0 },
+ {2616,2617, 0, 4, 40000, 66,0 },
+ {2618,2619, 0, 4, 133, 0,0 },
+ {2620,2621, 0, 4, 40000, 1280,0 },
+ {2622,2623, 0, 4, 40000, 160,0 },
+ {2624,2625, 0, 4, 40000, 0,0 },
+ {2626,2627, 0, 4, 40000, 73,0 },
+ {2628,2629, 0, 4, 40000, 0,0 },
+ {1516,2630, 0, 4, 1193, 406,0 },
+ {2631,2632, 0, 4, 40000, 553,0 },
+ {2633,2633, 0, 0, 40000, 40,0 },
+ {2634,2635, 0, 4, 40000, 773,0 },
+ {2636,2636, 0, 0, 40000, 320,0 },
+ {2637,2637, 0, 0, 1880, 73,0 },
+ {2638,2639, 0, 4, 486, 0,0 },
+ {2640,2641, 0, 4, 17020, 1193,0 },
+ {2642,2642, 0, 0, 40000, 720,0 },
+ {2643,2644, 0, 4, 1880, 40,0 },
+ {2645,2645, 0, 0, 40000, 73,0 },
+ {2646,2647, 0, 4, 40000, 46,0 },
+ {2648,2648, 0, 0, 2466, 80,0 },
+ {2649,2649, 0, 0, 40000, 193,0 },
+ {2650,2651, 0, 4, 993, 73,0 },
+ {2652,2652, 0, 0, 40000, 220,0 },
+ {2653,2654, 0, 4, 40000, 46,0 },
+ {2655,2656, 0, 4, 40000, 46,0 },
+ {2657,2657, 0, 0, 40000, 66,0 },
+ {2658,2658, 35, 0, 626, 20,0 },
+ {2659,2659, 35, 0, 306, 26,0 },
+ {2660,2660, 52, 0, 126, 26,0 },
+ {2661,2661, 60, 0, 286, 20,0 },
+ {2662,2662, 58, 0, 113, 0,0 },
+ {2663,2663, 60, 0, 380, 20,0 },
+ {2664,2664, 50, 0, 1640, 66,0 },
+ {2665,2665, 43, 0, 153, 20,0 },
+ {2664,2664, 55, 0, 1640, 20,0 },
+ {1553,1553, 43, 0, 160, 80,0 },
+ {2666,2666, 50, 0, 980, 20,0 },
+ {2667,2667, 43, 0, 446, 73,0 },
+ {2666,2666, 53, 0, 1000, 80,0 },
+ {2666,2666, 57, 0, 700, 73,0 },
+ {2668,2668, 72, 0, 773, 13,0 },
+ {2666,2666, 60, 0, 686, 20,0 },
+ { 373, 373, 76, 0, 826, 20,0 },
+ {2669,2669, 84, 0, 713, 20,0 },
+ {2670,2670, 42, 0, 1186, 20,0 },
+ {2671,2671, 65, 0, 293, 33,0 },
+ {2672,2672, 84, 0, 386, 33,0 },
+ {2673,2673, 84, 0, 1366, 20,0 },
+ {2674,2674, 24, 0, 960, 73,0 },
+ { 383, 383, 77, 0, 800, 20,0 },
+ {2675,2675, 58, 0, 426, 26,0 },
+ {2676,2676, 53, 0, 426, 20,0 },
+ {2677,2677, 64, 0, 200, 66,0 },
+ {2678,2678, 71, 0, 113, 13,0 },
+ {2679,2679, 44, 0, 766, 66,0 },
+ {2680,2680, 40, 0, 460, 60,0 },
+ {2681,2681, 69, 0, 126, 26,0 },
+ {2682,2682, 60, 0, 573, 66,0 },
+ {2683,2683, 80, 0, 226, 20,0 },
+ {2684,2684, 64, 0, 2693, 20,0 },
+ {2685,2685, 72, 0, 120, 66,0 },
+ {2686,2686, 70, 0, 820, 20,0 },
+ {2687,2687, 48, 0, 173, 20,0 },
+ {2688,2688, 53, 0, 980, 33,0 },
+ {2689,2690, 0, 4, 40000, 286,0 },
+ {2691,2692, 0, 4, 2340, 100,0 },
+ {2693,2694, 0, 4, 380, 80,0 },
+ {2695,2696, 0, 4, 14793, 73,0 },
+ {2697,2698, 0, 4, 40000, 40,0 },
+ { 192,2699, 0, 4, 40000, 73,0 },
+ {2700,2701, 0, 4, 973, 126,0 },
+ {2702,2703, 0, 4, 4666, 106,0 },
+ {2704,2705, 0, 4, 40000, 73,0 },
+ {2706,2707, 0, 4, 40000, 73,0 },
+ {2708,2709, 0, 4, 40000, 73,0 },
+ {2710,2711, 0, 4, 2053, 0,0 },
+ {2712,1473, 0, 4, 320, 26,0 },
+ {2713,2714, 0, 4, 573, 93,0 },
+ {2715,2716, 0, 4, 6513, 0,0 },
+ {1478,2717, 0, 4, 40000, 146,0 },
+ {2718,2719, 0, 4, 40000, 66,0 },
+ { 286,2720, 0, 4, 40000, 73,0 },
+ {2721,2722, 0, 4, 40000, 86,0 },
+ {2723,2724, 0, 4, 40000, 60,0 },
+ {2725,2726, 0, 4, 393, 73,0 },
+ {2727,2724, 0, 4, 40000, 60,0 },
+ {1514,2728, 0, 4, 40000, 180,0 },
+ {2729,2730, 0, 4, 40000, 0,0 },
+ {2731,2732, 0, 4, 486, 0,0 },
+ {2733,2734, 0, 4, 733, 0,0 },
+ {2735,2736, 0, 4, 286, 40,0 },
+ {2737,2738, 0, 4, 40000, 73,0 },
+ {2739,2740, 0, 4, 1326, 746,0 },
+ {2741,2742, 0, 4, 1340, 700,0 },
+ {2743,2744, 0, 4, 40000, 0,0 },
+ {2745,2746, 0, 4, 2046, 0,0 },
+ {2747,2747, 35, 0, 386, 166,0 },
+ {2748,2748, 60, 0, 493, 193,0 },
+ {2749,2749, 43, 0, 126, 66,0 },
+ {2750,2750, 0, 0, 3740, 1260,0 },
+ {2751,2752, 0, 4, 14846, 353,0 },
+ {2753,2754, 0, 4, 10266, 0,0 },
+ {2755,2756, 0, 4, 18286, 146,0 },
+ {2757,2758, 0, 4, 14520, 333,0 },
+ {2759,2760, 0, 4, 14686, 633,0 },
+ {2761,2762, 0, 4, 14826, 300,0 },
+ {2763,2764, 0, 4, 10493, 0,0 },
+ {2765,2766, 0, 4, 40000, 60,0 },
+ {2767,2768, 0, 4, 40000, 80,0 },
+ {2769,2770, 0, 4, 40000, 80,0 },
+ {2771,2772, 0, 4, 40000, 73,0 },
+ {2773,2774, 0, 4, 40000, 73,0 },
+ {2775,2776, 0, 4, 40000, 80,0 },
+ {2777,2778, 0, 4, 40000, 73,0 },
+ {2779,2780, 0, 4, 40000, 73,0 },
+ {2781,2782, 0, 4, 40000, 66,0 },
+ {2783,2784, 0, 4, 7260, 186,0 },
+ {2785,2786, 0, 4, 10386, 0,0 },
+ {2787,2788, 0, 4, 40000, 246,0 },
+ {2789,2790, 0, 4, 9173, 746,0 },
+ {2791,2792, 0, 4, 7440, 666,0 },
+ {2793,2794, 0, 4, 40000, 0,0 },
+ {2795,2796, 0, 4, 40000, 413,0 },
+ {2795,2797, 0, 4, 40000, 1506,0 },
+ {2798,2799, 0, 4, 40000, 60,0 },
+ {2800,2801, 0, 4, 40000, 233,0 },
+ {2802,2803, 0, 4, 40000, 80,0 },
+ {2804,2805, 0, 4, 40000, 80,0 },
+ {2806,2807, 0, 4, 4520, 80,0 },
+ {2808,2809, 0, 4, 40000, 73,0 },
+ {2810,2811, 0, 4, 1186, 100,0 },
+ {2812,2813, 0, 4, 953, 153,0 },
+ {2814,2815, 0, 4, 14786, 126,0 },
+ {2816,2817, 0, 4, 14800, 193,0 },
+ {2818,2819, 0, 4, 14573, 626,0 },
+ {2820,2821, 0, 4, 2200, 73,0 },
+ {2822,2823, 0, 4, 373, 86,0 },
+ {2824,2825, 0, 4, 12780, 200,0 },
+ {2826,2827, 0, 4, 40000, 73,0 },
+ {2828,2829, 0, 4, 9193, 146,0 },
+ {2830,2831, 0, 4, 2540, 326,0 },
+ {2832,2833, 0, 4, 6933, 200,0 },
+ {2834,2835, 0, 4, 40000, 413,0 },
+ {2836,2837, 0, 4, 4826, 1313,0 },
+ {2838,2839, 0, 4, 14740, 340,0 },
+ {2840,2841, 0, 4, 1886, 653,0 },
+ {2842,2843, 0, 4, 5280, 260,0 },
+ {2844,2845, 0, 4, 40000, 240,0 },
+ {2846,2847, 0, 4, 40000, 240,0 },
+ {2848,2849, 0, 4, 40000, 240,0 },
+ {2850,2851, 0, 4, 40000, 406,0 },
+ {2852,2853, 0, 4, 40000, 406,0 },
+ {2854,2855, 0, 4, 40000, 146,0 },
+ {2856,2856, 0, 0, 2400, 1126,0 },
+ {2857,2857, 0, 0, 2400, 1126,0 },
+ {2858,2859, 0, 4, 4613, 73,0 },
+ {2860,2861, 0, 4, 40000, 426,0 },
+ {2862,2863, 0, 4, 4580, 100,0 },
+ {2864,2865, 0, 4, 40000, 80,0 },
+ {2866,2867, 0, 4, 5300, 53,0 },
+ {2868,2869, 0, 4, 5313, 113,0 },
+ {2870,2871, 0, 4, 7080, 186,0 },
+ {2872,2873, 0, 4, 4720, 106,0 },
+ {2874,2875, 0, 4, 40000, 73,0 },
+ {2876,2877, 0, 4, 1640, 0,0 },
+ {2878,2879, 0, 4, 7306, 186,0 },
+ {2880,2881, 0, 4, 7373, 1246,0 },
+ {2882,2883, 0, 4, 4620, 93,0 },
+ {2884,2885, 0, 4, 3460, 926,0 },
+ {2886,2887, 0, 4, 40000, 73,0 },
+ {2888,2888, 0, 0, 18926, 426,0 },
+ {2889,2889, 0, 0, 18520, 73,0 },
+ {2890,2890, 0, 0, 18473, 73,0 },
+ {2891,2892, 0, 4, 40000, 93,0 },
+ {2893,2893, 0, 0, 8006, 133,0 },
+ {2894,2894, 0, 0, 18533, 66,0 },
+ {2895,2895, 0, 0, 14786, 4966,0 },
+ {2896,2897, 0, 4, 40000, 80,0 },
+ {2898,2899, 0, 4, 40000, 73,0 },
+ {2353,2900, 0, 4, 18520, 86,0 },
+ {2901,2901, 0, 0, 40000, 0,0 },
+ {2902,2903, 0, 4, 40000, 100,0 },
+ {2904,2905, 0, 4, 40000, 93,0 },
+ {2906,2907, 0, 4, 40000, 73,0 },
+ {2908,2909, 0, 4, 10720, 153,0 },
+ {2910,2911, 0, 4, 40000, 73,0 },
+ {2912,2912, 0, 0, 40000, 40,0 },
+ {2913,2914, 0, 4, 8720, 446,0 },
+ {2915,2916, 0, 4, 14706, 653,0 },
+ {2917,2918, 0, 4, 9213, 426,0 },
+ {2919,2920, 0, 4, 9286, 240,0 },
+ {2921,2922, 0, 4, 8706, 413,0 },
+ {2923,2924, 0, 4, 2233, 346,0 },
+ {2925,2926, 0, 4, 2373, 426,0 },
+ {2927,2928, 0, 4, 2353, 233,0 },
+ {2929,2929, 0, 0, 40000, 140,0 },
+ {2930,2931, 0, 4, 40000, 100,0 },
+ {2932,2933, 0, 4, 40000, 73,0 },
+ {2934,2935, 0, 4, 40000, 80,0 },
+ {2936,2937, 0, 4, 40000, 80,0 },
+ {2938,2939, 0, 4, 40000, 246,0 },
+ {2940,2940, 0, 0, 553, 446,0 },
+ {2941,2941, 0, 0, 40000, 193,0 },
+ {2942,2943, 0, 4, 1206, 406,0 },
+ {2944,2944, 0, 0, 7026, 1553,0 },
+ {2945,2945, 0, 0, 3426, 360,0 },
+ {2946,2947, 0, 4, 7313, 646,0 },
+ {2948,2948, 0, 0, 40000, 386,0 },
+ {2949,2949, 0, 0, 1953, 726,0 },
+ {2950,2951, 0, 4, 14606, 106,0 },
+ {2952,2953, 0, 4, 40000, 1566,0 },
+ {2954,2954, 60, 2, 6, 0,0 },
+ {2955,2956, 0, 4, 40000, 240,0 },
+ {2957,2958, 0, 4, 40000, 80,0 },
+ {2959,2960, 0, 4, 40000, 113,0 },
+ {2961,2962, 0, 4, 40000, 240,0 },
+ {2963,2963, 0, 0, 8506, 680,0 },
+ {2964,2964, 0, 0, 40000, 1593,0 },
+ {2436,2436, 49, 0, 1873, 633,0 },
+ {2357,2357, 61, 0, 113, 20,0 },
+ {2357,2357, 56, 0, 113, 26,0 },
+ {2357,2357, 58, 0, 113, 26,0 },
+ {2357,2357, 49, 0, 126, 26,0 },
+ {2357,2357, 44, 0, 126, 26,0 },
+ {2965,2965, 0, 0, 40000, 380,0 },
+ {2966,2966, 0, 0, 4440, 66,0 },
+ {2967,2967, 0, 0, 8133, 1433,0 },
+ {2968,2968, 0, 0, 40000, 126,0 },
+ {2969,2969, 0, 0, 40000, 0,0 },
+ {2970,2970, 84, 0, 160, 26,0 },
+ {2971,2971, 72, 0, 440, 180,0 },
+ {2972,2972, 0, 0, 8313, 580,0 },
+ {2973,2973, 0, 0, 40000, 160,0 },
+ {2974,2974, 0, 0, 40000, 3000,0 },
+ {2975,2975, 0, 0, 8300, 493,0 },
+ {2976,2976, 0, 0, 973, 673,0 },
+ {2977,2977, 0, 0, 40000, 73,0 },
+ {2978,2978, 0, 0, 40000, 133,0 },
+ {2979,2979, 0, 0, 40000, 140,0 },
+ {2980,2980, 0, 0, 40000, 346,0 },
+ {2981,2981, 0, 0, 40000, 1006,0 },
+ {2982,2982, 0, 0, 40000, 966,0 },
+ {2983,2983, 0, 0, 40000, 0,0 },
+ {2984,2984, 0, 0, 40000, 0,0 },
+ {2985,2985, 0, 0, 40000, 66,0 },
+ {2986,2986, 0, 0, 40000, 66,0 },
+ {2987,2987, 0, 0, 40000, 46,0 },
+ {2988,2988, 0, 0, 40000, 533,0 },
+ {2989,2989, 0, 0, 2400, 780,0 },
+ {2990,2990, 0, 0, 820, 66,0 },
+ {2991,2991, 0, 0, 40000, 240,0 },
+ {2992,2992, 0, 0, 40000, 220,0 },
+ {2993,2993, 0, 0, 40000, 0,0 },
+ {2994,2994, 0, 0, 15100, 73,0 },
+ {2995,2995, 0, 0, 40000, 200,0 },
+ {2996,2996, 0, 0, 2426, 93,0 },
+ {2997,2997, 0, 0, 4640, 1553,0 },
+ {2998,2998, 0, 0, 40000, 73,0 },
+ {2999,2999, 0, 0, 40000, 73,0 },
+ {3000,3000, 0, 0, 1133, 633,0 },
+ {3001,3001, 0, 0, 40000, 0,0 },
+ {3002,3002, 0, 0, 40000, 1006,0 },
+ {3003,3003, 0, 0, 4653, 653,0 },
+ {3004,3004, 0, 0, 40000, 1000,0 },
+ {3005,3005, 0, 0, 40000, 53,0 },
+ {3006,3006, 0, 0, 40000, 60,0 },
+ {3007,3007, 0, 0, 40000, 0,0 },
+ { 350, 350, 0, 0, 513, 200,0 },
+ {3008,3008, 0, 0, 213, 106,0 },
+ {3009,3009, 0, 0, 280, 126,0 },
+ {3010,3010, 0, 0, 1193, 426,0 },
+ {3011,3011, 0, 0, 14653, 4906,0 },
+ {3012,3012, 0, 0, 1040, 326,0 },
+ {3013,3013, 0, 0, 5740, 2326,0 },
+ {3014,3014, 0, 0, 40000, 73,0 },
+ {3015,3015, 0, 0, 40000, 240,0 },
+ { 350, 350, 36, 0, 380, 153,0 },
+ { 369, 369, 37, 0, 213, 66,0 },
+ {3008,3008, 38, 0, 213, 106,0 },
+ { 369, 369, 24, 0, 193, 13,0 },
+ {3008,3008, 32, 0, 206, 106,0 },
+ { 369, 369, 48, 0, 186, 20,0 },
+ {3009,3009, 42, 0, 220, 106,0 },
+ { 369, 369, 50, 0, 186, 73,0 },
+ { 369, 369, 52, 0, 186, 73,0 },
+ { 369, 369, 54, 0, 186, 33,0 },
+ { 369, 369, 55, 0, 186, 33,0 },
+ { 369, 369, 57, 0, 180, 33,0 },
+ {3010,3010, 51, 0, 966, 353,0 },
+ { 144, 144, 61, 0, 213, 126,0 },
+ {3016,3016, 0, 0, 8340, 520,0 },
+ {3016,3016, 63, 0, 6106, 373,0 },
+ {3016,3016, 64, 0, 6073, 380,0 },
+ {3017,3017, 40, 0, 206, 100,0 },
+ {3017,3017, 70, 0, 160, 93,0 },
+ {3018,3018, 0, 0, 40000, 73,0 },
+ {3019,3019, 0, 0, 40000, 73,0 },
+ {3020,3020, 0, 0, 40000, 73,0 },
+ {3021,3021, 0, 0, 40000, 73,0 },
+ {3022,3022, 38, 0, 246, 33,0 },
+ {2441,2441, 57, 0, 286, 126,0 },
+ {3023,3023, 63, 0, 146, 126,0 },
+ {3024,3024, 74, 0, 280, 73,0 },
+ {3025,3025, 74, 0, 453, 100,0 },
+ {3026,3026, 60, 0, 666, 33,0 },
+ {1439,1440, 0, 0, 13566, 273,0 },
+ {1593,1594, 35, 0, 2200, 673,0 },
+ {1564,1565, 35, 0, 740, 280,0 },
+ {1443,1444, 0, 0, 11886, 333,0 },
+ {1481,1482, 0, 0, 40000, 133,0 },
+ { 185, 186, 0, 0, 5980, 1540,0 },
+ { 235, 237, 0, 0, 3366, 1093,0 },
+ { 239, 240, 0, 0, 40000, 133,0 },
+ {1477,1476, 0, 0, 40000, 160,0 },
+ { 268, 269, 0, 0, 40000, 80,0 },
+ { 176, 177, 0, 0, 40000, 0,0 },
+ {1490,1491, 0, 0, 40000, 60,0 },
+ { 231, 232, 0, 0, 40000, 146,0 },
+ { 233, 234, 0, 0, 40000, 433,0 },
+ { 254, 255, 0, 0, 40000, 93,0 },
+ { 192, 193, 0, 0, 40000, 66,0 },
+ { 252, 253, 0, 0, 40000, 73,0 },
+ { 248,3027, 0, 0, 40000, 80,0 },
+ { 39,1476, 0, 0, 40000, 160,0 },
+ { 241, 242, 0, 0, 40000, 146,0 },
+ {1508,1509, 0, 0, 40000, 0,0 },
+ { 246, 247, 0, 0, 3966, 800,0 },
+ { 181,1451, 0, 0, 2153, 640,0 },
+ { 209, 210, 0, 0, 4453, 100,0 },
+ { 270, 271, 0, 0, 40000, 80,0 },
+ { 115,1533, 0, 0, 4260, 1720,0 },
+ {1454,1455, 0, 0, 40000, 0,0 },
+ { 107, 319, 0, 0, 1266, 413,0 },
+ { 46, 238, 0, 0, 6873, 1246,0 },
+ { 216, 217, 0, 0, 4046, 100,0 },
+ { 272, 273, 0, 0, 40000, 126,0 },
+ {1445,3028, 0, 0, 9966, 386,0 },
+ { 172, 173, 0, 0, 7340, 100,0 },
+ { 174, 175, 0, 0, 6913, 100,0 },
+ {1447,3029, 0, 0, 10306, 80,0 },
+ {1452,3030, 0, 0, 9240, 240,0 },
+ { 183, 184, 0, 0, 586, 253,0 },
+ {1456,1457, 0, 0, 1386, 180,0 },
+ {1458,1459, 0, 0, 40000, 60,0 },
+ { 190,1460, 0, 0, 40000, 46,0 },
+ {1462,1463, 0, 0, 40000, 340,0 },
+ {1464,1465, 0, 0, 40000, 360,0 },
+ { 195, 196, 0, 0, 40000, 66,0 },
+ { 197, 198, 0, 0, 40000, 86,0 },
+ { 199, 200, 0, 0, 40000, 60,0 },
+ { 201, 202, 0, 0, 3713, 100,0 },
+ { 203, 204, 0, 0, 14633, 126,0 },
+ { 205, 206, 0, 0, 9440, 153,0 },
+ { 214, 215, 0, 0, 17020, 100,0 },
+ { 218, 219, 0, 0, 14000, 180,0 },
+ { 220, 221, 0, 0, 2846, 100,0 },
+ {1472,1473, 0, 0, 8066, 66,0 },
+ {1474,1475, 0, 0, 8040, 93,0 },
+ { 225, 226, 0, 0, 8066, 106,0 },
+ { 229, 230, 0, 0, 40000, 160,0 },
+ {1478,1479, 0, 0, 40000, 413,0 },
+ { 50,1480, 0, 0, 40000, 393,0 },
+ {1485,1486, 0, 0, 40000, 226,0 },
+ { 258, 259, 0, 0, 40000, 73,0 },
+ { 262, 263, 0, 0, 40000, 160,0 },
+ { 264, 265, 0, 0, 40000, 160,0 },
+ {1494,1495, 0, 0, 40000, 80,0 },
+ {1496,1497, 0, 0, 40000, 73,0 },
+ { 274, 275, 0, 0, 40000, 100,0 },
+ {1499,1500, 0, 0, 40000, 73,0 },
+ { 277, 278, 0, 0, 40000, 173,0 },
+ { 279, 280, 0, 0, 40000, 160,0 },
+ { 281, 282, 0, 0, 40000, 173,0 },
+ {1501,1502, 0, 0, 40000, 146,0 },
+ { 284, 285, 0, 0, 40000, 66,0 },
+ { 286, 287, 0, 0, 40000, 86,0 },
+ {1503,1504, 0, 0, 40000, 86,0 },
+ {1505,1506, 0, 0, 40000, 73,0 },
+ { 289, 290, 0, 0, 40000, 66,0 },
+ { 291, 292, 0, 0, 40000, 160,0 },
+ { 293, 294, 0, 0, 40000, 200,0 },
+ { 86,1507, 0, 0, 40000, 80,0 },
+ { 88, 297, 0, 0, 40000, 1346,0 },
+ { 298, 299, 0, 0, 40000, 320,0 },
+ { 300, 301, 0, 0, 40000, 1273,0 },
+ {1514,1515, 0, 0, 40000, 100,0 },
+ {1518,1519, 0, 0, 4733, 0,0 },
+ {1520,1521, 0, 0, 40000, 440,0 },
+ {1524,1525, 0, 0, 40000, 1180,0 },
+ {1526,1527, 0, 0, 40000, 746,0 },
+ {1528,1529, 0, 0, 40000, 920,0 },
+ { 311, 312, 0, 0, 15306, 213,0 },
+ { 313, 314, 0, 0, 7280, 340,0 },
+ { 315, 316, 0, 0, 3693, 346,0 },
+ { 317, 318, 0, 0, 13720, 4033,0 },
+ { 108, 320, 0, 0, 40000, 66,0 },
+ { 109, 321, 0, 0, 40000, 180,0 },
+ { 322, 323, 0, 0, 40000, 73,0 },
+ { 111,1530, 0, 0, 4053, 426,0 },
+ { 324, 325, 0, 0, 626, 260,0 },
+ { 326, 327, 0, 0, 1166, 400,0 },
+ {1531,1532, 0, 0, 186, 340,0 },
+ {1534,1535, 0, 0, 3240, 440,0 },
+ { 330, 331, 0, 0, 1920, 360,0 },
+ {1536,1537, 0, 0, 3020, 0,0 },
+ {1538,1539, 0, 0, 1660, 846,0 },
+ {1541, 339, 0, 0, 9213, 813,0 },
+ {1542,1543, 0, 0, 993, 100,0 },
+ {1544,3031, 0, 0, 860, 180,0 },
+ {1546,3032, 0, 0, 40000, 80,0 },
+ { 338, 339, 0, 0, 40000, 200,0 },
+ { 340, 341, 0, 0, 40000, 0,0 },
+ {1441,1442, 0, 0, 7393, 186,0 },
+ { 207, 208, 0, 0, 14373, 126,0 },
+ {1466,1467, 0, 0, 40000, 66,0 },
+ {1468,1469, 0, 0, 40000, 46,0 },
+ { 179, 180, 0, 0, 4080, 346,0 },
+ {1449,1450, 0, 0, 8313, 3373,0 },
+ { 35,1470, 0, 0, 40000, 0,0 },
+ { 36,1471, 0, 0, 8093, 40,0 },
+ { 235, 236, 0, 0, 2393, 333,0 },
+ {1483,1484, 0, 0, 40000, 0,0 },
+ { 55,1487, 0, 0, 40000, 80,0 },
+ {1488,1489, 0, 0, 40000, 80,0 },
+ {1492,1493, 0, 0, 40000, 66,0 },
+ { 256, 257, 0, 0, 40000, 53,0 },
+ { 260, 261, 0, 0, 40000, 86,0 },
+ {1512,1513, 0, 0, 40000, 40,0 },
+ {1510,1511, 0, 0, 40000, 80,0 },
+ {1496,1498, 0, 0, 40000, 73,0 },
+ { 295, 296, 0, 0, 40000, 340,0 },
+ {1540, 339, 0, 0, 2466, 633,0 },
+ { 398, 399, 35, 0, 1860, 226,0 },
+ {1516,1517, 0, 0, 40000, 660,0 },
+ {1550,3033, 35, 0, 213, 26,0 },
+ {1556,1557, 35, 0, 1200, 426,0 },
+ {1558,1559, 35, 0, 1173, 406,0 },
+ {1570,1571, 35, 0, 1160, 140,0 },
+ {1608,1609, 35, 0, 2100, 320,0 },
+ {1595,1596, 35, 0, 220, 273,0 },
+ { 159,1597, 35, 0, 220, 266,0 },
+ {1610,1611, 35, 0, 220, 273,0 },
+ { 397,1588, 35, 0, 253, 86,0 },
+ {1606,1607, 35, 0, 133, 66,0 },
+ { 145,1576, 35, 0, 180, 0,0 },
+ {1612,1613, 35, 0, 526, 400,0 },
+ {1577,1578, 35, 0, 506, 453,0 },
+ {1614,1615, 35, 0, 773, 933,0 },
+ { 305, 306, 0, 0, 40000, 1160,0 },
+ {1522,1523, 0, 0, 40000, 0,0 },
+ {1550,1551, 35, 0, 526, 146,0 },
+ { 364, 365, 35, 0, 186, 20,0 },
+ { 129,1549, 35, 0, 326, 133,0 },
+ { 132,1552, 35, 0, 226, 113,0 },
+ {1553,1554, 35, 0, 206, 73,0 },
+ { 129,1548, 35, 0, 326, 133,0 },
+ { 134,1555, 35, 0, 2580, 893,0 },
+ {1560,1561, 35, 0, 600, 366,0 },
+ {1562,1563, 35, 0, 40000, 0,0 },
+ {1572,1573, 35, 0, 340, 133,0 },
+ {1574,1575, 35, 0, 406, 226,0 },
+ {1581,1582, 35, 0, 640, 213,0 },
+ { 149,1583, 35, 0, 326, 20,0 },
+ {1584,1585, 35, 0, 633, 240,0 },
+ {1591,1592, 35, 0, 1226, 413,0 },
+ {1568,1569, 35, 0, 1313, 460,0 },
+ {1579,1580, 35, 0, 326, 0,0 },
+ {1586,1587, 35, 0, 606, 220,0 },
+ {1589,1590, 35, 0, 120, 86,0 },
+ {1600,1601, 35, 0, 1326, 420,0 },
+ {1602,1603, 35, 0, 706, 266,0 },
+ {1604,1605, 35, 0, 4540, 1326,0 },
+ { 391, 392, 35, 0, 360, 153,0 },
+ { 391, 393, 35, 0, 453, 153,0 },
+ {1598,1599, 35, 0, 1246, 346,0 },
+ { 367, 368, 35, 0, 600, 153,0 },
+ { 380, 381, 35, 0, 40000, 0,0 },
+ { 374, 375, 35, 0, 40000, 0,0 },
+ {1566,1567, 35, 0, 40000, 0,0 },
+ {2306,2307, 35, 0, 7660, 1560,0 },
+ {3034, 339, 35, 0, 5860, 426,0 },
+ {2301,2302, 35, 0, 2146, 753,0 },
+ {2305,1548, 35, 0, 326, 133,0 },
+ {1595,1595, 35, 0, 220, 273,0 },
+ {2303,2304, 35, 0, 186, 20,0 },
+ {1560,2308, 35, 0, 600, 373,0 },
+ {2309,2310, 35, 0, 40000, 0,0 },
+ {1568,1568, 35, 0, 1280, 453,0 },
+ {2311,2312, 35, 0, 360, 106,0 },
+ {2313,2314, 35, 0, 620, 0,0 },
+ {2315,2315, 35, 0, 106, 0,0 },
+ {2316,2316, 35, 0, 506, 453,0 },
+ {1612,1612, 35, 0, 526, 400,0 },
+ {2317,2317, 35, 0, 640, 253,0 },
+ {2318,2318, 35, 0, 326, 20,0 },
+ {2319,2319, 35, 0, 453, 446,0 },
+ {2320,2320, 35, 0, 466, 453,0 },
+ {2321,2321, 35, 0, 120, 26,0 },
+ {2322,2322, 35, 0, 1220, 406,0 },
+ {2323,2323, 35, 0, 2360, 786,0 },
+ {2324, 392, 35, 0, 353, 146,0 },
+ {2324, 393, 35, 0, 453, 146,0 },
+ {2325,2326, 35, 0, 533, 140,0 },
+ {2327,2328, 35, 0, 1273, 393,0 },
+ {2329,2330, 35, 0, 40000, 0,0 },
+ {2331,2332, 35, 0, 40000, 0,0 },
+ {3035,3036, 35, 0, 4133, 433,0 },
+ {3037,3038, 35, 0, 1740, 286,0 },
+ {1564,1564, 35, 0, 713, 273,0 },
+ {3039,3039, 0, 0, 40000, 0,0 },
+ {3040,3040, 0, 0, 6100, 146,0 },
+ {3041,3041, 0, 0, 2386, 26,0 },
+ {3042,3042, 0, 0, 4320, 80,0 },
+ {3043,3043, 0, 0, 3433, 313,0 },
+ {3044,3044, 0, 0, 6620, 2446,0 },
+ {3045,3045, 0, 0, 3726, 1253,0 },
+ {3046,3046, 0, 0, 40000, 133,0 },
+ {3047,3047, 0, 0, 4566, 1253,0 },
+ {3048,3048, 0, 0, 40000, 813,0 },
+ {3049,3049, 0, 0, 18513, 1560,0 },
+ {3050,3050, 0, 0, 2186, 426,0 },
+ {3051,3051, 0, 0, 1186, 420,0 },
+ {3052,3052, 0, 0, 766, 420,0 },
+ {3053,3053, 0, 0, 14513, 4713,0 },
+ {3054,3054, 0, 0, 15493, 1580,0 },
+ {3055,3055, 0, 0, 40000, 66,0 },
+ {3056,3056, 0, 0, 40000, 60,0 },
+ {3057,3057, 0, 0, 4740, 100,0 },
+ {3058,3058, 0, 0, 40000, 66,0 },
+ {3059,3059, 0, 0, 40000, 73,0 },
+ {3060,3060, 0, 0, 40000, 73,0 },
+ {3061,3061, 0, 0, 40000, 0,0 },
+ {3062,3062, 0, 0, 8373, 633,0 },
+ {3063,3063, 0, 0, 7560, 133,0 },
+ {3064,3064, 0, 0, 40000, 0,0 },
+ {3065,3065, 0, 0, 40000, 86,0 },
+ {3066,3066, 0, 0, 340, 140,0 },
+ {3067,3067, 0, 0, 40000, 0,0 },
+ {3068,3068, 0, 0, 40000, 166,0 },
+ {3069,3069, 0, 0, 4280, 1466,0 },
+ {3070,3070, 0, 0, 2193, 73,0 },
+ {3071,3071, 0, 0, 4846, 100,0 },
+ {3072,3072, 0, 0, 12740, 93,0 },
+ {3073,3073, 0, 0, 6953, 200,0 },
+ {3074,3074, 0, 0, 13780, 73,0 },
+ {3075,3075, 0, 0, 40000, 73,0 },
+ {3076,3076, 0, 0, 5860, 600,0 },
+ {3077,3077, 0, 0, 2206, 73,0 },
+ {3078,3078, 0, 0, 40000, 140,0 },
+ {3079,3079, 0, 0, 40000, 53,0 },
+ {3080,3080, 0, 0, 40000, 120,0 },
+ {3081,3081, 0, 0, 40000, 140,0 },
+ {3082,3082, 0, 0, 40000, 126,0 },
+ {3083,3083, 0, 0, 360, 140,0 },
+ {3084,3084, 0, 0, 8880, 1373,0 },
+ {3085,3085, 0, 0, 593, 73,0 },
+ {3086,3086, 0, 0, 40000, 193,0 },
+ {3087,3087, 0, 0, 40000, 200,0 },
+ {3088,3088, 0, 0, 40000, 160,0 },
+ {3089,3089, 0, 0, 40000, 200,0 },
+ {3090,3090, 0, 0, 40000, 53,0 },
+ {3091,3091, 0, 0, 40000, 73,0 },
+ {3092,3092, 0, 0, 40000, 73,0 },
+ {3093,3093, 0, 0, 760, 213,0 },
+ {3094,3094, 0, 0, 40000, 133,0 },
+ {3095,3095, 0, 0, 40000, 220,0 },
+ {3096,3096, 0, 0, 40000, 100,0 },
+ {3097,3097, 0, 0, 40000, 73,0 },
+ {3098,3098, 0, 0, 40000, 140,0 },
+ {3099,3099, 0, 0, 40000, 140,0 },
+ {3100,3100, 0, 0, 40000, 140,0 },
+ {3101,3101, 0, 0, 40000, 73,0 },
+ {3102,3102, 0, 0, 40000, 73,0 },
+ {3103,3103, 0, 0, 40000, 73,0 },
+ {3104,3104, 0, 0, 40000, 73,0 },
+ {3105,3105, 0, 0, 40000, 66,0 },
+ {3106,3106, 0, 0, 40000, 66,0 },
+ {3107,3107, 0, 0, 40000, 73,0 },
+ {3108,3108, 0, 0, 40000, 73,0 },
+ {3109,3109, 0, 0, 40000, 73,0 },
+ {3110,3110, 0, 0, 40000, 73,0 },
+ {3111,3111, 0, 0, 40000, 86,0 },
+ {3112,3112, 0, 0, 5393, 100,0 },
+ {3113,3113, 0, 0, 40000, 60,0 },
+ {3114,3114, 0, 0, 18500, 73,0 },
+ {3115,3115, 0, 0, 40000, 93,0 },
+ {3116,3116, 0, 0, 40000, 86,0 },
+ {3117,3117, 0, 0, 40000, 173,0 },
+ {3118,3118, 0, 0, 40000, 1353,0 },
+ {3119,3119, 0, 0, 17506, 73,0 },
+ {3120,3120, 0, 0, 40000, 100,0 },
+ {3121,3121, 0, 0, 40000, 73,0 },
+ {3122,3122, 0, 0, 5620, 193,0 },
+ {3123,3123, 0, 0, 3700, 80,0 },
+ {3124,3124, 0, 0, 40000, 66,0 },
+ {3125,3125, 0, 0, 2740, 80,0 },
+ {3126,3126, 0, 0, 8333, 173,0 },
+ {3127,3127, 0, 0, 2226, 466,0 },
+ {3128,3128, 0, 0, 340, 146,0 },
+ {3129,3129, 0, 0, 19980, 6280,0 },
+ {3130,3130, 0, 0, 353, 73,0 },
+ {3131,3131, 35, 0, 566, 233,0 },
+ {3132,3132, 35, 0, 226, 46,0 },
+ {3133,3133, 35, 0, 40000, 100,0 },
+ {3134,3134, 35, 0, 40000, 100,0 },
+ {3135,3135, 35, 0, 360, 146,0 },
+ {3061,3061, 35, 0, 40000, 0,0 },
+ {3136,3136, 35, 0, 366, 20,0 },
+ { 739, 739, 35, 0, 246, 20,0 },
+ {3137,3137, 35, 0, 333, 33,0 },
+ {3138,3138, 35, 0, 420, 166,0 },
+ {3139,3139, 35, 0, 626, 240,0 },
+ {3140,3140, 35, 0, 233, 100,0 },
+ {3141,3141, 35, 0, 1166, 440,0 },
+ {3142,3142, 35, 0, 166, 66,0 },
+ {3143,3143, 35, 0, 1166, 440,0 },
+ {3144,3144, 35, 0, 813, 100,0 },
+ {3145,3145, 35, 0, 1040, 440,0 },
+ {3146,3146, 35, 0, 40000, 0,0 },
+ {3147,3147, 35, 0, 40000, 0,0 },
+ {3148,3148, 35, 0, 180, 40,0 },
+ {3149,3149, 35, 0, 40000, 0,0 },
+ {3150,3150, 0, 0, 40000, 0,0 },
+ {3151,3151, 0, 0, 4900, 240,0 },
+ {3152,3152, 0, 0, 3480, 80,0 },
+ {3153,3153, 0, 0, 3586, 86,0 },
+ {3154,3154, 0, 0, 4626, 633,0 },
+ {3155,3155, 0, 0, 4293, 2286,0 },
+ {3156,3156, 0, 0, 13653, 0,0 },
+ {3157,3157, 0, 0, 1206, 426,0 },
+ {3158,3158, 0, 0, 653, 426,0 },
+ {3159,3159, 0, 0, 40000, 0,0 },
+ {3160,3160, 0, 0, 4633, 633,0 },
+ {3161,3161, 0, 0, 40000, 73,0 },
+ {3162,3162, 0, 0, 40000, 60,0 },
+ {3163,3163, 0, 0, 40000, 146,0 },
+ {3164,3164, 0, 0, 40000, 73,0 },
+ {3165,3165, 0, 0, 40000, 73,0 },
+ {3166,3166, 0, 0, 40000, 0,0 },
+ {3167,3167, 0, 0, 40000, 66,0 },
+ {3168,3168, 0, 0, 3680, 1180,0 },
+ {3169,3169, 0, 0, 2406, 846,0 },
+ {3170,3170, 0, 0, 1560, 73,0 },
+ {3171,3171, 0, 0, 1946, 226,0 },
+ {3172,3172, 0, 0, 4333, 13,0 },
+ {3173,3173, 0, 0, 40000, 0,0 },
+ {3174,3174, 0, 0, 40000, 0,0 },
+ {3175,3175, 0, 0, 40000, 66,0 },
+ {3176,3176, 0, 0, 40000, 180,0 },
+ {3177,3177, 0, 0, 15380, 80,0 },
+ {3178,3178, 0, 0, 18213, 73,0 },
+ {3179,3179, 0, 0, 1706, 0,0 },
+ {3180,3180, 0, 0, 5733, 1266,0 },
+ {3181,3181, 0, 0, 40000, 0,0 },
+ {3182,3182, 0, 0, 40000, 366,0 },
+ {3183,3183, 0, 0, 40000, 66,0 },
+ {3184,3184, 0, 0, 4786, 73,0 },
+ {3185,3185, 0, 0, 5660, 720,0 },
+ {3186,3186, 0, 0, 1293, 406,0 },
+ {3187,3187, 0, 0, 40000, 0,0 },
+ {3188,3188, 0, 0, 2686, 233,0 },
+ {3189,3189, 0, 0, 40000, 0,0 },
+ {3190,3190, 0, 0, 40000, 73,0 },
+ {3191,3191, 0, 0, 40000, 0,0 },
+ {3192,3192, 0, 0, 40000, 73,0 },
+ {3193,3193, 0, 0, 40000, 0,0 },
+ {3194,3194, 0, 0, 3920, 73,0 },
+ {3195,3195, 0, 0, 40000, 73,0 },
+ {3196,3196, 0, 0, 40000, 66,0 },
+ {3197,3197, 0, 0, 40000, 80,0 },
+ {3198,3198, 0, 0, 40000, 86,0 },
+ {3199,3199, 0, 0, 40000, 60,0 },
+ {3200,3200, 0, 0, 40000, 0,0 },
+ {3201,3201, 0, 0, 40000, 353,0 },
+ {3202,3202, 0, 0, 3920, 73,0 },
+ {3203,3203, 0, 0, 5833, 813,0 },
+ {3204,3204, 0, 0, 40000, 60,0 },
+ {3205,3205, 0, 0, 40000, 73,0 },
+ {3206,3206, 0, 0, 1400, 406,0 },
+ {3207,3207, 0, 0, 40000, 66,0 },
+ {3208,3208, 0, 0, 9066, 2220,0 },
+ {3209,3209, 0, 0, 1473, 773,0 },
+ {3210,3210, 0, 0, 40000, 120,0 },
+ {3211,3211, 0, 0, 40000, 306,0 },
+ {3212,3212, 0, 0, 9306, 3013,0 },
+ {3213,3213, 0, 0, 40000, 60,0 },
+ {3214,3214, 0, 0, 40000, 73,0 },
+ {3215,3215, 0, 0, 40000, 73,0 },
+ {3216,3216, 0, 0, 40000, 453,0 },
+ {3217,3217, 0, 0, 40000, 3460,0 },
+ {3218,3218, 0, 0, 40000, 453,0 },
+ {3219,3219, 0, 0, 40000, 40,0 },
+ {3220,3220, 0, 0, 40000, 3926,0 },
+ {3221,3221, 0, 0, 40000, 4506,0 },
+ {3222,3222, 0, 0, 4646, 646,0 },
+ {3223,3223, 0, 0, 773, 100,0 },
+ {3224,3224, 0, 0, 40000, 73,0 },
+ {3225,3225, 0, 0, 40000, 173,0 },
+ {3226,3226, 0, 0, 1606, 653,0 },
+ {3227,3227, 0, 0, 2353, 806,0 },
+ {3228,3228, 0, 0, 980, 360,0 },
+ {3229,3229, 0, 0, 1193, 413,0 },
+ { 499, 499, 0, 0, 266, 0,0 },
+ {3230,3230, 0, 0, 973, 360,0 },
+ {3231,3231, 0, 0, 273, 53,0 },
+ {3232,3232, 0, 0, 726, 220,0 },
+ {3233,3233, 0, 0, 19933, 6093,0 },
+ {3234,3234, 0, 0, 40000, 0,0 },
+ { 403, 403, 0, 0, 40000, 73,0 },
+ {3235,3235, 0, 0, 4966, 233,0 },
+ {3236,3236, 0, 0, 4946, 240,0 },
+ {3237,3237, 0, 0, 4946, 233,0 },
+ {3238,3238, 0, 0, 4640, 1613,0 },
+ {3239,3239, 0, 0, 2360, 806,0 },
+ {3240,3240, 0, 0, 4466, 200,0 },
+ {3241,3241, 0, 0, 40000, 73,0 },
+ {3242,3242, 0, 0, 40000, 73,0 },
+ {3243,3243, 0, 0, 40000, 73,0 },
+ {3244,3244, 0, 0, 40000, 73,0 },
+ {3245,3245, 0, 0, 40000, 240,0 },
+ {3246,3246, 0, 0, 40000, 226,0 },
+ {3247,3247, 0, 0, 40000, 233,0 },
+ {3248,3248, 0, 0, 40000, 240,0 },
+ {3249,3249, 0, 0, 4306, 1253,0 },
+ {3250,3250, 0, 0, 3873, 1206,0 },
+ {3251,3251, 0, 0, 4640, 633,0 },
+ {3252,3252, 0, 0, 1233, 80,0 },
+ {3253,3253, 0, 0, 1233, 26,0 },
+ {3254,3254, 0, 0, 1233, 26,0 },
+ {3255,3255, 0, 0, 4573, 1253,0 },
+ {3256,3256, 0, 0, 3793, 1240,0 },
+ {3257,3257, 0, 0, 40000, 73,0 },
+ {3258,3258, 0, 0, 40000, 73,0 },
+ {3259,3259, 0, 0, 40000, 140,0 },
+ {3260,3260, 0, 0, 40000, 146,0 },
+ {3261,3261, 0, 0, 40000, 80,0 },
+ {3262,3262, 0, 0, 5953, 200,0 },
+ {3263,3263, 0, 0, 5926, 200,0 },
+ {3264,3264, 0, 0, 5866, 26,0 },
+ {3265,3265, 0, 0, 18573, 6153,0 },
+ {3266,3266, 0, 0, 40000, 2093,0 },
+ {3267,3267, 0, 0, 40000, 73,0 },
+ {3268,3268, 0, 0, 18626, 1553,0 },
+ {3269,3269, 0, 0, 40000, 1820,0 },
+ {3270,3270, 0, 0, 40000, 500,0 },
+ {3271,3271, 0, 0, 18206, 5900,0 },
+ {3272,3272, 0, 0, 14200, 93,0 },
+ {3273,3273, 0, 0, 40000, 2873,0 },
+ {3274,3274, 0, 0, 14960, 4913,0 },
+ {3275,3275, 0, 0, 40000, 86,0 },
+ {3276,3276, 0, 0, 40000, 826,0 },
+ {3277,3277, 0, 0, 40000, 200,0 },
+ {3278,3278, 0, 0, 40000, 340,0 },
+ {3279,3279, 0, 0, 13220, 2500,0 },
+ {3280,3280, 0, 0, 40000, 100,0 },
+ {3281,3281, 0, 0, 40000, 1026,0 },
+ {3282,3282, 0, 0, 40000, 366,0 },
+ {3283,3283, 0, 0, 40000, 386,0 },
+ {3284,3284, 0, 0, 40000, 0,0 },
+ {3285,3285, 0, 0, 40000, 0,0 },
+ {3286,3286, 0, 0, 40000, 140,0 },
+ {3287,3287, 0, 0, 40000, 53,0 },
+ {3288,3288, 0, 0, 40000, 120,0 },
+ {3289,3289, 0, 0, 8866, 1366,0 },
+ {3290,3290, 0, 0, 4193, 1400,0 },
+ {3291,3291, 0, 0, 8353, 673,0 },
+ {3292,3292, 0, 0, 8353, 673,0 },
+ {3293,3293, 0, 0, 8400, 593,0 },
+ {3294,3294, 0, 0, 8440, 666,0 },
+ {3295,3295, 0, 0, 9600, 1580,0 },
+ {3296,3296, 0, 0, 40000, 46,0 },
+ {3297,3297, 0, 0, 40000, 0,0 },
+ {3298,3298, 0, 0, 1653, 93,0 },
+ {3299,3299, 0, 0, 2706, 73,0 },
+ {3300,3300, 0, 0, 11680, 26,0 },
+ {3301,3301, 0, 0, 6500, 340,0 },
+ {3302,3302, 0, 0, 40000, 0,0 },
+ {3303,3303, 0, 0, 40000, 0,0 },
+ {3304,3304, 0, 0, 40000, 73,0 },
+ {3305,3305, 0, 0, 40000, 73,0 },
+ {3306,3306, 0, 0, 40000, 73,0 },
+ {3307,3307, 0, 0, 40000, 73,0 },
+ {3308,3308, 0, 0, 40000, 73,0 },
+ {3309,3309, 0, 0, 40000, 73,0 },
+ {3310,3310, 0, 0, 40000, 73,0 },
+ {3311,3311, 0, 0, 40000, 73,0 },
+ {3312,3312, 0, 0, 40000, 73,0 },
+ {3313,3313, 0, 0, 40000, 133,0 },
+ {3314,3314, 0, 0, 40000, 126,0 },
+ {3315,3315, 0, 0, 40000, 73,0 },
+ {3316,3316, 0, 0, 40000, 73,0 },
+ {3317,3317, 0, 0, 40000, 73,0 },
+ {3318,3318, 0, 0, 40000, 200,0 },
+ {3319,3319, 0, 0, 40000, 133,0 },
+ {3320,3320, 0, 0, 40000, 0,0 },
+ {3321,3321, 0, 0, 40000, 240,0 },
+ {3322,3322, 0, 0, 40000, 220,0 },
+ {3323,3323, 0, 0, 40000, 226,0 },
+ {3324,3324, 0, 0, 40000, 100,0 },
+ {3325,3325, 0, 0, 40000, 140,0 },
+ {3326,3326, 0, 0, 40000, 0,0 },
+ {3327,3327, 0, 0, 40000, 426,0 },
+ {3328,3328, 0, 0, 40000, 426,0 },
+ {3329,3329, 0, 0, 3680, 1220,0 },
+ {3330,3330, 0, 0, 40000, 533,0 },
+ {3331,3331, 0, 0, 40000, 813,0 },
+ {3332,3332, 0, 0, 14506, 4706,0 },
+ {3333,3333, 0, 0, 766, 420,0 },
+ {3334,3334, 0, 0, 40000, 1566,0 },
+ {3335,3335, 0, 0, 40000, 120,0 },
+ {3336,3336, 0, 0, 40000, 2380,0 },
+ {3337,3337, 0, 0, 5666, 300,0 },
+ {3338,3338, 0, 0, 40000, 73,0 },
+ {3339,3339, 0, 0, 40000, 2513,0 },
+ {3340,3340, 0, 0, 1260, 826,0 },
+ {3341,3341, 0, 0, 2420, 413,0 },
+ {3342,3342, 0, 0, 626, 240,0 },
+ {3343,3343, 0, 0, 273, 60,0 },
+ {3344,3344, 0, 0, 540, 20,0 },
+ {3345,3345, 0, 0, 540, 20,0 },
+ {3346,3346, 0, 0, 540, 20,0 },
+ {3347,3347, 0, 0, 1153, 760,0 },
+ {3348,3348, 0, 0, 40000, 100,0 },
+ {3349,3349, 0, 0, 7326, 2380,0 },
+ {3350,3350, 0, 0, 40000, 4426,0 },
+ {3351,3351, 0, 0, 7413, 2493,0 },
+ {3352,3352, 0, 0, 253, 20,0 },
+ {3353,3353, 0, 0, 246, 33,0 },
+ {3354,3354, 0, 0, 286, 13,0 },
+ {3355,3355, 0, 0, 953, 13,0 },
+ {3356,3356, 0, 0, 293, 20,0 },
+ { 142, 142, 20, 0, 1893, 620,0 },
+ {3357,1451, 0, 4, 2373, 780,0 },
+ {3358,3359, 0, 4, 9260, 246,0 },
+ {3360,1455, 0, 4, 40000, 0,0 },
+ {3361,1463, 0, 4, 40000, 266,0 },
+ { 225,3362, 0, 4, 7993, 100,0 },
+ {3363,1545, 0, 4, 293, 86,0 },
+ {3364,1547, 0, 4, 40000, 180,0 },
+ {3365,3366, 39, 4, 66, 0,0 },
+ {3367, 368, 58, 4, 173, 0,0 },
+ {3368,1551, 48, 4, 520, 200,0 },
+ {3368,3033, 49, 4, 53, 0,0 },
+ {3368,3033, 51, 4, 53, 0,0 },
+ {3368,3033, 54, 4, 60, 0,0 },
+ {3368,3033, 57, 4, 60, 0,0 },
+ {3368,3033, 60, 4, 60, 0,0 },
+ {3369,3370, 70, 4, 840, 0,0 },
+ {1564,1565, 80, 4, 220, 0,0 },
+ {3371,1571, 44, 4, 420, 0,0 },
+ {3372,3372, 0, 0, 8366, 666,0 },
+ {3373,3373, 0, 0, 8366, 666,0 },
+ {3374,3374, 0, 0, 3773, 73,0 },
+ {3375,3375, 0, 0, 8366, 666,0 },
+ {3376,3376, 0, 0, 4693, 26,0 },
+ {3377,3377, 0, 0, 7400, 80,0 },
+ {3378,3378, 0, 0, 3586, 80,0 },
+ {3379,3379, 0, 0, 8366, 666,0 },
+ {3380,3380, 0, 0, 3786, 1240,0 },
+ {3381,3381, 0, 0, 9013, 1466,0 },
+ {3382,3382, 0, 0, 1200, 73,0 },
+ {3383,3383, 0, 0, 8146, 1446,0 },
+ {3384,3384, 0, 0, 3660, 1206,0 },
+ {3385,3385, 0, 0, 200, 100,0 },
+ {3386,3386, 0, 0, 40000, 0,0 },
+ {3387,3387, 0, 0, 1213, 426,0 },
+ {3388,3388, 0, 0, 40000, 2573,0 },
+ {3389,3389, 0, 0, 40000, 3446,0 },
+ {3390,3390, 0, 0, 40000, 333,0 },
+ {3391,3391, 0, 0, 40000, 73,0 },
+ {3392,3392, 0, 0, 40000, 93,0 },
+ {3393,3393, 0, 0, 40000, 73,0 },
+ {3394,3394, 0, 0, 40000, 73,0 },
+ {3395,3395, 0, 0, 40000, 73,0 },
+ {3396,3396, 0, 0, 2193, 413,0 },
+ {3397,3397, 0, 0, 14606, 2886,0 },
+ {3398,3398, 0, 0, 10626, 4520,0 },
+ {3399,3399, 0, 0, 2413, 100,0 },
+ {3400,3400, 0, 0, 3593, 1140,0 },
+ {3401,3401, 0, 0, 40000, 146,0 },
+ {3402,3402, 0, 0, 40000, 86,0 },
+ {3403,3403, 0, 0, 40000, 86,0 },
+ {3404,3404, 0, 0, 9366, 106,0 },
+ {3405,3405, 0, 0, 40000, 73,0 },
+ {3406,3406, 0, 0, 40000, 0,0 },
+ {3407,3407, 0, 0, 40000, 0,0 },
+ {3408,3408, 0, 0, 1626, 400,0 },
+ {3409,3409, 0, 0, 4473, 2933,0 },
+ {3410,3410, 0, 0, 40000, 66,0 },
+ {3411,3411, 0, 0, 40000, 0,0 },
+ {3412,3412, 0, 0, 40000, 253,0 },
+ {3413,3413, 0, 0, 40000, 233,0 },
+ {3414,3414, 0, 0, 40000, 346,0 },
+ {3415,3415, 0, 0, 1966, 26,0 },
+ {3416,3416, 0, 0, 40000, 366,0 },
+ {3417,3417, 0, 0, 2266, 386,0 },
+ {3418,3418, 0, 0, 40000, 0,0 },
+ {3419,3419, 0, 0, 2313, 766,0 },
+ {3420,3420, 0, 0, 40000, 340,0 },
+ {3421,3421, 0, 0, 40000, 346,0 },
+ {3422,3422, 0, 0, 40000, 340,0 },
+ {3423,3423, 0, 0, 40000, 353,0 },
+ {3424,3424, 0, 0, 40000, 353,0 },
+ {3425,3425, 0, 0, 40000, 226,0 },
+ {3426,3426, 0, 0, 40000, 73,0 },
+ {3427,3427, 0, 0, 940, 253,0 },
+ {3428,3428, 0, 0, 40000, 73,0 },
+ {3429,3429, 0, 0, 40000, 80,0 },
+ {3430,3430, 0, 0, 40000, 240,0 },
+ {3431,3431, 0, 0, 40000, 80,0 },
+ {3432,3432, 0, 0, 40000, 73,0 },
+ {3433,3433, 0, 0, 40000, 73,0 },
+ {3434,3434, 0, 0, 40000, 73,0 },
+ {3435,3435, 0, 0, 40000, 73,0 },
+ {3436,3436, 0, 0, 40000, 73,0 },
+ {3437,3437, 0, 0, 40000, 73,0 },
+ {3438,3438, 0, 0, 40000, 73,0 },
+ {3439,3439, 0, 0, 40000, 73,0 },
+ {3440,3440, 0, 0, 40000, 73,0 },
+ {3441,3441, 0, 0, 40000, 73,0 },
+ {3442,3442, 0, 0, 40000, 66,0 },
+ {3443,3443, 0, 0, 40000, 73,0 },
+ {3444,3444, 0, 0, 40000, 80,0 },
+ {3445,3445, 0, 0, 40000, 66,0 },
+ {3446,3446, 0, 0, 40000, 66,0 },
+ {3447,3447, 0, 0, 40000, 66,0 },
+ {3448,3448, 0, 0, 40000, 66,0 },
+ {3449,3449, 0, 0, 40000, 80,0 },
+ {3450,3450, 0, 0, 40000, 353,0 },
+ {3451,3451, 0, 0, 40000, 0,0 },
+ {3452,3452, 0, 0, 18440, 100,0 },
+ {3453,3453, 0, 0, 18086, 100,0 },
+ {3454,3454, 0, 0, 266, 66,0 },
+ {3455,3455, 0, 0, 40000, 80,0 },
+ {3456,3456, 0, 0, 40000, 100,0 },
+ {3457,3457, 0, 0, 40000, 80,0 },
+ {3458,3458, 0, 0, 40000, 120,0 },
+ {3459,3459, 0, 0, 40000, 93,0 },
+ {3460,3460, 0, 0, 40000, 233,0 },
+ {3461,3461, 0, 0, 40000, 0,0 },
+ {3462,3462, 0, 0, 40000, 86,0 },
+ {3463,3463, 0, 0, 40000, 820,0 },
+ {3464,3464, 0, 0, 40000, 4986,0 },
+ {3465,3465, 0, 0, 40000, 146,0 },
+ {3466,3466, 0, 0, 40000, 100,0 },
+ {3467,3467, 0, 0, 40000, 3346,0 },
+ {3468,3468, 0, 0, 40000, 660,0 },
+ {3469,3469, 0, 0, 40000, 366,0 },
+ {3470,3470, 0, 0, 40000, 1480,0 },
+ {3471,3471, 0, 0, 40000, 646,0 },
+ {3472,3472, 0, 0, 40000, 2673,0 },
+ {3473,3473, 0, 0, 40000, 2500,0 },
+ {3474,3474, 0, 0, 40000, 2513,0 },
+ {3475,3475, 0, 0, 40000, 66,0 },
+ {3476,3476, 0, 0, 9600, 1580,0 },
+ {3477,3477, 0, 0, 40000, 46,0 },
+ {3478,3478, 0, 0, 10673, 100,0 },
+ {3479,3479, 0, 0, 2333, 800,0 },
+ {3480,3480, 0, 0, 3673, 1200,0 },
+ {3481,3481, 0, 0, 40000, 73,0 },
+ {3482,3482, 0, 0, 40000, 146,0 },
+ {3483,3483, 0, 0, 40000, 73,0 },
+ {3484,3484, 0, 0, 2266, 726,0 },
+ {3485,3485, 0, 0, 333, 140,0 },
+ {3486,3486, 0, 0, 2286, 746,0 },
+ {3487,3487, 0, 0, 293, 126,0 },
+ {3488,3488, 0, 0, 3700, 1213,0 },
+ {3489,3489, 0, 0, 3773, 1186,0 },
+ {3490,3490, 0, 0, 3646, 1200,0 },
+ {3491,3491, 0, 0, 3020, 73,0 },
+ {3492,3492, 0, 0, 786, 273,0 },
+ {3493,3493, 0, 0, 40000, 146,0 },
+ {3494,3494, 0, 0, 40000, 3093,0 },
+ {3495,3495, 0, 0, 273, 60,0 },
+ {3496,3496, 0, 0, 40000, 73,0 },
+ {3497,3497, 0, 0, 40000, 73,0 },
+ {3498,3498, 0, 0, 40000, 3093,0 },
+ {3499,3499, 0, 0, 40000, 240,0 },
+ {3500,3500, 0, 2, 6, 0,0 },
+ { 739, 739, 46, 0, 220, 33,0 },
+ {3501,3501, 47, 0, 973, 93,0 },
+ {3502,3502, 64, 0, 126, 66,0 },
+ {3503,3503, 40, 0, 340, 146,0 },
+ {3504,3504, 48, 0, 100, 0,0 },
+ {3505,3505, 48, 0, 286, 133,0 },
+ {3506,3506, 46, 0, 466, 166,0 },
+ {3507,3507,111, 0, 226, 113,0 },
+ {3508,3508, 49, 0, 473, 166,0 },
+ {3509,3509, 56, 0, 126, 40,0 },
+ {3510,3510, 52, 0, 520, 206,0 },
+ {3511,3511, 96, 0, 1346, 473,0 },
+ {3510,3510, 54, 0, 513, 206,0 },
+ {3512,3512, 57, 0, 973, 266,0 },
+ {3513,3513, 82, 0, 1580, 553,0 },
+ {3510,3510, 60, 0, 506, 200,0 },
+ {3514,3514, 60, 0, 1886, 646,0 },
+ {3515,3515, 92, 0, 1026, 520,0 },
+ {3516,3516, 60, 0, 180, 93,0 },
+ {3517,3517, 58, 0, 213, 213,0 },
+ {3518,3518, 22, 0, 2300, 766,0 },
+ {3519,3519, 60, 0, 1873, 653,0 },
+ {3520,3520, 72, 0, 260, 93,0 },
+ {3521,3521, 77, 0, 253, 93,0 },
+ {3522,3522, 70, 0, 206, 93,0 },
+ {3523,3523, 75, 0, 173, 93,0 },
+ {3524,3524, 69, 0, 406, 113,0 },
+ {3525,3525, 59, 0, 380, 160,0 },
+ {3526,3526, 48, 0, 373, 40,0 },
+ {3527,3527, 89, 0, 433, 180,0 },
+ {3528,3528, 84, 0, 813, 180,0 },
+ {3529,3529, 33, 0, 240, 53,0 },
+ {3530,3530, 55, 0, 220, 86,0 },
+ {3531,3531, 58, 0, 526, 200,0 },
+ {3532,3532, 52, 0, 526, 193,0 },
+ {3533,3533, 57, 0, 166, 80,0 },
+ {3534,3534, 57, 0, 240, 100,0 },
+ {3535,3535, 85, 0, 220, 113,0 },
+ {3536,3536, 68, 0, 173, 93,0 },
+ {3536,3536, 61, 0, 220, 113,0 },
+ {3537,3537, 64, 0, 346, 53,0 },
+ {3538,3538, 44, 0, 1080, 346,0 },
+ {3539,3539,100, 0, 193, 20,0 },
+ {3540,3540,100, 0, 793, 26,0 },
+ {3541,3541, 0, 0, 14166, 320,0 },
+ {3542,3542, 0, 0, 3873, 1613,0 },
+ {3543,3543, 0, 0, 3586, 86,0 },
+ {3544,3544, 0, 0, 7406, 2486,0 },
+ {3545,3545, 0, 0, 4640, 1560,0 },
+ {3546,3546, 0, 0, 446, 440,0 },
+ {3547,3547, 0, 0, 9253, 3100,0 },
+ {3548,3548, 0, 0, 4646, 646,0 },
+ {3549,3549, 0, 0, 40000, 66,0 },
+ {3550,3550, 0, 0, 40000, 73,0 },
+ {3551,3551, 0, 0, 40000, 113,0 },
+ {3552,3552, 0, 0, 40000, 73,0 },
+ {3553,3553, 0, 0, 40000, 73,0 },
+ {3554,3554, 0, 0, 40000, 0,0 },
+ {3555,3555, 0, 0, 40000, 60,0 },
+ {3556,3556, 0, 0, 3673, 1206,0 },
+ {3557,3557, 0, 0, 3706, 1293,0 },
+ {3558,3558, 0, 0, 5693, 1126,0 },
+ {3559,3559, 0, 0, 2406, 846,0 },
+ {3560,3560, 0, 0, 40000, 66,0 },
+ {3561,3561, 0, 0, 40000, 73,0 },
+ {3562,3562, 0, 0, 4333, 13,0 },
+ {3563,3563, 0, 0, 3700, 66,0 },
+ {3564,3564, 0, 0, 40000, 0,0 },
+ {3565,3565, 0, 0, 3713, 1260,0 },
+ {3566,3566, 0, 0, 1140, 126,0 },
+ {3567,3567, 0, 0, 40000, 186,0 },
+ {3568,3568, 0, 0, 40000, 0,0 },
+ {3569,3569, 0, 0, 14400, 6,0 },
+ {3570,3570, 0, 0, 14580, 66,0 },
+ {3571,3571, 0, 0, 40000, 73,0 },
+ {3572,3572, 0, 0, 40000, 353,0 },
+ {3573,3573, 0, 0, 40000, 0,0 },
+ {3574,3574, 0, 0, 40000, 173,0 },
+ {3575,3575, 0, 0, 1833, 600,0 },
+ {3576,3576, 0, 0, 40000, 0,0 },
+ {3577,3577, 0, 0, 40000, 206,0 },
+ {3578,3578, 0, 0, 40000, 46,0 },
+ {3579,3579, 0, 0, 40000, 73,0 },
+ {3580,3580, 0, 0, 9166, 2900,0 },
+ {3581,3581, 0, 0, 5640, 680,0 },
+ {3582,3582, 0, 0, 640, 220,0 },
+ {3583,3583, 0, 0, 40000, 53,0 },
+ {3584,3584, 0, 0, 40000, 26,0 },
+ {3585,3585, 0, 0, 40000, 0,0 },
+ {3586,3586, 0, 0, 40000, 66,0 },
+ {3587,3587, 0, 0, 40000, 60,0 },
+ {3588,3588, 0, 0, 40000, 0,0 },
+ {3589,3589, 0, 0, 40000, 73,0 },
+ {3590,3590, 0, 0, 40000, 0,0 },
+ {3591,3591, 0, 0, 40000, 0,0 },
+ {3592,3592, 0, 0, 3780, 73,0 },
+ {3593,3593, 0, 0, 40000, 0,0 },
+ {3594,3594, 0, 0, 3786, 73,0 },
+ {3595,3595, 0, 0, 40000, 73,0 },
+ {3596,3596, 0, 0, 40000, 66,0 },
+ {3597,3597, 0, 0, 40000, 73,0 },
+ {3598,3598, 0, 0, 40000, 53,0 },
+ {3599,3599, 0, 0, 40000, 426,0 },
+ {3600,3600, 0, 0, 40000, 133,0 },
+ {3601,3601, 0, 0, 40000, 66,0 },
+ {3602,3602, 0, 0, 40000, 433,0 },
+ {3603,3603, 0, 0, 393, 126,0 },
+ {3604,3604, 0, 0, 40000, 66,0 },
+ {3605,3605, 0, 0, 40000, 353,0 },
+ {3606,3606, 0, 0, 3813, 73,0 },
+ {3607,3607, 0, 0, 5793, 780,0 },
+ {3608,3608, 0, 0, 40000, 73,0 },
+ {3609,3609, 0, 0, 40000, 86,0 },
+ {3610,3610, 0, 0, 820, 206,0 },
+ {3611,3611, 0, 0, 40000, 66,0 },
+ {3612,3612, 0, 0, 40000, 200,0 },
+ {3613,3613, 0, 0, 18186, 720,0 },
+ {3614,3614, 0, 0, 40000, 0,0 },
+ {3615,3615, 0, 0, 40000, 493,0 },
+ {3616,3616, 0, 0, 40000, 306,0 },
+ {3617,3617, 0, 0, 2166, 600,0 },
+ {3618,3618, 0, 0, 40000, 73,0 },
+ {3619,3619, 0, 0, 40000, 3073,0 },
+ {3620,3620, 0, 0, 2333, 413,0 },
+ {3621,3621, 0, 0, 14880, 73,0 },
+ {3622,3622, 0, 0, 40000, 66,0 },
+ {3623,3623, 0, 0, 40000, 73,0 },
+ {3624,3624, 0, 0, 40000, 1873,0 },
+ {3625,3625, 0, 0, 40000, 446,0 },
+ {3626,3626, 0, 0, 40000, 3126,0 },
+ {3627,3627, 0, 0, 18446, 6140,0 },
+ {3628,3628, 0, 0, 1113, 240,0 },
+ {3629,3629, 0, 0, 40000, 3600,0 },
+ {3630,3630, 0, 0, 40000, 4726,0 },
+ {3631,3631, 0, 0, 40000, 0,0 },
+ {3632,3632, 0, 0, 2893, 606,0 },
+ {3633,3633, 0, 0, 40000, 0,0 },
+ {3634,3634, 0, 0, 40000, 0,0 },
+ {3635,3635, 0, 0, 40000, 173,0 },
+ {3636,3636, 0, 0, 40000, 60,0 },
+ {3637,3637, 0, 0, 40000, 0,0 },
+ {3638,3638, 0, 0, 986, 326,0 },
+ {3639,3639, 0, 0, 1873, 646,0 },
+ {3640,3640, 0, 0, 200, 260,0 },
+ {3641,3641, 0, 0, 1180, 393,0 },
+ {3642,3642, 0, 0, 266, 0,0 },
+ {3643,3643, 0, 0, 313, 126,0 },
+ {3644,3644, 0, 0, 406, 253,0 },
+ {3645,3645, 0, 0, 1013, 813,0 },
+ {3646,3646, 0, 0, 273, 53,0 },
+ {3647,3647, 0, 0, 720, 213,0 },
+ {3648,3648, 0, 0, 386, 120,0 },
+ {3649,3649, 0, 0, 40000, 766,0 },
+ {3650,3650, 0, 0, 40000, 66,0 },
+ {3651,3651, 0, 0, 40000, 73,0 },
+ {3652,3652, 0, 0, 1186, 426,0 },
+ {3653,3653, 0, 0, 16720, 240,0 },
+ {3654,3654, 0, 0, 8026, 246,0 },
+ {3655,3655, 0, 0, 18186, 140,0 },
+ {3656,3656, 0, 0, 14566, 200,0 },
+ {3657,3657, 0, 0, 7973, 20,0 },
+ {3658,3658, 0, 0, 4446, 86,0 },
+ {3659,3659, 0, 0, 4473, 100,0 },
+ {3660,3660, 0, 0, 8646, 153,0 },
+ {3661,3661, 0, 0, 3726, 660,0 },
+ {3662,3662, 0, 0, 1893, 653,0 },
+ {3663,3663, 0, 0, 1933, 760,0 },
+ {3664,3664, 0, 0, 9160, 240,0 },
+ {3665,3665, 0, 0, 1133, 100,0 },
+ {3666,3666, 0, 0, 633, 233,0 },
+ {3667,3667, 0, 0, 9153, 3060,0 },
+ {3668,3668, 0, 0, 2166, 406,0 },
+ {3669,3669, 0, 0, 40000, 66,0 },
+ {3670,3670, 0, 0, 40000, 73,0 },
+ {3671,3671, 0, 0, 40000, 73,0 },
+ {3672,3672, 0, 0, 40000, 73,0 },
+ {3673,3673, 0, 0, 40000, 346,0 },
+ {3674,3674, 0, 0, 40000, 353,0 },
+ {3675,3675, 0, 0, 40000, 200,0 },
+ {3676,3676, 0, 0, 40000, 320,0 },
+ {3677,3677, 0, 0, 4646, 100,0 },
+ {3678,3678, 0, 0, 4426, 133,0 },
+ {3679,3679, 0, 0, 4633, 100,0 },
+ {3680,3680, 0, 0, 2266, 133,0 },
+ {3681,3681, 0, 0, 2346, 53,0 },
+ {3682,3682, 0, 0, 40000, 66,0 },
+ {3683,3683, 0, 0, 9686, 173,0 },
+ {3684,3684, 0, 0, 14300, 66,0 },
+ {3685,3685, 0, 0, 40000, 0,0 },
+ {3686,3686, 0, 0, 40000, 0,0 },
+ {3687,3687, 0, 0, 40000, 0,0 },
+ {3688,3688, 0, 0, 8613, 73,0 },
+ {3689,3689, 0, 0, 40000, 0,0 },
+ {3690,3690, 0, 0, 40000, 0,0 },
+ {3691,3691, 0, 0, 40000, 0,0 },
+ {3692,3692, 0, 0, 40000, 0,0 },
+ {3693,3693, 0, 0, 40000, 393,0 },
+ {3694,3694, 0, 0, 40000, 126,0 },
+ {3695,3695, 0, 0, 40000, 120,0 },
+ {3696,3696, 0, 0, 40000, 0,0 },
+ {3697,3697, 0, 0, 40000, 226,0 },
+ {3698,3698, 0, 0, 7420, 1186,0 },
+ {3699,3699, 0, 0, 3280, 1726,0 },
+ {3700,3700, 0, 0, 3680, 1220,0 },
+ {3701,3701, 0, 0, 40000, 480,0 },
+ {3702,3702, 0, 0, 40000, 306,0 },
+ {3703,3703, 0, 0, 40000, 433,0 },
+ {3704,3704, 0, 0, 40000, 133,0 },
+ {3705,3705, 0, 0, 40000, 0,0 },
+ {3706,3706, 0, 0, 40000, 0,0 },
+ {3707,3707, 0, 0, 1166, 380,0 },
+ {3708,3708, 0, 0, 40000, 140,0 },
+ {3709,3709, 0, 0, 40000, 126,0 },
+ {3710,3710, 0, 0, 40000, 100,0 },
+ {3711,3711, 0, 0, 40000, 66,0 },
+ {3712,3712, 0, 0, 40000, 226,0 },
+ {3713,3713, 0, 0, 40000, 133,0 },
+ {3714,3714, 0, 0, 40000, 73,0 },
+ {3715,3715, 0, 0, 40000, 226,0 },
+ {3716,3716, 0, 0, 40000, 100,0 },
+ {3717,3717, 0, 0, 40000, 80,0 },
+ {3718,3718, 0, 0, 40000, 100,0 },
+ {3719,3719, 0, 0, 40000, 73,0 },
+ {3720,3720, 0, 0, 40000, 73,0 },
+ {3721,3721, 0, 0, 40000, 73,0 },
+ {3722,3722, 0, 0, 40000, 126,0 },
+ {3723,3723, 0, 0, 40000, 80,0 },
+ {3724,3724, 0, 0, 40000, 73,0 },
+ {3725,3725, 0, 0, 40000, 86,0 },
+ {3726,3726, 0, 0, 40000, 100,0 },
+ {3727,3727, 0, 0, 40000, 0,0 },
+ {3728,3728, 0, 0, 40000, 126,0 },
+ {3729,3729, 0, 0, 40000, 133,0 },
+ {3730,3730, 0, 0, 40000, 140,0 },
+ {3731,3731, 0, 0, 40000, 73,0 },
+ {3732,3732, 0, 0, 40000, 60,0 },
+ {3733,3733, 0, 0, 40000, 93,0 },
+ {3734,3734, 0, 0, 40000, 80,0 },
+ {3735,3735, 0, 0, 40000, 66,0 },
+ {3736,3736, 0, 0, 40000, 0,0 },
+ {3737,3737, 0, 0, 40000, 220,0 },
+ {3738,3738, 0, 0, 40000, 80,0 },
+ {3739,3739, 0, 0, 40000, 400,0 },
+ {3740,3740, 0, 0, 40000, 1373,0 },
+ {3741,3741, 0, 0, 40000, 86,0 },
+ {3742,3742, 0, 0, 40000, 1313,0 },
+ {3743,3743, 0, 0, 40000, 0,0 },
+ {3744,3744, 0, 0, 11486, 593,0 },
+ {3745,3745, 0, 0, 40000, 1246,0 },
+ {3746,3746, 0, 0, 40000, 140,0 },
+ {3747,3747, 0, 0, 14386, 2680,0 },
+ {3748,3748, 0, 0, 40000, 653,0 },
+ {3749,3749, 0, 0, 2286, 713,0 },
+ {3750,3750, 0, 0, 40000, 253,0 },
+ {3751,3751, 0, 0, 6933, 406,0 },
+ {3752,3752, 0, 0, 40000, 1313,0 },
+ {3753,3753, 0, 0, 40000, 1440,0 },
+ {3754,3754, 0, 0, 40000, 73,0 },
+ {3755,3755, 0, 0, 11100, 420,0 },
+ {3756,3756, 0, 0, 6493, 320,0 },
+ {3757,3757, 0, 0, 3486, 126,0 },
+ {3758,3758, 0, 0, 6620, 2133,0 },
+ {3759,3759, 0, 0, 1180, 413,0 },
+ {3760,3760, 0, 0, 40000, 73,0 },
+ {3761,3761, 0, 0, 40000, 73,0 },
+ {3762,3762, 0, 0, 40000, 66,0 },
+ {3763,3763, 0, 0, 4580, 413,0 },
+ {3764,3764, 0, 0, 340, 146,0 },
+ {3765,3765, 0, 0, 1166, 400,0 },
+ {3766,3766, 0, 0, 1346, 660,0 },
+ {3767,3767, 0, 0, 1260, 393,0 },
+ {3768,3768, 0, 0, 3646, 1186,0 },
+ {3769,3769, 0, 0, 2713, 400,0 },
+ {3770,3770, 0, 0, 1780, 73,0 },
+ {3771,3771, 0, 0, 800, 213,0 },
+ {3772,3772, 0, 0, 660, 173,0 },
+ {3773,3773, 0, 0, 12146, 73,0 },
+ {3774,3774, 0, 0, 273, 60,0 },
+ {3775,3775, 0, 0, 40000, 73,0 },
+ {3776,3776, 0, 0, 380, 53,0 },
+ {3777,3777, 0, 0, 40000, 200,0 },
+ {3778,3778, 0, 0, 586, 20,0 },
+ {3779,3779, 0, 2, 6, 0,0 },
+ { 738, 738, 44, 0, 840, 340,0 },
+ {3780,3780, 36, 0, 7366, 140,0 },
+ {3781,3781, 32, 0, 100, 0,0 },
+ {2030,2030, 60, 0, 293, 126,0 },
+ {3782,3782, 24, 0, 100, 0,0 },
+ {3783,3783, 60, 0, 126, 73,0 },
+ {3784,3784, 44, 0, 393, 93,0 },
+ { 132, 132, 44, 0, 173, 100,0 },
+ {3785,3785, 47, 0, 393, 93,0 },
+ { 152, 152, 44, 0, 213, 86,0 },
+ {3784,3784, 50, 0, 393, 93,0 },
+ { 139, 139, 44, 0, 293, 100,0 },
+ {3784,3784, 54, 0, 393, 93,0 },
+ {3784,3784, 57, 0, 393, 93,0 },
+ {3786,3786, 60, 0, 1900, 666,0 },
+ {3784,3784, 60, 0, 393, 93,0 },
+ {3787,3787, 60, 0, 1900, 666,0 },
+ {3788,3788, 60, 0, 1886, 666,0 },
+ {3789,3789, 60, 0, 1866, 653,0 },
+ {3790,3790, 60, 0, 1873, 633,0 },
+ {3791,3791, 44, 0, 946, 333,0 },
+ {2037,2037, 44, 0, 213, 126,0 },
+ { 144, 144, 44, 0, 213, 126,0 },
+ {2038,2038, 44, 0, 106, 0,0 },
+ {3792,3792, 44, 0, 380, 360,0 },
+ {3793,3793, 44, 0, 520, 206,0 },
+ {3794,3794, 45, 0, 273, 100,0 },
+ {3795,3795, 33, 0, 326, 106,0 },
+ {3796,3796, 56, 0, 506, 200,0 },
+ {3796,3796, 51, 0, 506, 200,0 },
+ {3797,3797, 44, 0, 126, 66,0 },
+ {3798,3798, 44, 0, 553, 186,0 },
+ {3534,3534, 56, 0, 240, 100,0 },
+ { 158, 158, 68, 0, 126, 140,0 },
+ {3799,3799, 51, 0, 513, 206,0 },
+ {3800,3800, 46, 0, 506, 200,0 },
+ {3801,3801, 44, 0, 513, 206,0 },
+ {3802,3802, 44, 0, 3720, 1260,0 },
+ { 152, 152, 45, 0, 220, 80,0 },
+ {3803,3803, 0, 0, 40000, 86,0 },
+ {3804,3804, 0, 0, 40000, 226,0 },
+ {3805,3805, 0, 0, 40000, 73,0 },
+ {3806,3806, 0, 0, 40000, 73,0 },
+ {3807,3807, 0, 0, 40000, 93,0 },
+ {3808,3808, 0, 0, 4653, 660,0 },
+ {3809,3809, 0, 0, 6686, 2246,0 },
+ {3810,3810, 0, 0, 1180, 413,0 },
+ {3811,3811, 0, 0, 966, 293,0 },
+ {3812,3812, 0, 0, 1780, 66,0 },
+ {3780,3780, 45, 0, 5900, 113,0 },
+ {3061,3061, 45, 0, 40000, 0,0 },
+ {3813,3813, 60, 0, 126, 226,0 },
+ {3781,3781, 60, 0, 93, 0,0 },
+ {3814,3814, 44, 0, 393, 86,0 },
+ {3815,3815, 57, 0, 166, 80,0 },
+ {3816,3816, 56, 0, 240, 100,0 },
+ {3817,3817, 60, 0, 113, 0,0 },
+ {3818,3818, 60, 0, 113, 0,0 },
+ {3517,3517, 45, 0, 213, 213,0 },
+ {3819,3819, 0, 0, 4033, 100,0 },
+ {3820,3820, 0, 0, 5200, 873,0 },
+ {3821,3821, 0, 0, 40000, 0,0 },
+ {3822,3822, 0, 0, 10493, 160,0 },
+ {3823,3823, 0, 0, 40000, 740,0 },
+ {3824,3825, 0, 1, 40000, 366,0.078125 },
+ {3826,3826, 0, 0, 40000, 5100,0 },
+ {3827,3827, 0, 0, 40000, 766,0 },
+ {3828,1172, 0, 1, 40000, 780,0.15625 },
+ {3829,3829, 0, 0, 40000, 60,0 },
+ {3830,3830, 0, 0, 566, 133,0 },
+ {3831,3831, 32, 0, 146, 0,0 },
+ {3832,3832, 36, 0, 273, 0,0 },
+ {3833,3833, 88, 0, 340, 120,0 },
+ {3834,3834, 0, 0, 9006, 240,0 },
+ {3835,3835, 0, 0, 9206, 246,0 },
+ {3836,3836, 0, 0, 9246, 386,0 },
+ {3837,3837, 0, 0, 9440, 220,0 },
+ {3838,3838, 0, 0, 8900, 133,0 },
+ {3839,3839, 0, 0, 9400, 253,0 },
+ {3840,3840, 0, 0, 4613, 420,0 },
+ {3841,3841, 0, 0, 9233, 426,0 },
+ {3842,3842, 0, 0, 40000, 526,0 },
+ {3843,3843, 0, 0, 40000, 640,0 },
+ {3844,3844, 0, 0, 40000, 666,0 },
+ {3845,3845, 0, 0, 40000, 1053,0 },
+ {3846,3846, 0, 0, 40000, 173,0 },
+ {3847,3847, 0, 0, 40000, 246,0 },
+ {3848,3848, 0, 0, 40000, 226,0 },
+ {3849,3849, 0, 0, 4073, 233,0 },
+ {3850,3850, 0, 0, 14286, 326,0 },
+ {3851,3851, 0, 0, 9233, 146,0 },
+ {3852,3852, 0, 0, 4480, 133,0 },
+ {3853,3853, 0, 0, 40000, 53,0 },
+ {3854,3854, 0, 0, 40000, 126,0 },
+ {3855,3855, 0, 0, 40000, 126,0 },
+ {3856,3856, 0, 0, 18226, 146,0 },
+ {3857,3857, 0, 0, 40000, 326,0 },
+ {3858,3858, 0, 0, 40000, 0,0 },
+ {3859,3859, 0, 0, 40000, 300,0 },
+ {3860,3860, 0, 0, 40000, 0,0 },
+ {3861,3861, 0, 0, 40000, 0,0 },
+ {3862,3862, 0, 0, 40000, 0,0 },
+ {3863,3863, 0, 0, 40000, 140,0 },
+ {3864,3864, 0, 0, 40000, 153,0 },
+ {3865,3865, 0, 0, 40000, 233,0 },
+ {3866,3866, 0, 0, 40000, 186,0 },
+ {3867,3867, 0, 0, 40000, 413,0 },
+ {3868,3868, 0, 0, 40000, 373,0 },
+ {3869,3869, 0, 0, 1246, 440,0 },
+ {3870,3870, 0, 0, 4620, 1513,0 },
+ {3871,3871, 0, 0, 40000, 433,0 },
+ {3872,3872, 0, 0, 40000, 453,0 },
+ {3873,3873, 0, 0, 40000, 1440,0 },
+ {3874,3874, 0, 0, 40000, 480,0 },
+ {3875,3875, 0, 0, 40000, 1360,0 },
+ {3876,3876, 0, 0, 40000, 0,0 },
+ {3877,3877, 0, 0, 40000, 353,0 },
+ {3878,3878, 0, 0, 40000, 86,0 },
+ {3879,3879, 0, 0, 40000, 126,0 },
+ {3880,3880, 0, 0, 40000, 73,0 },
+ {3881,3881, 0, 0, 40000, 80,0 },
+ {3882,3882, 0, 0, 40000, 246,0 },
+ {3883,3883, 0, 0, 40000, 93,0 },
+ {3884,3884, 0, 0, 40000, 120,0 },
+ {3885,3885, 0, 0, 40000, 180,0 },
+ {3886,3886, 0, 0, 40000, 133,0 },
+ {3887,3887, 0, 0, 40000, 133,0 },
+ {3888,3888, 0, 0, 40000, 153,0 },
+ {3889,3889, 0, 0, 40000, 93,0 },
+ {3890,3890, 0, 0, 40000, 140,0 },
+ {3891,3891, 0, 0, 40000, 100,0 },
+ {3892,3892, 0, 0, 40000, 146,0 },
+ {3893,3893, 0, 0, 40000, 126,0 },
+ {3894,3894, 0, 0, 40000, 160,0 },
+ {3895,3895, 0, 0, 40000, 226,0 },
+ {3896,3896, 0, 0, 40000, 140,0 },
+ {3897,3897, 0, 0, 40000, 200,0 },
+ {3898,3898, 0, 0, 40000, 66,0 },
+ {3899,3899, 0, 0, 40000, 446,0 },
+ {3900,3900, 0, 0, 40000, 140,0 },
+ {3901,3901, 0, 0, 40000, 400,0 },
+ {3902,3902, 0, 0, 40000, 373,0 },
+ {3903,3903, 0, 0, 40000, 1306,0 },
+ {3904,3904, 0, 0, 40000, 186,0 },
+ {3905,3905, 0, 0, 40000, 640,0 },
+ {3906,3906, 0, 0, 40000, 346,0 },
+ {3907,3907, 0, 0, 40000, 140,0 },
+ {3908,3908, 0, 0, 40000, 253,0 },
+ {3909,3909, 0, 0, 8980, 746,0 },
+ {3910,3910, 0, 0, 40000, 1266,0 },
+ {3911,3911, 0, 0, 40000, 1306,0 },
+ {3912,3912, 0, 0, 7226, 593,0 },
+ {3913,3913, 0, 0, 40000, 140,0 },
+ {3914,3914, 0, 0, 40000, 220,0 },
+ {3915,3915, 0, 0, 40000, 146,0 },
+ {3916,3916, 0, 0, 4606, 1506,0 },
+ {3917,3917, 0, 0, 40000, 80,0 },
+ {3918,3918, 0, 0, 40000, 0,0 },
+ {3919,3919, 0, 0, 40000, 0,0 },
+ {3920,3920, 0, 0, 613, 226,0 },
+ {3921,3921, 0, 0, 9073, 2946,0 },
+ {3922,3922, 0, 0, 40000, 73,0 },
+ {3923,3923, 0, 0, 3726, 200,0 },
+ {3924,3924, 0, 0, 3680, 373,0 },
+ {3925,3925, 0, 0, 7113, 186,0 },
+ {3926,3926, 0, 0, 2406, 106,0 },
+ {3927,3927, 0, 0, 40000, 0,0 },
+ {3928,3928, 0, 0, 40000, 253,0 },
+ {3929,3929, 0, 0, 40000, 0,0 },
+ {3930,3930, 0, 0, 40000, 80,0 },
+ {3931,3931, 0, 0, 40000, 86,0 },
+ {3932,3932, 0, 0, 18186, 740,0 },
+ {3933,3933, 0, 0, 18426, 813,0 },
+ { 523, 523, 0, 0, 200, 260,0 },
+ {3934,3934, 0, 0, 340, 146,0 },
+ {3935,3935, 0, 0, 366, 260,0 },
+ {3936,3936, 48, 0, 126, 0,0 },
+ {3937,3937, 27, 0, 200, 106,0 },
+ {3938,3938, 40, 0, 1073, 800,0 },
+ {3939,3939, 48, 0, 100, 0,0 },
+ {3938,3938, 45, 0, 933, 666,0 },
+ {3940,3940, 48, 0, 140, 333,0 },
+ {3938,3938, 47, 0, 933, 666,0 },
+ {3941,3941, 48, 0, 1840, 0,0 },
+ {3938,3938, 49, 0, 953, 686,0 },
+ {3938,3938, 53, 0, 906, 686,0 },
+ {3938,3938, 56, 0, 913, 693,0 },
+ { 129, 129, 52, 0, 293, 126,0 },
+ { 130, 130, 48, 0, 173, 93,0 },
+ { 129, 129, 58, 0, 286, 126,0 },
+ { 132, 132, 47, 0, 173, 100,0 },
+ { 492, 492, 43, 0, 820, 306,0 },
+ { 132, 132, 49, 0, 173, 93,0 },
+ { 132, 132, 51, 0, 173, 93,0 },
+ { 132, 132, 54, 0, 173, 93,0 },
+ { 132, 132, 57, 0, 146, 86,0 },
+ { 492, 492, 72, 0, 706, 300,0 },
+ { 137, 137, 76, 0, 1900, 666,0 },
+ { 138, 138, 84, 0, 740, 300,0 },
+ { 139, 139, 36, 0, 353, 146,0 },
+ { 140, 140, 76, 0, 1886, 680,0 },
+ { 141, 141, 84, 0, 220, 113,0 },
+ { 135, 135, 83, 0, 1353, 480,0 },
+ { 142, 142, 84, 0, 386, 160,0 },
+ {3942,3942, 24, 0, 2313, 780,0 },
+ { 137, 137, 77, 0, 1893, 660,0 },
+ { 144, 144, 60, 0, 213, 0,0 },
+ { 145, 145, 65, 0, 180, 146,0 },
+ { 146, 146, 59, 0, 173, 93,0 },
+ { 147, 147, 51, 0, 266, 213,0 },
+ { 148, 148, 45, 0, 513, 200,0 },
+ { 149, 149, 71, 0, 246, 26,0 },
+ { 150, 150, 60, 0, 500, 193,0 },
+ { 151, 151, 58, 0, 513, 200,0 },
+ { 152, 152, 53, 0, 220, 86,0 },
+ { 153, 153, 64, 0, 113, 40,0 },
+ { 154, 154, 71, 0, 840, 300,0 },
+ { 156, 156, 61, 0, 166, 80,0 },
+ { 158, 158, 48, 0, 173, 213,0 },
+ { 159, 159, 69, 0, 126, 140,0 },
+ { 160, 160, 68, 0, 126, 140,0 },
+ { 161, 161, 63, 0, 326, 113,0 },
+ { 162, 162, 74, 0, 860, 286,0 },
+ { 163, 163, 60, 0, 386, 160,0 },
+ { 164, 164, 80, 0, 1106, 273,0 },
+ { 165, 165, 64, 0, 126, 66,0 },
+ { 166, 166, 69, 0, 386, 80,0 },
+ { 167, 167, 73, 0, 546, 306,0 },
+ { 168, 168, 75, 0, 126, 140,0 },
+ { 169, 169, 68, 0, 340, 320,0 },
+ { 131, 131, 48, 0, 520, 200,0 },
+ {3061,3061, 53, 0, 40000, 0,0 },
+ {3943,3944, 0, 4, 2153, 0,0 },
+ {3945,3946, 0, 4, 9060, 393,0 },
+ { 174,3947, 0, 4, 6953, 0,0 },
+ {3948,3949, 0, 4, 9386, 140,0 },
+ { 9,3950, 0, 4, 1626, 426,0 },
+ {3951,3952, 0, 4, 18466, 240,0 },
+ {3953,3954, 0, 4, 4666, 1486,0 },
+ { 15,3955, 0, 4, 5700, 1986,0 },
+ {3956,3957, 0, 4, 40000, 100,0 },
+ {3958,3959, 0, 4, 40000, 73,0 },
+ {3960,3961, 0, 4, 40000, 73,0 },
+ {3962,3963, 0, 4, 40000, 73,0 },
+ {3964,3965, 0, 4, 18280, 153,0 },
+ {3966,3965, 0, 4, 18686, 160,0 },
+ { 31,3967, 0, 4, 40000, 0,0 },
+ {3968,3969, 0, 4, 17966, 100,0 },
+ {3970,3971, 0, 4, 40000, 66,0 },
+ {3972,3971, 0, 4, 40000, 66,0 },
+ {3973,3974, 0, 4, 40000, 46,0 },
+ {3975,3976, 0, 4, 18693, 106,0 },
+ {3977,3976, 0, 4, 18593, 106,0 },
+ {3978,3979, 0, 4, 9366, 106,0 },
+ {3980,3981, 0, 4, 9120, 226,0 },
+ {3982,3983, 0, 4, 40000, 140,0 },
+ {3984,3985, 0, 4, 40000, 800,0 },
+ { 54,3986, 0, 4, 2520, 706,0 },
+ {3987,3988, 0, 4, 40000, 86,0 },
+ {3989,3990, 0, 4, 40000, 233,0 },
+ {3991, 253, 0, 4, 40000, 66,0 },
+ {3992,3992, 0, 0, 40000, 0,0 },
+ {3993,3993, 0, 0, 40000, 120,0 },
+ {3994,3995, 0, 4, 40000, 80,0 },
+ {3996,3997, 0, 4, 40000, 73,0 },
+ {3998,3999, 0, 4, 40000, 86,0 },
+ {1503,4000, 0, 4, 40000, 93,0 },
+ { 88,4001, 0, 4, 40000, 1220,0 },
+ {3743,4002, 0, 4, 7706, 1260,0 },
+ { 92,4003, 0, 4, 40000, 186,0 },
+ { 93,4004, 0, 4, 40000, 813,0 },
+ { 94,4005, 0, 4, 7720, 1260,0 },
+ { 96,4006, 0, 4, 40000, 2460,0 },
+ { 103,4007, 0, 4, 3720, 1240,0 },
+ { 104,4008, 0, 4, 3020, 1226,0 },
+ { 105,4009, 0, 4, 6086, 2453,0 },
+ { 107,4010, 0, 4, 2100, 760,0 },
+ { 108,4011, 0, 4, 40000, 73,0 },
+ { 110,4012, 0, 4, 40000, 100,0 },
+ { 111,4013, 0, 4, 2366, 820,0 },
+ {4014,4015, 0, 4, 1026, 326,0 },
+ { 115,4016, 0, 4, 1853, 0,0 },
+ { 118,4017, 0, 4, 1553, 53,0 },
+ { 119,4018, 0, 4, 593, 0,0 },
+ { 120,4019, 0, 4, 2293, 1173,0 },
+ { 121,4020, 0, 4, 10673, 3000,0 },
+ { 123,4021, 0, 4, 7413, 2486,0 },
+ { 124,4022, 0, 4, 40000, 1126,0 },
+ { 125,4023, 0, 4, 40000, 1546,0 },
+ {4024,4024, 35, 0, 706, 266,0 },
+ {4025,4026, 38, 1, 273, 106,0 },
+ {4027,4028, 38, 1, 366, 133,0 },
+ {4029,4030, 48, 1, 280, 133,-1.90625 },
+ {4031,4031, 51, 0, 113, 80,0 },
+ {4032,4033, 48, 1, 953, 346,-1.90625 },
+ {4034,4034, 61, 1, 3200, 540,0.09375 },
+ {3369,1557, 70, 4, 833, 0,0 },
+ {4035,4036, 79, 1, 1306, 513,0.078125 },
+ {4037,4037, 62, 0, 5200, 466,0 },
+ {4038,4039, 67, 1, 2153, 1080,0.078125 },
+ {4040,4040, 62, 1, 3226, 573,0.09375 },
+ {4041,4042, 54, 1, 286, 133,0 },
+ {4041,4043, 48, 1, 286, 126,0 },
+ { 389, 389, 42, 0, 266, 73,0 },
+ {4044,4045, 48, 1, 280, 126,0 },
+ {4046,4047, 48, 1, 380, 60,0 },
+ {4048,4048, 16, 0, 180, 20,0 },
+ {4049,4049, 16, 0, 740, 20,0 },
+ {4050,4051, 64, 4, 1366, 0,0 },
+ { 844, 844,244, 2, 6, 0,0 },
+ { 855, 855,244, 2, 6, 0,0 },
+ { 880, 880,232, 0, 253, 80,0 },
+ { 882, 882,220, 0, 40000, 266,0 },
+ { 887, 887, 35, 0, 133, 46,0 },
+ { 884, 884, 35, 0, 233, 80,0 },
+ { 885, 885, 35, 0, 226, 86,0 },
+ { 886, 886, 35, 0, 113, 0,0 },
+ { 361, 361, 35, 0, 286, 73,0 },
+ { 767, 767, 35, 0, 3020, 786,0 },
+ { 888, 888, 35, 0, 246, 53,0 },
+ {2141,2141, 35, 0, 186, 73,0 },
+ { 891, 891, 35, 0, 713, 266,0 },
+ {2142,2142, 35, 0, 200, 100,0 },
+ {2143,2143, 35, 0, 220, 80,0 },
+ {2144,2144, 35, 0, 2393, 100,0 },
+ {2145,2145, 35, 0, 1980, 813,0 },
+ { 376, 376, 35, 0, 1880, 840,0 },
+ { 895, 895, 35, 0, 366, 140,0 },
+ {2146,2146, 35, 0, 346, 106,0 },
+ { 382, 382, 35, 0, 1073, 113,0 },
+ {2147,2147, 35, 0, 106, 80,0 },
+ { 898, 898, 35, 0, 206, 153,0 },
+ { 899, 899, 35, 0, 633, 240,0 },
+ { 900, 900, 35, 0, 620, 240,0 },
+ { 871, 871, 35, 0, 380, 73,0 },
+ { 388, 388, 35, 0, 286, 80,0 },
+ { 901, 901, 35, 0, 260, 26,0 },
+ { 902, 902, 35, 0, 1093, 73,0 },
+ { 903, 903, 35, 0, 126, 73,0 },
+ {3500,3500, 35, 2, 6, 0,0 },
+ {4052,4052, 0, 0, 14166, 320,0 },
+ {4053,4053, 0, 0, 7413, 653,0 },
+ {4054,4054, 0, 0, 40000, 146,0 },
+ {4055,4055, 0, 0, 40000, 113,0 },
+ {4056,4056, 0, 0, 16773, 193,0 },
+ {4057,4057, 0, 0, 40000, 73,0 },
+ {4058,4058, 0, 0, 40000, 0,0 },
+ {4059,4059, 0, 0, 966, 373,0 },
+ {4060,4060, 0, 0, 40000, 80,0 },
+ {4061,4061, 0, 0, 40000, 80,0 },
+ {4062,4062, 0, 0, 18473, 93,0 },
+ {4063,4063, 0, 0, 40000, 60,0 },
+ {4064,4064, 0, 0, 40000, 73,0 },
+ {4065,4065, 0, 0, 40000, 0,0 },
+ {4066,4066, 0, 0, 40000, 213,0 },
+ {4067,4067, 0, 0, 40000, 66,0 },
+ {4068,4068, 0, 0, 1413, 1026,0 },
+ {4069,4069, 0, 0, 506, 200,0 },
+ {4070,4070, 0, 0, 3793, 1106,0 },
+ {4071,4071, 0, 0, 40000, 220,0 },
+ {4072,4072, 0, 0, 40000, 46,0 },
+ {4073,4073, 0, 0, 40000, 0,0 },
+ {4074,4074, 0, 0, 40000, 60,0 },
+ {4075,4075, 0, 0, 40000, 0,0 },
+ {4076,4076, 0, 0, 40000, 33,0 },
+ {4077,4077, 0, 0, 40000, 0,0 },
+ {4078,4078, 0, 0, 40000, 146,0 },
+ {4079,4079, 0, 0, 40000, 66,0 },
+ {4080,4080, 0, 0, 40000, 353,0 },
+ {4081,4081, 0, 0, 40000, 66,0 },
+ {4082,4082, 0, 0, 40000, 53,0 },
+ {4083,4083, 0, 0, 40000, 73,0 },
+ {4084,4084, 0, 0, 40000, 66,0 },
+ {4085,4085, 0, 0, 40000, 926,0 },
+ {4086,4086, 0, 0, 2833, 200,0 },
+ { 127, 127, 36, 0, 386, 166,0 },
+ {4087,4087, 36, 0, 100, 0,0 },
+ {2030,2030, 36, 0, 346, 140,0 },
+ {3782,3782, 48, 0, 93, 0,0 },
+ {3783,3783, 36, 0, 146, 0,0 },
+ {4088,4088, 48, 0, 1886, 653,0 },
+ { 132, 132, 69, 0, 126, 66,0 },
+ {4088,4088, 52, 0, 1853, 626,0 },
+ { 152, 152, 48, 0, 220, 86,0 },
+ {4088,4088, 55, 0, 1886, 640,0 },
+ { 139, 139, 57, 0, 293, 133,0 },
+ {4088,4088, 58, 0, 1860, 633,0 },
+ {4088,4088, 60, 0, 1886, 633,0 },
+ {4089,4089, 62, 0, 2660, 900,0 },
+ {4088,4088, 63, 0, 1880, 646,0 },
+ { 134, 134, 70, 0, 966, 360,0 },
+ {4090,4090, 70, 0, 973, 346,0 },
+ {4091,4091, 53, 0, 1866, 640,0 },
+ {3516,3516, 48, 0, 180, 93,0 },
+ {4092,4092, 84, 0, 1360, 473,0 },
+ {4093,4093, 43, 0, 513, 206,0 },
+ {4094,4094, 56, 0, 1353, 480,0 },
+ {3791,3791, 24, 0, 1866, 613,0 },
+ { 134, 134, 65, 0, 1346, 486,0 },
+ { 146, 146, 48, 0, 173, 93,0 },
+ { 146, 146, 54, 0, 173, 93,0 },
+ {4095,4095, 42, 0, 246, 140,0 },
+ {4095,4095, 39, 0, 240, 133,0 },
+ {3816,3816, 52, 0, 306, 113,0 },
+ {4096,4096, 52, 0, 413, 86,0 },
+ { 158, 158, 60, 0, 146, 166,0 },
+ { 158, 158, 66, 0, 146, 166,0 },
+ { 158, 158, 59, 0, 146, 166,0 },
+ {3538,3538, 91, 0, 773, 233,0 },
+ {3547,3547,109, 0, 5300, 1786,0 },
+ {4097,4097, 79, 0, 560, 313,0 },
+ {4098,4098, 0, 0, 10646, 73,0 },
+ {4099,4100, 0, 1, 14166, 586,0.03125 },
+ {4101,4102, 0, 1, 15553, 546,0.03125 },
+ {4103,4104, 0, 1, 11746, 320,0.046875 },
+ {4105,4106, 0, 1, 14706, 646,0.15625 },
+ {4107,4108, 0, 1, 7320, 100,0.046875 },
+ {4109,4110, 0, 1, 40000, 0,0.0625 },
+ {4111,4112, 0, 1, 13660, 260,0 },
+ {4113,4114, 0, 1, 15026, 133,0 },
+ {4115,4116, 0, 1, 40000, 0,2.5e-05 },
+ {4117,4118, 0, 1, 4980, 3400,0 },
+ {4119,4120, 0, 1, 7840, 2660,0.046875 },
+ {4121,4122, 0, 1, 8326, 180,0 },
+ {4123,4124, 0, 1, 1093, 140,0 },
+ {4125,4126, 0, 1, 2280, 400,0 },
+ {4127,4128, 0, 1, 4553, 1486,0.03125 },
+ {4129,4129, 0, 1, 40000, 0,0.03125 },
+ {4130,4131, 0, 1, 40000, 60,0.15625 },
+ {4132,4133, 0, 1, 40000, 93,0.078125 },
+ {4134,4135, 0, 1, 40000, 86,0.15625 },
+ {4136,4137, 0, 1, 40000, 520,0.03125 },
+ {4138,4139, 0, 1, 40000, 140,0.0625 },
+ {4140,4141, 0, 1, 40000, 133,0.140625 },
+ {4142,4143, 0, 1, 40000, 73,0 },
+ {4144,4145, 0, 1, 40000, 346,0.109375 },
+ {4146,4147, 0, 1, 3693, 86,0 },
+ {4148,4149, 0, 1, 6586, 460,2.5e-05 },
+ {4150,4151, 0, 1, 4320, 93,0 },
+ {4152,4153, 0, 1, 7346, 126,0.046875 },
+ {4154,4155, 0, 1, 3633, 260,0 },
+ {4156,4157, 0, 1, 40000, 126,-1.95312 },
+ {4158,4159, 0, 1, 40000, 126,-1.9375 },
+ {4160,4161, 0, 1, 40000, 46,0.234375 },
+ {4162,4163, 0, 1, 40000, 0,0.03125 },
+ {4164,4165, 0, 1, 10320, 86,0 },
+ {4166,4167, 0, 1, 12933, 133,0 },
+ {4168,4169, 0, 1, 11820, 240,0.046875 },
+ {4170,4171, 0, 1, 3966, 166,0 },
+ {4172,4173, 0, 1, 40000, 0,0 },
+ {4174,4174, 0, 0, 2666, 160,0 },
+ {4175,4176, 0, 1, 15046, 93,0.078125 },
+ {4177,4178, 0, 1, 40000, 100,0 },
+ {4179,4179, 0, 0, 40000, 260,0 },
+ {4180,4181, 0, 1, 40000, 126,2.5e-05 },
+ {4182,4182, 0, 0, 40000, 233,0 },
+ {4183,4184, 0, 1, 40000, 440,0.078125 },
+ {4185,4186, 0, 1, 2160, 606,0.109375 },
+ {4187,4188, 0, 1, 14753, 2400,0.03125 },
+ {4189,4190, 0, 1, 7693, 0,0.03125 },
+ {4191,4192, 0, 1, 40000, 446,0.0625 },
+ {4193,4194, 0, 1, 40000, 866,-0.0625 },
+ {4195,4195, 0, 1, 40000, 1226,0.109375 },
+ {4196,4196, 0, 1, 40000, 1960,0.109375 },
+ {4197,4198, 0, 1, 40000, 433,0.125 },
+ {4199,4200, 0, 1, 40000, 140,0.140625 },
+ {4201,4202, 0, 1, 40000, 706,0.15625 },
+ {4203,4204, 0, 1, 1640, 0,0.125 },
+ {4205,4206, 0, 1, 40000, 86,0 },
+ {4207,4208, 0, 1, 40000, 80,0.03125 },
+ {4209,4209, 0, 0, 40000, 73,0 },
+ {4210,4210, 0, 0, 40000, 126,0 },
+ {4211,4212, 0, 1, 40000, 353,0.03125 },
+ {4213,4214, 0, 1, 40000, 120,0.0625 },
+ {4215,4216, 0, 1, 40000, 0,0.09375 },
+ {4217,4217, 0, 1, 40000, 0,0.125 },
+ {4218,4219, 0, 1, 40000, 186,0 },
+ {4220,4220, 0, 0, 40000, 166,0 },
+ {4221,4221, 0, 0, 40000, 73,0 },
+ {4222,4222, 0, 0, 40000, 60,0 },
+ {4223,4224, 0, 1, 40000, 140,0 },
+ {4225,4225, 0, 0, 40000, 140,0 },
+ {4226,4226, 0, 0, 40000, 66,0 },
+ {4227,4228, 0, 1, 40000, 133,0 },
+ {4229,4229, 0, 0, 40000, 86,0 },
+ {4230,4230, 0, 0, 40000, 73,0 },
+ {4231,4231, 0, 0, 40000, 106,0 },
+ {4232,4233, 0, 1, 40000, 186,0.03125 },
+ {4234,4235, 0, 1, 40000, 86,0.046875 },
+ {4236,4237, 0, 1, 40000, 0,0.03125 },
+ {4238,4238, 0, 0, 40000, 300,0 },
+ {4239,4239, 0, 0, 40000, 66,0 },
+ {4240,4241, 0, 1, 40000, 73,0.125 },
+ {4242,4243, 0, 1, 40000, 86,0.109375 },
+ {4244,4245, 0, 1, 40000, 146,0.109375 },
+ {4246,4247, 0, 1, 40000, 66,-0.03125 },
+ {4248,4248, 0, 0, 40000, 60,0 },
+ {4249,4250, 0, 1, 40000, 213,0.15625 },
+ {4251,4252, 0, 1, 40000, 66,0.125 },
+ {4253,4254, 0, 1, 40000, 100,0.03125 },
+ {4255,4256, 0, 1, 40000, 1513,0.078125 },
+ {4257,4258, 0, 1, 40000, 353,0.109375 },
+ {4259,4260, 0, 1, 40000, 133,0.078125 },
+ {4261,4262, 0, 1, 40000, 746,0.140625 },
+ {4263,4264, 0, 1, 40000, 0,0.109375 },
+ {4265,4266, 0, 1, 5033, 1606,0.0625 },
+ {4267,4268, 0, 1, 40000, 1146,0.09375 },
+ {4269,4270, 0, 1, 40000, 1586,0.109375 },
+ {4271,4272, 0, 1, 40000, 0,0.09375 },
+ {4273,4274, 0, 1, 40000, 1006,0.125 },
+ {4275,4275, 0, 1, 2680, 793,0.109375 },
+ {4276,4277, 0, 1, 40000, 0,-0.046875 },
+ {4278,4279, 0, 1, 9000, 3186,0.125 },
+ {4280,4281, 0, 1, 40000, 1073,-0.078125 },
+ {4282,4283, 0, 1, 40000, 2093,0.140625 },
+ {4284,4285, 0, 1, 5640, 440,0.078125 },
+ {4286,4287, 0, 1, 9580, 713,0.03125 },
+ {4288,4289, 0, 1, 6286, 380,0 },
+ {4290,4291, 0, 1, 2220, 426,0.03125 },
+ {4292,4292, 0, 0, 1166, 760,0 },
+ {4293,4294, 0, 1, 1186, 240,0 },
+ {4295,4296, 0, 1, 40000, 100,0.0625 },
+ {4297,4297, 0, 0, 40000, 160,0 },
+ {4298,4298, 0, 0, 40000, 120,0 },
+ {4299,4299, 0, 0, 8673, 2413,0 },
+ {4300,4300, 0, 0, 393, 126,0 },
+ {4301,4302, 0, 1, 1220, 393,0.03125 },
+ {4303,4303, 0, 0, 246, 93,0 },
+ {4304,4305, 0, 1, 1953, 393,0 },
+ {4306,4307, 0, 1, 566, 146,0 },
+ {4308,4309, 0, 1, 4220, 133,0 },
+ {4310,4311, 0, 1, 2873, 73,0.109375 },
+ {4312,4312, 0, 0, 613, 60,0 },
+ {4313,4314, 0, 1, 40000, 186,0 },
+ {4315,4316, 0, 1, 11880, 2993,0 },
+ {4317,4317, 0, 0, 1573, 86,0 },
+ {4318,4319, 0, 1, 40000, 793,0 },
+ {4320,4321, 0, 1, 40000, 173,0 },
+ {4322,4323, 0, 1, 40000, 793,0 },
+ {4324,4324, 0, 0, 606, 133,0 },
+ {4325,4325, 34, 0, 133, 40,0 },
+ {4326,4326, 28, 0, 193, 46,0 },
+ {4327,4328, 39, 1, 553, 126,0 },
+ {4327,4328, 33, 1, 553, 126,0 },
+ {4329,4330, 63, 1, 160, 80,0 },
+ {4331,4331, 15, 0, 113, 0,0 },
+ {4332,4332, 36, 0, 106, 0,0 },
+ {4332,4333, 36, 1, 480, 173,0.40625 },
+ {4334,4335, 25, 1, 313, 153,0 },
+ {4336,4335, 25, 1, 206, 100,0 },
+ {4337,4338, 61, 1, 153, 93,0 },
+ {4339,4340, 37, 1, 206, 93,0 },
+ {4341,4342, 15, 1, 346, 153,0 },
+ {4343,4344, 48, 1, 280, 133,-1.90625 },
+ {4345,4346, 19, 1, 553, 200,0 },
+ {4347,4347, 48, 0, 180, 86,0 },
+ {4348,4349, 15, 1, 333, 153,0 },
+ {4350,4351, 12, 1, 340, 146,0 },
+ {4352,4353, 11, 1, 346, 146,0 },
+ {4354,4355, 61, 1, 2706, 1033,0.09375 },
+ {4356,4353, 8, 1, 340, 146,0 },
+ {4357,4358, 91, 1, 1166, 366,-0.046875 },
+ {4359,4359, 70, 0, 966, 346,0 },
+ {4360,4361, 80, 1, 300, 93,0.125 },
+ {4362,4362, 58, 0, 206, 53,0 },
+ {4363,4355, 62, 1, 2333, 820,0.09375 },
+ {4364,4365, 31, 1, 773, 200,0 },
+ {4366,4358, 91, 1, 1160, 360,-0.03125 },
+ {4367,4368, 41, 1, 373, 113,0 },
+ {4369,4370, 35, 1, 406, 126,0 },
+ {4371,4372, 29, 1, 146, 106,0 },
+ {4373,4374, 41, 1, 400, 126,0 },
+ {4373,4374, 37, 1, 400, 126,0 },
+ {4375,4376, 54, 1, 286, 133,0 },
+ {4375,4377, 48, 1, 286, 126,0 },
+ {4378,4379, 77, 1, 193, 93,0 },
+ {4380,4381, 72, 1, 200, 93,0 },
+ {4382,4382, 40, 0, 513, 0,0 },
+ {4383,4383, 38, 0, 200, 20,0 },
+ {4384,4384, 36, 0, 620, 20,0 },
+ {4385,4386, 60, 1, 120, 80,0 },
+ {4386,4387, 60, 1, 380, 80,0 },
+ {4388,4388, 73, 0, 166, 33,0 },
+ {4389,4390, 68, 1, 153, 40,0 },
+ {4391,4392, 18, 1, 200, 80,0 },
+ {4393,4394, 18, 1, 253, 73,0 },
+ {4395,4395, 90, 0, 193, 20,0 },
+ {4396,4396, 90, 0, 793, 40,0 },
+ {4397,4398, 64, 1, 373, 73,0.03125 },
+ {4399,4400, 80, 1, 406, 153,0.03125 },
+ {4401,4402, 64, 1, 1866, 606,0 },
+ {4403,4403, 67, 0, 106, 26,0 },
+ {4404,4405, 50, 1, 173, 0,0 },
+ {4406,4406, 36, 0, 4646, 0,0 },
+ {4407,4407, 0, 0, 40000, 86,0 },
+ {4408,4408, 0, 0, 40000, 73,0 },
+ {4409,4409, 0, 0, 2433, 700,0 },
+ {4410,4410, 0, 0, 1233, 26,0 },
+ {4411,4411, 0, 0, 40000, 66,0 },
+ {4412,4412, 0, 0, 40000, 60,0 },
+ {4413,4413, 0, 0, 40000, 60,0 },
+ {4414,4414, 0, 0, 40000, 66,0 },
+ {4415,4415, 0, 0, 40000, 66,0 },
+ {4416,4416, 0, 0, 40000, 0,0 },
+ {4416,4416, 73, 0, 40000, 0,0 },
+ {4417,4417, 0, 0, 40000, 60,0 },
+ {4418,4418, 0, 0, 40000, 60,0 },
+ {4419,4419, 0, 0, 7326, 2486,0 },
+ {4420,4420, 0, 0, 4886, 1586,0 },
+ {4421,4421, 0, 0, 646, 20,0 },
+ {4422,4422, 0, 0, 253, 20,0 },
+ {4422,4422, 12, 0, 253, 20,0 },
+ {4423,4423, 0, 0, 640, 100,0 },
+ {4423,4423, 1, 0, 640, 106,0 },
+ {4424,4424, 0, 0, 133, 106,0 },
+ {4424,4424, 23, 0, 133, 106,0 },
+ {4425,4425, 0, 0, 653, 100,0 },
+ {4426,4426, 0, 0, 4166, 1546,0 },
+ {4427,4427, 0, 0, 40000, 73,0 },
+ {4428,4428, 0, 0, 40000, 60,0 },
+ {4429,4429, 0, 0, 40000, 53,0 },
+ {4430,4430, 0, 0, 40000, 0,0 },
+ {4431,4431, 0, 0, 246, 20,0 },
+ {4432,4432, 0, 2, 6, 0,0 },
+ {4433,4433, 0, 0, 4946, 233,0 },
+ {4434,4434, 0, 0, 4946, 233,0 },
+ {4435,4435, 0, 0, 4953, 240,0 },
+ {4436,4436, 0, 0, 4946, 233,0 },
+ {4437,4437, 0, 0, 18233, 46,0 },
+ {4438,4438, 0, 0, 2386, 26,0 },
+ {4439,4439, 0, 0, 4640, 633,0 },
+ {4440,4440, 0, 0, 18466, 100,0 },
+ {4441,4441, 0, 0, 18440, 66,-2 },
+ {4442,4442, 0, 0, 18440, 6140,-2 },
+ {4443,4443, 0, 0, 1206, 433,-2 },
+ {4444,4444, 0, 0, 4626, 240,0 },
+ {4445,4445, 0, 0, 726, 400,0 },
+ {4446,4446, 0, 0, 5866, 73,0 },
+ {4447,4447, 0, 0, 40000, 73,0 },
+ {4448,4448, 0, 0, 40000, 73,0 },
+ {4449,4449, 0, 0, 40000, 73,0 },
+ {4450,4450, 0, 0, 40000, 73,0 },
+ {4451,4451, 0, 0, 6500, 346,0 },
+ {4452,4452, 0, 0, 6506, 346,0 },
+ {4453,4453, 0, 0, 40000, 66,-2 },
+ {4454,4454, 0, 0, 40000, 66,-2 },
+ {4455,4455, 0, 0, 40000, 0,0 },
+ {4456,4456, 0, 0, 40000, 46,0 },
+ {4457,4457, 0, 0, 40000, 0,0 },
+ {4457,4457, 0, 0, 40000, 0,-2 },
+ {4458,4458, 0, 0, 2386, 26,0 },
+ {4459,4459, 0, 0, 40000, 73,-2 },
+ {4460,4460, 0, 0, 5866, 26,-2 },
+ {4461,4461, 0, 0, 40000, 133,0 },
+ {4462,4462, 0, 0, 40000, 133,0 },
+ {4463,4463, 0, 0, 40000, 126,0 },
+ {4464,4464, 0, 0, 253, 20,0 },
+ {4465,4465, 0, 0, 8866, 1366,0 },
+ {4466,4466, 0, 0, 1040, 766,0 },
+ {4467,4467, 0, 0, 40000, 146,-2 },
+ {4468,4468, 0, 0, 40000, 153,-2 },
+ {4469,4469, 0, 0, 40000, 466,-2 },
+ {4470,4470, 0, 0, 40000, 66,0 },
+ {4471,4471, 0, 0, 2333, 566,0 },
+ {4472,4472, 0, 0, 40000, 140,-2 },
+ {4473,4473, 0, 0, 40000, 100,-2 },
+ {4474,4474, 0, 0, 40000, 226,-2 },
+ {4475,4475, 0, 0, 40000, 0,0 },
+ {3712,3712, 0, 0, 40000, 226,-2 },
+ {4476,4476, 0, 0, 40000, 140,-2 },
+ {4477,4477, 0, 0, 40000, 66,0 },
+ {4478,4478, 0, 0, 40000, 73,0 },
+ {4479,4479, 0, 0, 40000, 73,0 },
+ {4480,4480, 0, 0, 40000, 86,-2 },
+ {4481,4481, 0, 0, 40000, 80,0 },
+ {4482,4482, 0, 0, 40000, 73,-2 },
+ {4483,4483, 0, 0, 40000, 80,-2 },
+ {4484,4484, 0, 0, 40000, 73,-2 },
+ {4485,4485, 0, 0, 40000, 73,0 },
+ {4486,4486, 0, 0, 40000, 73,0 },
+ {4487,4487, 0, 0, 40000, 93,0 },
+ {4488,4488, 0, 0, 40000, 73,0 },
+ {4489,4489, 0, 0, 11946, 13,0 },
+ {4490,4490, 0, 0, 40000, 73,0 },
+ {4460,4460, 0, 0, 5866, 26,0 },
+ {4491,4491, 0, 0, 40000, 820,0 },
+ {4492,4492, 0, 0, 2153, 873,0 },
+ {1221,1221, 0, 0, 40000, 293,0.171875 },
+ {4493,4493, 0, 0, 1620, 120,0 },
+ {4494,4494, 0, 0, 15120, 93,0 },
+ {4495,4495, 0, 0, 14613, 93,0 },
+ {4496,4496, 0, 0, 2346, 793,0 },
+ {4497,4497, 0, 0, 40000, 2380,0 },
+ {4498,4498, 0, 0, 40000, 1280,0 },
+ {4499,4499, 0, 0, 40000, 1460,0 },
+ {4500,4500, 0, 0, 40000, 2513,0 },
+ {4501,4501, 0, 0, 14840, 1266,0 },
+ {4502,4502, 0, 0, 4513, 640,0 },
+ {4503,4503, 0, 0, 4680, 806,0 },
+ {4504,4504, 0, 0, 40000, 100,0 },
+ {4505,4505, 0, 0, 40000, 66,0 },
+ {4506,4506, 0, 0, 2420, 413,0 },
+ {4507,4507, 0, 0, 406, 73,-2 },
+ {4508,4508, 0, 0, 1166, 400,0 },
+ {4509,4509, 0, 0, 1213, 106,0 },
+ {4510,4510, 0, 0, 273, 60,-2 },
+ {4511,4511, 0, 0, 40000, 2380,0 },
+ {4512,4512, 0, 0, 40000, 440,0 },
+ {1261,1261, 0, 0, 40000, 2960,0 },
+ {4513,4513, 37, 0, 973, 73,-2 },
+ {4514,4514, 48, 0, 106, 0,-2 },
+ {4515,4515, 48, 0, 286, 133,-2 },
+ {4516,4516, 62, 0, 166, 60,0 },
+ {4517,4517, 44, 0, 980, 360,0 },
+ {4518,4518, 80, 0, 100, 0,0 },
+ {4517,4517, 50, 0, 980, 346,0 },
+ {4519,4519, 48, 0, 106, 0,-2 },
+ {4517,4517, 55, 0, 973, 360,0 },
+ {4520,4520, 61, 0, 513, 20,0 },
+ {4517,4517, 58, 0, 966, 353,0 },
+ {4517,4517, 63, 0, 973, 353,0 },
+ {4521,4521, 71, 0, 1366, 580,0 },
+ {4517,4517, 72, 0, 820, 306,0 },
+ {4522,4522, 70, 0, 1886, 666,0 },
+ {4521,4521, 88, 0, 1353, 560,0 },
+ {4523,4523, 76, 0, 1873, 653,0 },
+ {4524,4524, 84, 0, 260, 113,0 },
+ {4521,4521, 68, 0, 1366, 553,0 },
+ {4525,4525, 72, 0, 153, 53,0 },
+ {4526,4526, 28, 0, 1193, 413,0 },
+ {4522,4522, 81, 0, 1353, 480,0 },
+ {4527,4527, 58, 0, 246, 120,-2 },
+ {4527,4527, 55, 0, 246, 120,-2 },
+ {4527,4527, 44, 0, 246, 120,-2 },
+ {4527,4527, 49, 0, 246, 120,-2 },
+ {4527,4527, 40, 0, 286, 133,-2 },
+ {4528,4528, 55, 0, 740, 560,-2 },
+ {4528,4528, 48, 0, 893, 693,-2 },
+ {4529,4529, 52, 0, 513, 206,0 },
+ {4529,4529, 45, 0, 513, 206,0 },
+ {4530,4530, 48, 0, 173, 100,-2 },
+ {4531,4531, 48, 0, 120, 266,-2 },
+ {4532,4532, 48, 0, 253, 60,-2 },
+ {4507,4507, 73, 0, 160, 20,-2 },
+ {4507,4507, 68, 0, 160, 20,-2 },
+ {4507,4507, 63, 0, 193, 20,-2 },
+ {4533,4533,108, 0, 406, 26,0 },
+ {4534,4534,108, 0, 740, 26,0 },
};
@@ -9339,7 +9472,7 @@ const unsigned short banks[75][256] =
232, 233, 234, 235, 236, 237, 238, 239, 71, 72, 240, 241, 242, 243, 244, 245,
246, 247, 248, 82, 249, 250, 251, 86, 252, 253, 254, 255, 91, 92, 256, 257,
258, 259, 260, 98, 99, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271,
- 111, 272, 273, 274, 115, 275, 276, 277, 278, 120, 279, 280, 281, 282, 283, 284,
+ 111, 272, 273, 274, 115, 275, 276, 277, 278, 120, 279, 280, 281, 282, 295, 284,
127, 132, 285, 286, 127, 287, 288, 289, 290, 291, 292, 127, 127, 293, 294, 295,
289, 296, 297, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308,
309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 318, 320, 318, 321, 318,
@@ -9358,86 +9491,86 @@ const unsigned short banks[75][256] =
79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
- 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384,
- 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 385, 386, 387, 388, 389,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 385, 386, 387, 388, 389,
390, 391, 392, 369, 393, 308, 394, 395, 396, 397, 398, 399, 398, 400, 401, 402,
403, 404, 405, 406, 404, 406, 407, 404, 408, 404, 330, 409, 410, 411, 412, 413,
414, 415, 416, 417, 418, 419, 420, 341, 342, 421, 422, 423, 424, 425, 426, 427,
- 428, 429, 419, 430, 351, 431, 308, 432, 384, 384, 384, 384, 384, 384, 384, 384,
- 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384,
- 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384,
+ 428, 429, 419, 430, 351, 431, 308, 432, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
},
{
- 433, 434, 435, 28, 436, 31, 30, 437, 438, 439, 440, 441, 442, 38, 46, 443,
+ 295, 434, 435, 28, 436, 31, 30, 437, 438, 439, 440, 441, 442, 38, 46, 443,
79, 84, 444, 445, 49, 89, 92, 93, 105, 446, 447, 448, 449, 450, 451, 452,
453, 454, 455, 456, 119, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467,
- 468, 469, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 304, 470, 471, 472, 473,
+ 468, 469, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 304, 470, 471, 472, 473,
474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489,
490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505,
506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 345, 517, 518, 519, 520,
- 521, 522, 523, 524, 525, 526, 527, 528, 355, 356, 357, 358, 359, 529, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433,
+ 521, 522, 523, 524, 525, 526, 527, 528, 355, 356, 357, 358, 359, 529, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
},
{
- 433, 434, 435, 28, 436, 31, 30, 437, 438, 439, 440, 441, 442, 38, 46, 443,
+ 295, 434, 435, 28, 436, 31, 30, 437, 438, 439, 440, 441, 442, 38, 46, 443,
79, 84, 444, 445, 49, 89, 92, 93, 105, 446, 447, 448, 449, 450, 451, 452,
453, 454, 455, 456, 119, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467,
- 468, 433, 112, 99, 530, 531, 93, 532, 248, 107, 116, 533, 28, 78, 534, 535,
- 536, 79, 94, 38, 33, 115, 537, 538, 539, 540, 433, 433, 433, 433, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 433, 541, 542, 543, 544, 545, 546, 433, 295,
+ 468, 295, 112, 99, 530, 531, 93, 532, 248, 107, 116, 533, 28, 78, 534, 535,
+ 536, 79, 94, 38, 33, 115, 537, 538, 539, 540, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 541, 542, 543, 544, 545, 546, 295, 295,
547, 132, 134, 136, 138, 139, 141, 173, 156, 291, 292, 127, 548, 549, 550, 551,
- 552, 362, 553, 143, 433, 433, 433, 433, 433, 433, 433, 304, 470, 471, 472, 473,
+ 552, 362, 553, 143, 295, 295, 295, 295, 295, 295, 295, 304, 470, 471, 472, 473,
474, 475, 476, 477, 478, 479, 480, 481, 482, 554, 555, 556, 557, 487, 488, 489,
490, 491, 492, 493, 558, 495, 496, 497, 498, 499, 500, 501, 559, 503, 504, 505,
506, 507, 508, 560, 561, 511, 512, 513, 514, 562, 563, 345, 517, 518, 519, 520,
- 521, 522, 523, 524, 525, 526, 527, 528, 564, 356, 565, 358, 359, 433, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 295,
+ 521, 522, 523, 524, 525, 526, 527, 528, 564, 356, 565, 358, 359, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
},
{
- 433, 434, 435, 28, 436, 31, 30, 437, 438, 439, 440, 441, 442, 38, 46, 443,
+ 295, 434, 435, 28, 436, 31, 30, 437, 438, 439, 440, 441, 442, 38, 46, 443,
79, 84, 444, 445, 49, 89, 92, 93, 105, 446, 447, 448, 449, 450, 451, 452,
453, 454, 455, 456, 119, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467,
- 468, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 566, 567, 568, 569,
+ 468, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 566, 567, 568, 569,
570, 34, 571, 572, 437, 51, 52, 84, 573, 574, 575, 576, 577, 85, 530, 90,
- 93, 94, 101, 578, 114, 119, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 293, 127, 548,
+ 93, 94, 101, 578, 114, 119, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 293, 127, 548,
550, 296, 297, 296, 297, 298, 299, 300, 301, 302, 303, 304, 470, 471, 472, 473,
474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489,
490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505,
506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 345, 517, 518, 519, 520,
521, 522, 523, 524, 525, 526, 527, 528, 355, 356, 357, 358, 359, 360, 361, 362,
- 164, 363, 156, 364, 292, 365, 366, 367, 368, 178, 433, 433, 433, 433, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433,
+ 164, 363, 156, 364, 292, 365, 366, 367, 368, 178, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
},
{
- 433, 434, 435, 28, 436, 31, 30, 437, 438, 439, 440, 441, 442, 38, 46, 443,
+ 295, 434, 435, 28, 436, 31, 30, 437, 438, 439, 440, 441, 442, 38, 46, 443,
79, 84, 444, 445, 49, 89, 92, 93, 105, 446, 447, 448, 449, 450, 451, 452,
453, 454, 455, 456, 119, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467,
- 468, 433, 579, 580, 581, 433, 433, 582, 433, 433, 433, 433, 583, 584, 585, 586,
- 587, 444, 588, 589, 590, 433, 591, 592, 433, 433, 433, 433, 433, 433, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 577, 566,
+ 468, 295, 579, 580, 581, 295, 295, 582, 295, 295, 295, 295, 583, 584, 585, 586,
+ 587, 444, 588, 589, 590, 295, 591, 592, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 577, 566,
437, 90, 460, 28, 593, 594, 595, 596, 31, 597, 598, 28, 441, 442, 567, 530,
- 93, 572, 599, 279, 30, 435, 100, 94, 575, 38, 281, 437, 447, 51, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 356, 357, 358, 359, 304, 470, 471, 472, 473,
+ 93, 572, 599, 279, 30, 435, 100, 94, 575, 38, 281, 437, 447, 51, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 356, 357, 358, 359, 304, 470, 471, 472, 473,
474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489,
490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505,
506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 345, 517, 518, 519, 520,
521, 522, 523, 524, 525, 526, 527, 528, 355, 600, 601, 602, 127, 548, 296, 603,
604, 550, 605, 606, 362, 607, 135, 608, 361, 609, 610, 611, 612, 507, 146, 613,
- 547, 500, 614, 364, 173, 615, 366, 600, 616, 617, 618, 619, 620, 621, 433, 433,
+ 547, 500, 614, 364, 173, 615, 366, 600, 616, 617, 618, 619, 620, 621, 295, 295,
},
{
622, 179, 371, 180, 372, 373, 374, 375, 376, 377, 186, 378, 187, 379, 380, 190,
@@ -9465,15 +9598,15 @@ const unsigned short banks[75][256] =
659, 599, 660, 661, 662, 68, 663, 664, 71, 665, 666, 74, 75, 667, 668, 669,
577, 85, 441, 442, 38, 84, 46, 86, 530, 88, 670, 90, 91, 92, 93, 94,
258, 671, 97, 532, 99, 100, 101, 672, 536, 673, 674, 675, 676, 677, 464, 110,
- 678, 578, 113, 114, 679, 116, 680, 599, 31, 462, 279, 125, 465, 281, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433,
- 433, 433, 433, 681, 682, 683, 500, 503, 614, 684, 685, 296, 552, 550, 605, 600,
+ 678, 578, 113, 114, 679, 116, 680, 599, 31, 462, 279, 125, 465, 281, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 681, 682, 683, 500, 503, 614, 684, 685, 296, 552, 550, 605, 600,
548, 602, 127, 601, 293, 549, 604, 551, 603, 298, 362, 299, 135, 300, 361, 301,
302, 547, 303, 142, 143, 144, 619, 146, 291, 686, 149, 687, 367, 368, 292, 365,
366, 364, 688, 158, 689, 690, 615, 162, 163, 164, 363, 691, 167, 168, 169, 170,
171, 172, 173, 174, 175, 176, 177, 178, 692, 693, 694, 695, 696, 697, 698, 699,
- 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 433, 433, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433,
+ 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
},
{
712, 713, 714, 715, 716, 713, 717, 718, 719, 720, 721, 722, 723, 724, 715, 725,
@@ -9484,14 +9617,14 @@ const unsigned short banks[75][256] =
769, 770, 771, 664, 772, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782,
783, 784, 785, 786, 787, 788, 788, 789, 786, 753, 790, 780, 780, 780, 791, 791,
792, 793, 794, 795, 796, 680, 680, 797, 798, 799, 800, 801, 802, 803, 742, 804,
- 805, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806,
- 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806,
- 806, 806, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819,
+ 805, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819,
820, 821, 822, 823, 821, 824, 825, 821, 826, 821, 827, 828, 829, 830, 831, 832,
- 833, 834, 834, 835, 835, 825, 825, 836, 837, 838, 806, 839, 840, 841, 806, 806,
- 842, 843, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806,
- 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806,
- 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806,
+ 833, 834, 834, 835, 835, 825, 825, 836, 837, 838, 295, 839, 840, 841, 295, 295,
+ 842, 843, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
},
{
844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859,
@@ -9502,14 +9635,14 @@ const unsigned short banks[75][256] =
924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939,
940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955,
956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 295,
- 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384,
- 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 971, 972, 973, 974,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 971, 972, 973, 974,
975, 310, 976, 977, 978, 974, 979, 980, 981, 982, 983, 984, 983, 985, 986, 987,
988, 989, 990, 325, 989, 325, 991, 989, 992, 989, 330, 993, 994, 995, 996, 997,
998, 999,1000,1001,1002,1003, 340,1004,1005,1006,1007,1008,1009, 310,1010,1011,
-1012, 429,1003, 430,1013,1014, 974,1015, 384, 384, 384, 384, 384, 384, 384, 384,
- 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384,
- 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 295,
+1012, 429,1003, 430,1013,1014, 974,1015, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
},
{
1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,
@@ -9520,14 +9653,14 @@ const unsigned short banks[75][256] =
1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,
1111,1112,1113,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126,
1127,1128,1129,1130,1131,1132,1133,1134,1135,1136,1137,1138,1139,1140,1141,1142,
- 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384,
- 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 305, 306, 307, 308,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 305, 306, 307, 308,
1143, 425, 311,1144, 393, 308, 394, 395, 396, 397,1145, 399,1145, 400,1146, 402,
403, 404, 405, 406, 404, 406, 407, 404, 408, 404, 330, 409, 410, 411, 412, 413,
414, 415, 416, 417, 418, 419, 420, 341, 342, 421, 422, 423, 424, 425, 426, 427,
- 428, 429, 419, 430, 351, 431, 308, 432, 384, 384, 384, 384, 384, 384, 384, 384,
- 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384,
- 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384,
+ 428, 429, 419, 430, 351, 431, 308, 432, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
},
{
1147,1017,1018,1148,1149,1150,1022, 184,1024,1025,1026,1027,1028,1151,1152,1153,
@@ -9538,14 +9671,14 @@ const unsigned short banks[75][256] =
1188,1189,1097,1098,1190,1100,1191,1192,1103,1193,1194,1195,1196,1197,1198,1199,
1111,1200,1201,1202,1203,1116,1204,1205,1119,1206,1207,1122,1123,1124,1125,1208,
1127,1209,1210,1130,1131,1211,1212,1213,1135,1214,1215,1138,1139,1216,1217,1218,
- 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384,
- 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 385, 386, 387, 388, 389,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 385, 386, 387, 388, 389,
390, 391, 392,1219,1219, 308, 394, 395, 396, 397, 398, 399, 398, 400, 401, 402,
403, 404, 405, 406, 404, 406, 407, 404, 408, 404, 330, 409, 410, 411, 412, 413,
414, 415, 416,1220,1221, 419, 420, 341, 342, 421, 422, 423, 424, 425, 426, 427,
- 428, 429, 419, 430, 351, 431, 308, 432, 384, 384, 384, 384, 384, 384, 384, 384,
- 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384,
- 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384,
+ 428, 429, 419, 430, 351, 431, 308, 432, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
},
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
@@ -9578,7 +9711,7 @@ const unsigned short banks[75][256] =
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 312,1349,1350,1351,1352,1353,1354, 319,1355, 320,1356, 321,1357,
1358,1359,1360,1361,1362,1363,1364,1365,1366,1359,1367,1361, 332, 333, 334, 335,
- 336,1368,1369, 338, 339, 320,1370,1371,1371,1371,1371,1372,1373,1374,1375,1371,
+ 336,1368,1369, 338, 339, 320,1370, 295, 295, 295, 295,1372,1373,1374,1375, 295,
347, 348, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
@@ -9596,7 +9729,7 @@ const unsigned short banks[75][256] =
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 312,1349,1350,1351,1352,1382,1354, 319,1355, 320,1356, 321,1357,
1358,1359,1360,1361,1362,1363,1364,1383,1366,1359,1384,1361, 332, 333, 334, 335,
- 336,1368,1369, 338, 339, 320,1370,1371,1371,1371,1371,1372,1373,1374,1375,1371,
+ 336,1368,1369, 338, 339, 320,1370, 295, 295, 295, 295,1372,1373,1374,1375, 295,
347, 348, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
@@ -9614,7 +9747,7 @@ const unsigned short banks[75][256] =
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 312,1349,1350,1351,1352,1353,1354, 319,1355, 320,1356, 321,1357,
1358,1359,1360,1361,1362,1363,1364,1383,1366,1359,1387,1361, 332, 333, 334, 335,
- 336,1368,1369, 338, 339, 320,1370,1371,1371,1371,1371,1372,1373,1374,1375,1371,
+ 336,1368,1369, 338, 339, 320,1370, 295, 295, 295, 295,1372,1373,1374,1375, 295,
347, 348, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
@@ -9681,7 +9814,7 @@ const unsigned short banks[75][256] =
232, 233, 234, 235,1583, 237, 238, 239,1584,1585, 240,1586, 242, 243, 244,1587,
246, 247,1588,1589, 249, 250, 251,1590, 252, 253, 254, 255,1591,1592,1593,1594,
1595, 259,1596,1597,1598,1599,1600,1601, 264, 265, 266, 267, 268, 269, 270, 271,
-1602, 272, 273,1603,1604,1605, 276,1606,1607,1608,1609,1610,1611,1612, 283, 284,
+1602, 272, 273,1603,1604,1605, 276,1606,1607, 295, 295,1610,1611,1612, 295, 284,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 127, 127,1613,1614,1615,1616,1617,1618,1619,1620,1621,1622,1623,
@@ -9790,14 +9923,14 @@ const unsigned short banks[75][256] =
2059,2060,2061,2062,2063,2064,2065,2066,2067,2068,2069,2070,2071,2071,2072,2073,
2074,2075,2076,2077,2078,2079,2080, 275,2081,2082,1527,2083,2084,2085,2086,2087,
2088,2089,2090,2091,2092,2093,2094,2095,2096,2097,2098,2099, 122,2100,2101,2102,
-2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,
-2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,
-2103,2103,2103,2104,2105,2106,2107,2108,2109,2110,2111,2110,2112,2113,2114,2113,
-2115, 547,2115,2116,2103,2103,2117,2103,2118,2103,2103,2103,2119,2120,2121,2122,
-2123,2124,2125,2126,2127, 160, 161, 162, 163,2128,2103,2129,2103,2103,2103,2103,
-2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,
-2103,2103,2103,2103, 295,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,
-2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295,2104,2105,2106,2107,2108,2109,2110,2111,2110,2112,2113,2114,2113,
+2115, 547,2115,2116, 295, 295,2117, 295,2118, 295, 295, 295,2119,2120,2121,2122,
+2123,2124,2125,2126,2127, 160, 161, 162, 163,2128, 295,2129, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
},
{
2130,2130,2130,2130,2130,2130, 727,2131,2132,2133,2134,2135,2136,2137,2138,2139,
@@ -9879,7 +10012,7 @@ const unsigned short banks[75][256] =
232, 233, 234, 235,2281, 237, 238, 239,1584,1585,2282,1586, 242, 243, 244,1587,
246, 247,1588,1589, 249, 250, 251,1590,2283, 253, 254, 255,1591,1592,1593,1594,
1595, 259,1596,1597,1598,1599,1600,1601, 264, 265, 266, 267, 268, 269, 270, 271,
-1602, 272, 273,1603,1604,1605, 276,1606,1607,1608,1609,1610,1611,1612, 283, 284,
+1602, 272, 273,1603,1604,1605, 276,1606,1607, 295, 295,1610,1611,1612, 295, 284,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,2284,
295, 295, 295,2284,2285,2286,1614,1615,2287,2288,1618,1619,1620,1621,1622,1623,
@@ -9969,7 +10102,7 @@ const unsigned short banks[75][256] =
232, 233, 234, 235,1583, 237, 238, 239,1584,1585, 240,1586, 242, 243, 244,1587,
246, 247,1588,1589, 249, 250, 251,1590, 252, 253, 254, 255,1591,1592,1593,1594,
1595, 259,1596,1597,1598,1599,1600,1601, 264, 265, 266, 267, 268, 269, 270, 271,
-1602, 272, 273,1603,1604,1605, 276,1606,1607,1608,1609,1610,1611,1612, 283, 284,
+1602, 272, 273,1603,1604,1605, 276,1606,1607, 295, 295,1610,1611,1612, 295, 284,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295,2430,2430,2431,2432,2433,2434,2435,2436,2437,2436,2438,2436,2439,
@@ -10005,7 +10138,7 @@ const unsigned short banks[75][256] =
232, 233, 234, 235,1583, 237, 238, 239,1584,1585, 240,1586, 242, 243, 244,1587,
246, 247,1588,1589, 249, 250, 251,1590, 252, 253, 254, 255,1591,1592,1593,1594,
1595, 259,1596,1597,1598,1599,1600,1601, 264, 265, 266, 267, 268, 269, 270, 271,
-1602, 272, 273,1603,1604,1605, 276,1606,1607,1608,1609,1610,1611,1612, 283, 284,
+1602, 272, 273,1603,1604,1605, 276,1606,1607, 295, 295,1610,1611,1612, 295, 284,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 127, 127,2286,1614,1615,1616,2288,1618,1619,1620,1621,1622,1623,
@@ -10045,7 +10178,7 @@ const unsigned short banks[75][256] =
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,2493,
295,2555, 295,2556,2495,2557,2558,2559,2496,2497,2560,2498,2561,2499,2562,2500,
-2563,2564,2565,2527, 295, 295,2566, 295,2567, 295, 295, 295,2570,2571, 295,2572,
+2563,2564,2565,2527, 295, 295,2566, 295, 295, 295, 295, 295,2570,2571, 295,2572,
2573, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
@@ -10131,7 +10264,7 @@ const unsigned short banks[75][256] =
232, 233, 234, 235,1583, 237, 238, 239,1584,1585, 240,2873, 242, 243, 244,2874,
246, 247,1588,1589, 249,2875,2876,2877,2878, 253, 254, 255,1591,1592,1593,2879,
1595, 259,1596,2880,1598,1599,1600,1601, 264, 265, 266,2881, 268, 108, 270,2859,
-2882,2883, 273,1603,1604,1605, 276,2884,2885,2886,1609,1610,2887,1612,2888, 284,
+2882,2883, 273,1603,1604,1605, 276,2884,2885,2886, 295,1610,2887,1612,2888, 284,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295,2889,2889, 128, 129, 130,2890, 132,2891, 134, 135, 136, 137, 138,
@@ -10168,14 +10301,14 @@ const unsigned short banks[75][256] =
2968,2969,2554,2970,2489,2971,2972,2973, 657, 575,2974,2975,2976, 779,2977,2978,
2979,2980,2981,2982,2983,2984,2985,2986,2987,2988,2553,2989,2990,2991,2992,2993,
2994,2995, 680, 796,2996, 797,2662,2997,2998,2999,2514,3000,3001,1913,3002,3003,
- 295, 295, 295, 295, 295, 295, 295, 295, 295, 384, 295, 295, 295, 295, 295, 295,
- 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,3004, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295,1219,1219, 308, 394, 395, 396, 397, 398, 399, 398, 400, 401, 402,
403, 404, 405, 406, 404, 406, 407, 404, 408, 404, 330, 409, 410, 411, 412, 413,
414, 415, 416,1220,1221, 419, 420, 341, 342, 421, 422, 423, 424, 425, 426, 427,
- 428, 429, 419, 430, 351, 431, 308, 432, 384, 384, 384, 384, 384, 384, 384, 384,
- 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384,
- 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384,
+ 428, 429, 419, 430, 351, 431, 308, 432, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
},
{
2501,2502,2503,2504,2505,2506,2507, 730,2508,2509,2510,2511,2512,2513,2514,2515,
@@ -10189,7 +10322,7 @@ const unsigned short banks[75][256] =
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,2493,
295,2555, 295,2556,2495,2557,2558,2559,2496,2497,2560,2498,2561,2499,2562,2500,
-2563,3011,2565,2527, 295, 295,2566, 295,2567, 295, 295, 295,3012,3013,3014,3015,
+2563,3011,2565,2527, 295, 295,2566, 295, 295, 295, 295, 295,3012,3013,3014,3015,
3016,3015,3016, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
@@ -10240,14 +10373,14 @@ const unsigned short banks[75][256] =
2059,2060,2061,2062,2063,2064,2065,2066,3089,2068,2069,2070,3090,3091,2072,2073,
2074,2075,2076,2077,2078,2079,2080, 275,2081,2082,1527,2083,2084,2085,2086,2087,
2088,2089,2090,2091,2092,2093,2094,2095,2096,2097,2098,2099, 122,2100,2101,2102,
-2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,
-2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,
-2103,2103,2103,2104,2105,2106,2107,2108,2109,2110,2111,2110,2112,2113,2114,2113,
-2115, 547,2115,2116,2103,2103,2117,2103,2118,2103,2103,2103,2119,2120,2121,2122,
-2123,2124,2125,2126,2127, 160, 161, 162, 163,2128,2103,2129,2103,2103,2103,2103,
-2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,
-2103,2103,2103,2103, 295,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,
-2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,2103,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295,2104,2105,2106,2107,2108,2109,2110,2111,2110,2112,2113,2114,2113,
+2115, 547,2115,2116, 295, 295,2117, 295,2118, 295, 295, 295,2119,2120,2121,2122,
+2123,2124,2125,2126,2127, 160, 161, 162, 163,2128, 295,2129, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
},
{
2501,2502,2503,2504,2505,2506,2507, 730,2508,2509,2510,2511,2512,2513,2514,2515,
@@ -10261,75 +10394,75 @@ const unsigned short banks[75][256] =
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,2493,
295,2555, 295,3092,2495,2557,2558,2559,2496,2497,2562,2498,2561,2499,2562,2500,
-2563,3011,2565,2527, 295, 295,2566, 295,2567, 295, 295, 295,2570,2571, 295,2572,
+2563,3011,2565,2527, 295, 295,2566, 295, 295, 295, 295, 295,2570,2571, 295,2572,
3093, 295, 295, 295, 295, 295,3094, 295, 295,3095,3096, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295,3097, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
},
{
-1551,1552,1553,3101, 181, 182, 183,3102, 185,1556,1557,3103,1559, 188, 189,1560,
-1561,1562, 193,1564,1565, 195, 196, 197, 198, 199, 200, 201, 202,1566,1567, 205,
- 206, 207, 208,1568,1569,1570,1571, 211,1572,1573, 214, 215, 216, 217, 218, 219,
- 220, 221,1574,1575,1576,1577,1578, 225,1579,1580,3100,1581,1582, 229, 230, 231,
- 232, 233, 234, 235,1583, 237, 238, 239,1584,1585, 240,1586, 242, 243, 244,1587,
- 246, 247,1588,1589, 249, 250, 251,1590, 252, 253, 254, 255,1591,1592,1593,1594,
-1595, 259,1596,1597,1598,1599,1600,1601, 264, 265, 266, 267, 268, 269, 270, 271,
-1602, 272, 273,1603,1604,1605, 276,1606,1607,1608,1609,1610,3104,3105, 283, 284,
+3098,3205,3101,3129,3130,3131,3108,3132,3209,3210,3120,3133,3124,3134,3103,3135,
+3136,3137,3113,3138,3139,3140,3141,3142,3143,3144,3145,3206,3121,3207,3208,3146,
+3127,3147,3148,3211,3212,3149,3150,3151,3116,3106,3152,3110,3111,3213,3104,3126,
+3105,3117,3153,3154,3102,3214,3155,3119,3215,3216,3115,3109,3217,3114,3112,3218,
+3156,3219,3157,3158,3159,3107,3122,3128,3160,3222,3161,3162,3163,3164,3165,3166,
+3167,3168,3169,3170,3171,3172,3173,3174,3223,3175,3176,3177,3118,3221,3220,3178,
+3226,3241,3179,3180,3242,3181,3182,3183,3184,3185,3186,3187,3125,3188,3189,3190,
+3191,3192,3193,3194,3123,3195,3196,3197,3198,3224,3199,3200,3201,3202,3203,3204,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
- 295, 295, 295, 127,3107,3122,3126, 316,3123,3121,3124,3107,3125,3107,3127,3107,
-3107, 329,3107,3108,3143,3109,3128,3129,3099,3144,1634,3110,3130,3131,3117,3119,
-3136,3132,3133,3134,3137,3115,3138,3135,3098, 343, 344,3112,3113,3113,3142,3139,
-3140,3141,3116,3106,3111,3114,3118,3120, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 127,3227,3244,3248,3268,3245,3243,3246,3227,3247,3227,3249,3227,
+3227,3269,3227,3228,3270,3229,3250,3251,3100,3271,3258,3230,3252,3253,3237,3239,
+3259,3254,3255,3256,3260,3235,3261,3257,3099,3265,3266,3232,3233,3233,3267,3262,
+3263,3264,3236,3225,3231,3234,3238,3240, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
},
{
-1551,1552,1553,3101, 181, 182, 183,3102, 185,1556,1557,3103,1559, 188, 189,1560,
-1561,1562, 193,1564,1565, 195, 196, 197, 198, 199, 200, 201, 202,1566,1567, 205,
- 206, 207, 208,1568,1569,1570,1571, 211,1572,1573, 214, 215, 216, 217, 218, 219,
- 220, 221,1574,1575,1576,1577,1578, 225,1579,1580,3100,1581,1582, 229, 230, 231,
- 232, 233, 234, 235,1583, 237, 238, 239,1584,1585, 240,1586, 242, 243, 244,1587,
- 246, 247,1588,1589, 249, 250, 251,1590, 252, 253, 254, 255,1591,1592,1593,1594,
-1595, 259,1596,1597,1598,1599,1600,1601, 264, 265, 266, 267, 268, 269, 270, 271,
-1602, 272, 273,1603,1604,1605, 276,1606,1607,1608,1609,1610,3104,3105, 283, 284,
+3098,3205,3101,3129,3130,3131,3108,3132,3209,3210,3120,3133,3124,3134,3103,3135,
+3136,3137,3113,3138,3139,3140,3141,3142,3143,3144,3145,3206,3121,3207,3208,3146,
+3127,3147,3148,3211,3212,3149,3150,3151,3116,3106,3152,3110,3111,3213,3104,3126,
+3105,3117,3153,3154,3102,3214,3155,3119,3215,3216,3115,3109,3217,3114,3112,3218,
+3156,3219,3157,3158,3159,3107,3122,3128,3160,3222,3161,3162,3163,3164,3165,3166,
+3167,3168,3169,3170,3171,3172,3173,3174,3223,3175,3176,3177,3118,3221,3220,3178,
+3226,3241,3179,3180,3242,3181,3182,3183,3184,3185,3186,3187,3125,3188,3189,3190,
+3191,3192,3193,3194,3123,3195,3196,3197,3198,3224,3199,3200,3201,3202,3203,3204,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
- 295, 295, 295,2430,2430,3149,3147,3148,3147,3145,3145,3145,3145,3145,3145,3145,
-3145,3145,3145,3145,3145,3145,3150,3151,3173, 329,3152, 329,3153,3154,3155,3156,
-3157,3158,3159,3160,3161, 349,3162,3163,3164,3165,3166,3148,3148,3148,3167,3168,
-3169,3170, 349,3171,3172,3148,3155,3156,3146, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295,3274,3274,3277,3275,3276,3275,3272,3272,3272,3272,3272,3272,3272,
+3272,3272,3272,3272,3272,3272,3278,3279,3301,3269,3280,3269,3281,3282,3283,3284,
+3285,3286,3287,3288,3289, 349,3290,3291,3292,3293,3294,3276,3276,3276,3295,3296,
+3297,3298, 349,3299,3300,3276,3283,3284,3273, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
},
{
-3174,3175,3176,3177,3178,3179,3180,3181,3182,3183,3184,3185,3186,3187,3188,3189,
-3190,3191,3192,3193,3194,3195,3196,3196,3197,3198,3199,3200,3201,3202,3203,3204,
-3205,3206,3207,3208,3209,3210,3211,3212,3213,3214,3215,3216,3217,3218,3219,3220,
-3221,3222,3223,3224,3225,3226,3227,3228,3229,3230,3231,3196,3232,3233,3234,3235,
-3196,3236,3237,3238,3196,3239,3196,3240,3196,3241,3196,3242,3196,3243,3244,3245,
-3246,3247,3248,3196,3249,3250,3196,3251,3252,3253,3254,3255,3196,3196,3256,3196,
-3257,3196,3258,3196,3259,3260,3196,3261,3196,3196,3262,3196,3196,3196,3196,3196,
-3196,3196,3196,3263,3196,3196,3196,3196,3196,3196,3264,3265,3196,3196,3196,3196,
-3266,3267, 285,3268,3269, 287, 288,3270,3271,3271,3271,3271,3271,3271,3271,3271,
-3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,
-3271,3271,3271,3272,3273,3271,3274,3271,3275,3276,3277,3278,3279,3280,3281,3282,
-3282,3283,3280,3284,3271,3271,3285,3286,3271,3271,3271,3271,3271,3271,3271,3271,
-3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,
-3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,
-3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,
-3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,3271,
+3302,3303,3304,3305,3306,3307,3308,3309,3310,3311,3312,3313,3314,3315,3316,3317,
+3318,3319,3320,3321,3322,3323,3324,3324,3325,3326,3327,3328,3329,3330,3331,3332,
+3333,3334,3335,3336,3337,3338,3339,3340,3341,3342,3343,3344,3345,3346,3347,3348,
+3349,3350,3351,3352,3353,3354,3355,3356,3357,3358,3359,3324,3360,3361,3362,3363,
+3324,3364,3365,3366,3324,3367,3324,3368,3324,3369,3324,3370,3324,3371,3372,3373,
+3374,3375,3376,3324,3377,3378,3324,3379,3380,3381,3382,3383,3324,3324,3384,3324,
+3385,3324,3386,3324,3387,3388,3324,3389,3324,3324,3390,3324,3324,3324,3324,3324,
+3324,3324,3324,3391,3324,3324,3324,3324,3324,3324,3392,3393,3324,3324,3324,3324,
+3394,3395, 285,3396,3397, 287, 288,3398,3399,3399,3399,3399,3399,3399,3399,3399,
+3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,
+3399,3399,3399,3400,3401,3399,3402,3399,3403,3404,3405,3406,3407,3408,3409,3410,
+3410,3411,3408,3412,3399,3399,3413,3414,3399,3399,3399,3399,3399,3399,3399,3399,
+3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,
+3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,
+3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,
+3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,3399,
},
{
-3287,3288, 466,3289, 713,3196,3290, 467,3291, 632,3292,3293,3294,3295,3296,3297,
-3298, 598,3299,3300,3301,3302,3303,3304,1512,3305,3294,3306, 759, 437, 437,3307,
-3308,3309, 439,3310, 440,3311, 442, 441,3312,3313,3314,3315,2306,3316,3317, 582,
-3318,3319, 452,3320,3321,3290,3322,3323,3324, 778,3325,2312, 779,3326,3327,3328,
-3329, 769,3330,3331,3332,3333, 663, 664,3334,2316,3335,3336,3337,1299,3338,3339,
-3340,3341,3342,3343,3344,3345,3346, 442,3347,3348,3349,3304,3350,1669,3351,3352,
-3353,3354,3355,3356,3353, 261,3357,3358,1919,2420,3359,3360, 676,3361,3362,3363,
-3364,3365,3366,3367, 677,3368, 677,3369,3370, 677,3371, 455,3372,2421,3373, 465,
+3415,3416, 466,3417, 713,3324,3418, 467,3419, 632,3420,3421,3422,3423,3424,3425,
+3426, 598,3427,3428,3429,3430,3431,3432,1512,3433,3422,3434, 759, 437, 437,3435,
+3436,3437, 439,3438, 440,3439, 442, 441,3440,3441,3442,3443,2306,3444,3445, 582,
+3446,3447, 452,3448,3449,3418,3450,3451,3452, 778,3453,2312, 779,3454,3455,3456,
+3457, 769,3458,3459,3460,3461, 663, 664,3462,2316,3463,3464,3465,1299,3466,3467,
+3468,3469,3470,3471,3472,3473,3474, 442,3475,3476,3477,3432,3478,1669,3479,3480,
+3481,3482,3483,3484,3481, 261,3485,3486,1919,2420,3487,3488, 676,3489,3490,3491,
+3492,3493,3494,3495, 677,3496, 677,3497,3498, 677,3499, 455,3500,2421,3501, 465,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
@@ -10340,14 +10473,14 @@ const unsigned short banks[75][256] =
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
},
{
-3374,3374,3375,3376,3377,3378,3378,3379,3380,3381,3382,3383,3384,3385,3386,3387,
-3388,3389,3390,3391,3392,3393,3394,3395,3396,3397,3398,3399,3400,3401,3402,3403,
-3404,3405,3406,3407,3408,3409,3410,3411,3412,3413,3414,3415,3416,3417,3418,3419,
-3420,3421,3422,3423,3424,3425,3426,3427,3425,3428,3429,3430,3431,3432,3433,3434,
-3435,3436,3437,3438,3439,3440,3441,3442,3443,3444,3445,3446,3335,3447,3448,3449,
-3450,3451,3452,3453,3454,3455,3456,3457,3458,3459,3460,3461,3462,3462,3463,3464,
-3465,3466,3467,3468,3469,3470,3471,3472,3473,3474,3475,3476,3477,3478,3479,3480,
-3481,3482,3481,3483,3484,3485,3486,3487,3488,3489,3490,3491,3492,3493,3494,3495,
+3502,3502,3503,3504,3505,3506,3506,3507,3508,3509,3510,3511,3512,3513,3514,3515,
+3516,3517,3518,3519,3520,3521,3522,3523,3524,3525,3526,3527,3528,3529,3530,3531,
+3532,3533,3534,3535,3536,3537,3538,3539,3540,3541,3542,3543,3544,3545,3546,3547,
+3548,3549,3550,3551,3552,3553,3554,3555,3553,3556,3557,3558,3559,3560,3561,3562,
+3563,3564,3565,3566,3567,3568,3569,3570,3571,3572,3573,3574,3463,3575,3576,3577,
+3578,3579,3580,3581,3582,3583,3584,3585,3586,3587,3588,3589,3590,3590,3591,3592,
+3593,3594,3595,3596,3597,3598,3599,3600,3601,3602,3603,3604,3605,3606,3607,3608,
+3609,3610,3609,3611,3612,3613,3614,3615,3616,3617,3618,3619,3620,3621,3622,3623,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
@@ -10369,155 +10502,155 @@ const unsigned short banks[75][256] =
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 127, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138,
- 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,3496, 150, 151, 152, 153, 154,
+ 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,3624, 150, 151, 152, 153, 154,
155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170,
171, 172, 173, 174, 175, 176, 177, 178, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
},
{
-1551,1552,1553,1554, 181, 182, 183,1555, 185,1556,3497,3498,3499, 188, 189,1560,
-1561,1562,1563,3500,1565, 195, 196, 197, 198, 199, 200, 201, 202,1566,1567, 205,
- 206, 207, 208,1568,1569,1570,1571,3501,1572,1573, 214, 215, 216, 217, 218, 219,
+1551,1552,1553,1554, 181, 182, 183,1555, 185,1556,3625,3626,3627, 188, 189,1560,
+1561,1562,1563,3628,1565, 195, 196, 197, 198, 199, 200, 201, 202,1566,1567, 205,
+ 206, 207, 208,1568,1569,1570,1571,3629,1572,1573, 214, 215, 216, 217, 218, 219,
220, 221,1574,1575,1576,1577,1578, 225,1579,1580, 226,1581,1582, 229, 230, 231,
232, 233, 234, 235,1583, 237, 238, 239,1584,1585, 240,1586, 242, 243, 244,1587,
246, 247,1588,1589, 249, 250, 251,1590, 252, 253, 254, 255,1591,1592,1593,1594,
1595, 259,1596,1597,1598,1599,1600,1601, 264, 265, 266, 267, 268, 269, 270, 271,
-1602, 272, 273,1603,1604,1605, 276,1606,1607,1608,1609,1610,3502,3503, 283, 284,
+1602, 272, 273,1603,1604,1605, 276,1606,1607, 295, 295,1610,3630,3631, 295, 284,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
- 295, 295, 295, 127,3504,1613,1614,3505,1616,3506,1618,3507,1620,3508,1622,3509,
-3510,1625,3511,3512,1628,1629,1630,1631,3513,1633,1634,3514,1636,1637,1638,1639,
+ 295, 295, 295, 127,3632,1613,1614,3633,1616,3634,1618,3635,1620,3636,1622,3637,
+3638,1625,3639,3640,1628,1629,1630,1631,3641,1633,1634,3642,1636,1637,1638,1639,
1640,1641,1642,1643,1644,1645,1646,1647,1648,1649,1650,1651,1652,1653,1654,1655,
1656,1657,1658,1659,1660,1661,1662,1663, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
},
{
-3515,3516,3517,3518,3519,3520,3521,3522,3523,3524,3525,3526,3527,3528,3529,3530,
-3531,3532,3533,3534,3535,3536,3537,3538,3539,3540,3541,3542,3543,3544,3545,3546,
-3547,3548,3549,3550,3551,3552,3553,3554,3555,3556,3557,3558,3559,3560,3561,3562,
-3563,3564,3565,3566,3567,3568,3569,3570,3571,3572,3573,3574,3575,3576,3577,3578,
-3579,3580,3581,3582,3583,3584,3585,3586,3587,3588,3589,3590,3591,3592,3593,3594,
-3595,3596,3597,3598,3599,3600,3601,3602,3603,3604,3605,3606,3607,3608,3609,3610,
-3611,3612,3613,3614,3615,3616,3617,3618,3619,3620,3621,3622,3623,3624,3625,3626,
-3627,3628,3629,3630,3631,3632,3633,3634,3635,3636,3637,3638,3639,3640,3641,3642,
-3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,
-3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,
-3643,3643,3643,3644,3645,3646,3647,3648,3649,3650,3651,3652,3653,3654,3655,3656,
-3657,3658,3659,3660,3658,3661,3662,3658,3663,3658,3664,3665,3666,3667,3668,3669,
-3670,3671,3672,3673,3674,3675,3676,3677,3678,3679,3680,3681,3682,3683,3684,3685,
-3686,3687, 806, 806, 806, 806, 806,3643,3643,3643,3643,3643,3643,3643,3643,3643,
-3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,
-3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,3643,
+3643,3644,3645,3646,3647,3648,3649,3650,3651,3652,3653,3654,3655,3656,3657,3658,
+3659,3660,3661,3662,3663,3664,3665,3666,3667,3668,3669,3670,3671,3672,3673,3674,
+3675,3676,3677,3678,3679,3680,3681,3682,3683,3684,3685,3686,3687,3688,3689,3690,
+3691,3692,3693,3694,3695,3696,3697,3698,3699,3700,3701,3702,3703,3704,3705,3706,
+3707,3708,3709,3710,3711,3712,3713,3714,3715,3716,3717,3718,3719,3720,3721,3722,
+3723,3724,3725,3726,3727,3728,3729,3730,3731,3732,3733,3734,3735,3736,3737,3738,
+3739,3740,3741,3742,3743,3744,3745,3746,3747,3748,3749,3750,3751,3752,3753,3754,
+3755,3756,3757,3758,3759,3760,3761,3762,3763,3764,3765,3766,3767,3768,3769,3770,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295,3772,3773,3774,3775,3776,3777,3778,3779,3780,3781,3782,3783,3784,
+3785,3786,3787,3788,3786,3789,3790,3786,3791,3786,3792,3793,3794,3795,3796,3797,
+3798,3799,3800,3801,3802,3803,3804,3805,3806,3807,3808,3809,3810,3811,3812,3813,
+3814,3815, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
},
{
-3287,1492,3688,3289, 713,3689,3690, 730,1914,3691,1533,3293,3692,3693,3694,3695,
-3298,3696,3697,3698,3699,3700,3701,3702,3703,3704,3705,3706, 759, 437,3707,3708,
-3308,3709,3710,3711,3712,3713, 442,3714,3715,3716,3717,3718,3719,3720,3721,3722,
-3723,2306,3724,3725,3726,3727,3728,3729,3730,3731,3732,3733,3734,3735,3736,3737,
-3738,3739,3740,3741,3742,3743,3744,3745,3746,3747,3748,3749,3750,3751,3752,3753,
-3754,3755,3756,3757,3758,3759,3760,3761,3762,3763,3764,3765,3766,3767,3768,3769,
-3770,3771,3772,3773,3774,3775,3776,3777,3778,3779,3780,3781,3782,3783,3784,3785,
-3786,3787,3788,3789,3790,3791,3792,3793,3794,3795,3371,3796,3797,2421,3798,3799,
+3415,1492,3816,3417, 713,3817,3818, 730,1914,3819,1533,3421,3820,3821,3822,3823,
+3426,3824,3825,3826,3827,3828,3829,3830,3831,3832,3833,3834, 759, 437,3835,3836,
+3436,3837,3838,3839,3840,3841, 442,3842,3843,3844,3845,3846,3847,3848,3849,3850,
+3851,2306,3852,3853,3854,3855,3856,3857,3858,3859,3860,3861,3862,3863,3864,3865,
+3866,3867,3868,3869,3870,3871,3872,3873,3874,3875,3876,3877,3878,3879,3880,3881,
+3882,3883,3884,3885,3886,3887,3888,3889,3890,3891,3892,3893,3894,3895,3896,3897,
+3898,3899,3900,3901,3902,3903,3904,3905,3906,3907,3908,3909,3910,3911,3912,3913,
+3914,3915,3916,3917,3918,3919,3920,3921,3922,3923,3499,3924,3925,2421,3926,3927,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
- 295, 295, 295,3644,3645,3646,3647,3648,3649,3650,3651,3652,3653,3654,3655,3656,
-3657,3658,3659,3660,3658,3661,3662,3658,3663,3658,3664,3665,3666,3667,3668,3669,
-3670,3671,3672,3673,3674,3675,3676,3677,3678,3679,3680,3681,3682,3683,3684,3685,
-3686,3687, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295,3772,3773,3774,3775,3776,3777,3778,3779,3780,3781,3782,3783,3784,
+3785,3786,3787,3788,3786,3789,3790,3786,3791,3786,3792,3793,3794,3795,3796,3797,
+3798,3799,3800,3801,3802,3803,3804,3805,3806,3807,3808,3809,3810,3811,3812,3813,
+3814,3815, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
},
{
-3800,3801,3802,3803,3804,3805,3806,3807,3808,3809,3810,3811,3812,3813,3814,3815,
-3816,3817,3818,3819,3820,3821,3822,3823,3824,3825,3826,3827,3828,3829,3830,3831,
-3832,3833,3834,3835,3836,3837,3838,3839,3840,3841,3842,3843,3844,3845,3846,3847,
-3840,3848,3849,3850,3851,3852,3853,3854,3855,3856,3857,3858,3859,3860,3861,3862,
-3863,3864,3864,3865,3866,3867,3868,3869,3870,3871,3872,3873,3874,3875,3876,3877,
-3878,3879,3880,3881,3882,3883,3884,3885,3886,3887,3888,3889,3890,3891,3892,3893,
-3894,3895,3896,3897,3898,3899,3900,3901,3902,3903,3904,3905,3906,3907,3908,3909,
-3910,3911,3912,3913,3914,3915,3916,3917,3918,3919,3920,3921,3922,3923,3924,3925,
-3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,
-3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,
-3926,3926,3926,3927,3928,3929,3930,3931,3932,3933,3934,3935,3936,3937,3938,3939,
-3940,3941,3942,3660,3943,3944,3662,3945,3663,3946,3947,3665,3948,3949,3950,3951,
-3952,3953,3954,3955,3956,3936,3676,3957,3958,3679,3959,3960,3961,3962,3684,3685,
-3963,3964,3965,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,
-3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,
-3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,3926,
+3928,3929,3930,3931,3932,3933,3934,3935,3936,3937,3938,3939,3940,3941,3942,3943,
+3944,3945,3946,3947,3948,3949,3950,3951,3952,3953,3954,3955,3956,3957,3958,3959,
+3960,3961,3962,3963,3964,3965,3966,3967,3968,3969,3970,3971,3972,3973,3974,3975,
+3968,3976,3977,3978,3979,3980,3981,3982,3983,3984,3985,3986,3987,3988,3989,3990,
+3991,3992,3992,3993,3994,3995,3996,3997,3998,3999,4000,4001,4002,4003,4004,4005,
+4006,4007,4008,4009,4010,4011,4012,4013,4014,4015,4016,4017,4018,4019,4020,4021,
+4022,4023,4024,4025,4026,4027,4028,4029,4030,4031,4032,4033,4034,4035,4036,4037,
+4038,4039,4040,4041,4042,4043,4044,4045,4046,4047,4048,4049,4050,4051,4052,4053,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295,4055,4056,4057,4058,4059,4060,4061,4062,4063,4064,4065,4066,4067,
+4068,4069,4070,3788,4071,4072,3790,4073,3791,4074,4075,3793,4076,4077,4078,4079,
+4080,4081,4082,4083,4084,4064,3804,4085,4086,3807,4087,4088,4089,4090,3812,3813,
+4091,4092,4093, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
},
{
-3800,3801,3802,3803,3804,3805,3806,3807,3808,3809,3810,3811,3812,3813,3814,3815,
-3816,3817,3818,3819,3820,3821,3822,3823,3824,3825,3826,3827,3828,3830,3966,3831,
-3832,3833,3834,3835,3836,3837,3838,3839,3840,3841,3842,3843,3967,3845,3846,3847,
-3840,3848,3849,3850,3851,3852,3853,3854,3855,3856,3857,3858,3859,3860,3968,3862,
-3863,3864,3864,3865,3866,3867,3868,3869,3870,3871,3872,3873,3874,3875,3876,3877,
-3969,3879,3970,3881,3882,3883,3884,3885,3886,3887,3888,3889,3890,3891,3892,3893,
-3894,3895,3896,3897,3898,3899,3900,3901,3902,3903,3971,3972,3973,3907,3908,3909,
-3910,3911,3912,3913,3974,3915,3916,3975,3918,3919,3920,3921,3922,3923,3924,3925,
-3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,
-3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3977,3977,3977,3977,3978,
-3977,3977,3977,3927,3928,3979,3930,3931,3932,3980,3934,3935,3936,3937,3938,3939,
-3940,3941,3942,3660,3943,3944,3662,3945,3663,3946,3947,3665,3948,3949,3950,3951,
-3952,3953,3954,3955,3956,3936,3676,3957,3958,3981,3982,3960,3983,3984,3684,3685,
-3963,3964,3965,3977,3977,3977,3977,3977,3977,3976,3985,3985,3985,3985,3985,3985,
-3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,
-3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,
+3928,3929,3930,3931,3932,3933,3934,3935,3936,3937,3938,3939,3940,3941,3942,3943,
+3944,3945,3946,3947,3948,3949,3950,3951,3952,3953,3954,3955,3956,3958,4094,3959,
+3960,3961,3962,3963,3964,3965,3966,3967,3968,3969,3970,3971,4095,3973,3974,3975,
+3968,3976,3977,3978,3979,3980,3981,3982,3983,3984,3985,3986,3987,3988,4096,3990,
+3991,3992,3992,3993,3994,3995,3996,3997,3998,3999,4000,4001,4002,4003,4004,4005,
+4097,4007,4098,4009,4010,4011,4012,4013,4014,4015,4016,4017,4018,4019,4020,4021,
+4022,4023,4024,4025,4026,4027,4028,4029,4030,4031,4099,4100,4101,4035,4036,4037,
+4038,4039,4040,4041,4102,4043,4044,4103,4046,4047,4048,4049,4050,4051,4052,4053,
+4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,
+4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4105,4105,4105,4105,4106,
+4105,4105,4105,4055,4056,4107,4058,4059,4060,4108,4062,4063,4064,4065,4066,4067,
+4068,4069,4070,3788,4071,4072,3790,4073,3791,4074,4075,3793,4076,4077,4078,4079,
+4080,4081,4082,4083,4084,4064,3804,4085,4086,4109,4110,4088,4111,4112,3812,3813,
+4091,4092,4093,4105,4105,4105,4105,4105,4105,4104,4113,4113,4113,4113,4113,4113,
+4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,
+4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,
},
{
1222,1223,1224,1225,1226,1227,1228,1229,1230,1231,1232,1233,1234,1235,1236,1237,
-1238,1239,1240,1241,1242,1243,1244,1245,3986,3987,3988,1249,1250,1376,1377,1253,
-1378,1255,1256,3989,1380,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,3990,
-1270,3991,3992,3993,3994,1275,1276,1277,1278,1279,1381,1281,1282,1283,1284,1285,
+1238,1239,1240,1241,1242,1243,1244,1245,4114,4115,4116,1249,1250,1376,1377,1253,
+1378,1255,1256,4117,1380,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,4118,
+1270,4119,4120,4121,4122,1275,1276,1277,1278,1279,1381,1281,1282,1283,1284,1285,
1286,1287,1288,1289,1290,1291,1292,1293,1294,1295,1296,1297,1298,1299,1300,1301,
-1302,1303,1304,1305,3995,1307,1308,1309,1309,1310,1311,1312,1313,1314,1315,1316,
+1302,1303,1304,1305,4123,1307,1308,1309,1309,1310,1311,1312,1313,1314,1315,1316,
1317,1318,1319,1320,1321,1322,1323,1324,1325,1326,1327,1328,1329,1330,1331,1332,
-1333,1334,1335,1336,1337,3996,1339,1340,1341,1342,1343,1344,1345,1346,1347,1348,
+1333,1334,1335,1336,1337,4124,1339,1340,1341,1342,1343,1344,1345,1346,1347,1348,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
- 295, 295, 295, 312,1349,1350,3997,1352,3998,1354,3999,1355, 320,1356, 321,1357,
+ 295, 295, 295, 312,1349,1350,4125,1352,4126,1354,4127,1355, 320,1356, 321,1357,
1358,1359,1360,1361,1362,1363,1364,1383,1366,1359,1384,1361, 332, 333, 334, 335,
- 336,1368,1369, 338, 339, 320,1370,1371,1371,1371,1371,1372,1373,1374,1375,1371,
+ 336,1368,1369, 338, 339, 320,1370, 295, 295, 295, 295,1372,1373,1374,1375, 295,
347, 348, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
},
{
-4000,4001,4002,4003,4004,4005, 6, 7,4006, 9, 10,4007, 12, 13, 14, 15,
-4008,4009,4010,4011, 20,4012,4013,4014,4015,4016,4017,4018,4019,4020,4021,4022,
- 32,4023,4024,4025,4026,4027,4028,4029,4030,4031,4032,4033,4034,4035,4036, 46,
-4037,4038,4039,4040,4041,4042,4043, 54,4044,4045,4046,4047,4048,4049,4050,4051,
-4052,4053,4054, 66,4055,4056, 69,4057,4058,4059,4060, 74, 75, 76, 77, 78,
-4061,4062,4063, 82,4064,4065, 85,4066,4067, 88,4068,4069,4070,4071,4072,4073,
- 95, 96, 97,4074,4075,4076,4077, 102, 103,4078, 105, 106, 107,4079,4080,4081,
-4082, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,4083,4084,4085, 125,4086,
- 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806,
- 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806,
- 806, 806, 806,3644,3645,3646,3647,3648,3649,3650,3651,3652,3653,3654,3655,3656,
-3657,3658,3659,3660,3658,3661,3662,3658,3663,3658,3664,3665,3666,3667,3668,3669,
-3670,3671,3672,3673,3674,3675,3676,3677,3678,3679,3680,3681,3682,3683,3684,3685,
-3686,3687, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806,
- 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806,
- 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806,
+4128,4129,4130,4131,4132,4133, 6, 7,4134, 9, 10,4135, 12, 13, 14, 15,
+4136,4137,4138,4139, 20,4140,4141,4142,4143,4144,4145,4146,4147,4148,4149,4150,
+ 32,4151,4152,4153,4154,4155,4156,4157,4158,4159,4160,4161,4162,4163,4164, 46,
+4165,4166,4167,4168,4169,4170,4171, 54,4172,4173,4174,4175,4176,4177,4178,4179,
+4180,4181,4182, 66,4183,4184, 69,4185,4186,4187,4188, 74, 75, 76, 77, 78,
+4189,4190,4191, 82,4192,4193, 85,4194,4195, 88,4196,4197,4198,4199,4200,4201,
+ 95, 96, 97,4202,4203,4204,4205, 102, 103,4206, 105, 106, 107,4207,4208,4209,
+4210, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,4211,4212,4213, 125,4214,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295,3772,3773,3774,3775,3776,3777,3778,3779,3780,3781,3782,3783,3784,
+3785,3786,3787,3788,3786,3789,3790,3786,3791,3786,3792,3793,3794,3795,3796,3797,
+3798,3799,3800,3801,3802,3803,3804,3805,3806,3807,3808,3809,3810,3811,3812,3813,
+3814,3815, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
},
{
-3287,3288, 466,3289, 713,3196,3290, 467,3291, 632,3292,3293,3294,3295,4087,3297,
-3298, 598,4088,3300,3301,3302,3303,3304,4089,4090,4091,4092, 759, 437, 438,3307,
-3308,3309, 439,3310, 440,4093, 442,4094,3312,3313,3314,3315,2306,4095,3317, 582,
-3318,3319, 452,3320,3321,4096,3322,3323,3324, 778,3325,2312, 779,3326,3327,3328,
-3329, 769,3330,3331,3332,3333, 663, 664,3334,2316,3335,3336,3337,1299,3338,3339,
-3340,3341,4097,3343,3344,3345,4098, 442,3347,3348,3349,3304,3350,1669,3351,3352,
-3353,3354,3355,3356,4099, 261,3357,3358,1919,2420,3359,3360, 676,3361,3362,3363,
-3364,4100,3366,3367,4101,4102, 680,3369,3370, 462,3371, 455,3372,2421,3373, 465,
- 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806,
- 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806,
- 806, 806, 806,3644,3645,4103,3649,3648,4104,4105,4106,4107,4108,4109,4110,4111,
-4112,3658,4113,3660,3658,3661,3662,3658,3663,3658,3664,2617,3666,3667,3668,3669,
-3670,3671,3672,3673,3674, 160,3676,3677,3678,3679,3680,3681,3682,3683,3684,3685,
-3686,3687, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806,
- 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806,
- 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806,
+3415,3416, 466,3417, 713,3324,3418, 467,3419, 632,3420,3421,3422,3423,4215,3425,
+3426, 598,4216,3428,3429,3430,3431,3432,4217,4218,4219,4220, 759, 437, 438,3435,
+3436,3437, 439,3438, 440,4221, 442,4222,3440,3441,3442,3443,2306,4223,3445, 582,
+3446,3447, 452,3448,3449,4224,3450,3451,3452, 778,3453,2312, 779,3454,3455,3456,
+3457, 769,3458,3459,3460,3461, 663, 664,3462,2316,3463,3464,3465,1299,3466,3467,
+3468,3469,4225,3471,3472,3473,4226, 442,3475,3476,3477,3432,3478,1669,3479,3480,
+3481,3482,3483,3484,4227, 261,3485,3486,1919,2420,3487,3488, 676,3489,3490,3491,
+3492,4228,3494,3495,4229,4230, 680,3497,3498, 462,3499, 455,3500,2421,3501, 465,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295,3772,3773,4231,3777,3776,4232,4233,4234,4235,4236,4237,4238,4239,
+4240,3786,4241,3788,3786,3789,3790,3786,3791,3786,3792,2617,3794,3795,3796,3797,
+3798,3799,3800,3801,3802, 160,3804,3805,3806,3807,3808,3809,3810,3811,3812,3813,
+3814,3815, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
},
{
622, 179, 371, 180, 372, 373, 374, 375, 376, 377, 186, 378, 187, 379, 380, 190,
@@ -10530,106 +10663,106 @@ const unsigned short banks[75][256] =
111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127,4114,4115,4116, 141,4117,4118,4119,4118,4120,4118,4121,4122,
-4123,1954,4124,4125,4126,4127,4128,4129,4130,4131,4132,4133,4134,4135,4136,4137,
-4138,4139,4140,4141,4142,4143, 163,4144, 625,4145,4146,4147,4148,4149,4150,4151,
-4152,4153,4154,4155,4156,4157,4158, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127,4242,4243,4244, 141,4245,4246,4247,4246,4248,4246,4249,4250,
+4251,1954,4252,4253,4254,4255,4256,4257,4258,4259,4260,4261,4262,4263,4264,4265,
+4266,4267,4268,4269,4270,4271, 163,4272, 625,4273,4274,4275,4276,4277,4278,4279,
+4280,4281,4282,4283,4284,4285,4286, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
},
{
-4159,4160,1553,1554, 181,4161,4162,1555, 185,4163,3497,4164,1559, 188,4165,4166,
-4167,1562,4168,4169,1565, 195,4170, 197,4171,4172, 200, 201, 28,1566,1567,4173,
-4174,4175,4176,4177,4178,4179,4180,4181,1572,1573, 214, 215, 216, 217, 218, 219,
- 220,4182,4183,1575,1576,1577,1578,4184,1579,1580,4185,1581,4186,4187,4188,4189,
- 232, 233, 234, 235,4190, 237, 238,4191,1584,1585, 240,1586, 242, 243, 244,1587,
- 246,4192,4193,1589, 249, 250, 251,1590, 252,4194, 254, 255,4195,4196,4197,4198,
-1595,4199,1596,1597,1598,1599,1600,1601,4200,4201,4202, 267,4203,4204, 270,4205,
-4206,4207, 273,1603,4208,1605, 276,4209,4210,4211,4212,1610,4213,4214,4215, 126,
- 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806,
- 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806,
- 806, 806, 806,4216,1470,1613,4217,1615,4218,1475,4219,1477,4220,1479,4221,1481,
-1482,4222,1484,4223,4224,4225,1630,4226,2291,4227,1634,3514,1636,1637,1638,1639,
-1640,4228,4229,1643,1644,1645,1646,4230, 342,4231,4232,1651,1652,1653,4233,4234,
-1656,4235,1658,1659,1660,1661,1662,1663, 806, 806, 806, 806, 806, 806, 806, 806,
- 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806,
- 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806,
+4287,4288,1553,1554, 181,4289,4290,1555, 185,4291,3625,4292,1559, 188,4293,4294,
+4295,1562,4296,4297,1565, 195,4298, 197,4299,4300, 200, 201, 28,1566,1567,4301,
+4302,4303,4304,4305,4306,4307,4308,4309,1572,1573, 214, 215, 216, 217, 218, 219,
+ 220,4310,4311,1575,1576,1577,1578,4312,1579,1580,4313,1581,4314,4315,4316,4317,
+ 232, 233, 234, 235,4318, 237, 238,4319,1584,1585, 240,1586, 242, 243, 244,1587,
+ 246,4320,4321,1589, 249, 250, 251,1590, 252,4322, 254, 255,4323,4324,4325,4326,
+1595,4327,1596,1597,1598,1599,1600,1601,4328,4329,4330, 267,4331,4332, 270,4333,
+4334,4335, 273,1603,4336,1605, 276,4337,4338,4339,4340,1610,4341,4342,4343, 126,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295,4344,1470,1613,4345,1615,4346,1475,4347,1477,4348,1479,4349,1481,
+1482,4350,1484,4351,4352,4353,1630,4354,2291,4355,1634,3642,1636,1637,1638,1639,
+1640,4356,4357,1643,1644,1645,1646,4358, 342,4359,4360,1651,1652,1653,4361,4362,
+1656,4363,1658,1659,1660,1661,1662,1663, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
},
{
-3643, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859,
+ 295, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859,
860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871,2216, 873, 874, 875,
876, 877, 878,2217, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891,
892, 893, 894,2218, 896, 897, 898, 899, 900,2219,2220, 903,2221, 905,2222,2223,
2224, 909,2225, 911, 912,2226,2227, 915, 916,2228,2229, 919, 920, 921, 922, 923,
-2230, 925, 926, 927, 928, 929,4236, 931, 932, 933, 934, 935,2232,2233, 938,2234,
- 940,4237, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955,
- 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966,4238, 968,4239,3643,3643,
-4240,4241,4242,4243,4244,4245,4246, 978,4247,4248,4249,4250,4251,4252,4253,4254,
-4255,4256,4257,4258,4259,4260,4261,4262,4263,4264,4265, 975, 971, 972, 973, 974,
+2230, 925, 926, 927, 928, 929, 295, 931, 932, 933, 934, 935,2232,2233, 938,2234,
+ 940, 295, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955,
+ 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966,4366, 968,4367, 295, 295,
+4368,4369,4370,4371,4372,4373,4374, 978,4375,4376,4377,4378,4379,4380,4381,4382,
+4383,4384,4385,4386,4387,4388,4389,4390,4391,4392,4393, 975, 971, 972, 973, 974,
975, 310, 976, 977, 978, 974,2239, 980,2240, 982,2241, 984,2242, 985,2243, 987,
988,2244, 990, 325,2244, 325, 991,2244,2245,2246, 330, 993,2247,2248,2249, 997,
998,2250,2251,1001,1002,1003, 340,1004,1005,1006,1007,1008,1009, 310,1010,1011,
-2252, 429,1003, 430,1013,1014, 974,1015,4266,4266,4266,4266,4266,4266,4266,4266,
-4266,4266,4266,4266,4266,4266,4266,4266,4266,4266,4266,4266,4266,4266,4266,4266,
-4266,4266,4266,4266,4266,4266,4266,4266,4266,4266,4266,4266,4266,4266,4266,4266,
+2252, 429,1003, 430,1013,1014, 974,1015, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
},
{
-3287,4267,3196,3196,4268,3196,3196,3196,3196,3196,3196, 378,3196,3196,3694,3196,
-3196,4269,3196,4270,4271,4272,3196,3196,3196, 370,3196,4273,4274,4275,4276,4277,
-3196,4278,4279,4280,3310,3310,4281, 442,4282,3196,3196,4283,4284,4283, 676,4285,
-4286,3196,3196,4287, 51,3196,3196,3196,4288,3324,4289,3196, 59,4290,4288, 62,
-3196,4291,4291,4292, 67,3196, 664,4293,3196,2316,3196,4294, 70,3196,4295, 78,
-4296,4297, 81,3196,3196,3196,3196,3196,3196,3196,3196, 90,3196,4298, 93,4299,
-3196,3196,3196,3196,3196,3196,3196,4300,3196,3196,3196,3196,3196,3196,3196,3196,
-3196,3196,3196,3196,3196,4101,3196,4301,3196,3196,3196,3196,3196,3196,3196,3196,
-3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,
-3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,
-3196,3196,3196,4302,4302,4303,4304,4305,4306,4307,4308,4309,4310,4311,4312,4313,
-4314,4315,4316,4317,4318,4319,4320,4321,4322,4323,4324,4325,3196,3196,4326, 154,
-4327,4328,4329,3196,3196, 160,3196,3196,3196,4330,4331,4332,4333,4334,4335,3196,
-3196,4336, 160,4337,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,
-3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,
-3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,3196,
+3415,4395,3324,3324,4396,3324,3324,3324,3324,3324,3324, 378,3324,3324,3822,3324,
+3324,4397,3324,4398,4399,4400,3324,3324,3324, 370,3324,4401,4402,4403,4404,4405,
+3324,4406,4407,4408,3438,3438,4409, 442,4410,3324,3324,4411,4412,4411, 676,4413,
+4414,3324,3324,4415, 51,3324,3324,3324,4416,3452,4417,3324, 59,4418,4416, 62,
+3324,4419,4419,4420, 67,3324, 664,4421,3324,2316,3324,4422, 70,3324,4423, 78,
+4424,4425, 81,3324,3324,3324,3324,3324,3324,3324,3324, 90,3324,4426, 93,4427,
+3324,3324,3324,3324,3324,3324,3324,4428,3324,3324,3324,3324,3324,3324,3324,3324,
+3324,3324,3324,3324,3324,4229,3324,4429,3324,3324,3324,3324,3324,3324,3324,3324,
+3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,
+3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,
+3324,3324,3324,4430,4430,4431,4432,4433,4434,4435,4436,4437,4438,4439,4440,4441,
+4442,4443,4444,4445,4446,4447,4448,4449,4450,4451,4452,4453,3324,3324,4454, 154,
+4455,4456,4457,3324,3324, 160,3324,3324,3324,4458,4459,4460,4461,4462,4463,3324,
+3324,4464, 160,4465,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,
+3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,
+3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,3324,
},
{
-3800,3801,3802,3803,3804,3805,3806,3807,3808,3809,3810,3811,3812,3813,3814,3815,
-3816,3817,3818,3819,3820,3821,3822,3823,3824,3825,3826,3827,3828,3829,3830,3831,
-3832,3833,3834,3835,3836,3837,3838,3839,3840,3841,3842,3843,3844,3845,3846,3847,
-3840,3848,3849,3850,3851,3852,3853,3854,3855,3856,3857,3858,3859,3860,3861,3862,
-3863,3864,3864,3865,3866,3867,3868,3869,3870,3871,3872,3873,3874,3875,3876,3877,
-3878,3879,3880,3881,3882,3883,3884,3885,3886,3887,3888,3889,3890,3891,3892,3893,
-3894,3895,3896,3897,3898,3899,3900,3901,3902,3903,3904,3905,3906,3907,3908,3909,
-3910,3911,3912,3913,3914,3915,3916,3917,3918,3919,4338,3921,3922,3923,3924,3925,
-3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,
-3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3976,3977,3977,3977,3977,3977,
-3977,3977,3977,3927,3928,3929,3930,3931,3932,3933,3934,3935,3936,3937,3938,3939,
-3940,3941,3942,3660,3943,3944,3662,3945,3663,3946,3947,3665,3948,3949,3950,3951,
-3952,3953,3954,3955,3956,3936,3676,3957,3958,3679,3959,3960,3961,3962,3684,3685,
-3963,3964,3965,3977,3977,3977,3977,3977,3977,3976,3985,3985,3985,3985,3985,3985,
-3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,
-3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,3985,
+3928,3929,3930,3931,3932,3933,3934,3935,3936,3937,3938,3939,3940,3941,3942,3943,
+3944,3945,3946,3947,3948,3949,3950,3951,3952,3953,3954,3955,3956,3957,3958,3959,
+3960,3961,3962,3963,3964,3965,3966,3967,3968,3969,3970,3971,3972,3973,3974,3975,
+3968,3976,3977,3978,3979,3980,3981,3982,3983,3984,3985,3986,3987,3988,3989,3990,
+3991,3992,3992,3993,3994,3995,3996,3997,3998,3999,4000,4001,4002,4003,4004,4005,
+4006,4007,4008,4009,4010,4011,4012,4013,4014,4015,4016,4017,4018,4019,4020,4021,
+4022,4023,4024,4025,4026,4027,4028,4029,4030,4031,4032,4033,4034,4035,4036,4037,
+4038,4039,4040,4041,4042,4043,4044,4045,4046,4047,4466,4049,4050,4051,4052,4053,
+4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,
+4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4104,4105,4105,4105,4105,4105,
+4105,4105,4105,4055,4056,4057,4058,4059,4060,4061,4062,4063,4064,4065,4066,4067,
+4068,4069,4070,3788,4071,4072,3790,4073,3791,4074,4075,3793,4076,4077,4078,4079,
+4080,4081,4082,4083,4084,4064,3804,4085,4086,3807,4087,4088,4089,4090,3812,3813,
+4091,4092,4093,4105,4105,4105,4105,4105,4105,4104,4113,4113,4113,4113,4113,4113,
+4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,
+4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,4113,
},
{
-4339,4340,4341,4342,4343,4344,4345,4346,4347,4348,4349,4350,4351,4352,4353,4354,
-4355,4356,4357,4358,4359,4360,4361,4362,4363,4364,4365,4366,4367,4368,4369,4370,
-4371,4372,4373,4374,4375,4376,4377,4378,4379,4380,4381,4382,4383,4384,4385,4386,
-4387,4388,4389,4390,4391,4392,4393,4394,4395,4396,4397,4398,4399,4400,4401,4402,
-4403,4404,4405,4406,4407,4408,4409,4410,4411,4412,4413,4414,4415,4416,4417,4418,
-4419,4420,4421,4422,4423,4424,4425,4426,4427,4428,4429,4430,4431,4432,4433,4434,
-4435,4436,4437,4438,4439,4440,4441,4442,4443,4444,4445,4446,4447,4448,4449,4450,
-4451,4452,4453,4454,4455,4456,4457,4458,4459,4460,4461,4462,4463,4464,4465,4466,
- 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806,
- 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806,4467,4468,4469,4470,4471,
-4472,4473,4474,4475,4476,4477,4217,4478,4218,4479,4480,4481,4482,4483,4221,4484,
-4485,4222,4486,4487,4224,4488,4489,4226,4490,4227,4491,4492,4493,4494,4495,4496,
-4497,4498,4499,4500,4501, 320,4502,4503,4504,4505,4506,4507,4508,1374,4509,4510,
-4511,4512,4513,4514,4515,4516,4517,4518, 806, 806, 806, 806, 806, 806, 806, 806,
- 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806,
- 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806,
+4467,4468,4469,4470,4471,4472,4473,4474,4475,4476,4477,4478,4479,4480,4481,4482,
+4483,4484,4485,4486,4487,4488,4489,4490,4491,4492,4493,4494,4495,4496,4497,4498,
+4499,4500,4501,4502,4503,4504,4505,4506,4507,4508,4509,4510,4511,4512,4513,4514,
+4515,4516,4517,4518,4519,4520,4521,4522,4523,4524,4525,4526,4527,4528,4529,4530,
+4531,4532,4533,4534,4535,4536,4537,4538,4539,4540,4541,4542,4543,4544,4545,4546,
+4547,4548,4549,4550,4551,4552,4553,4554,4555,4556,4557,4558,4559,4560,4561,4562,
+4563,4564,4565,4566,4567,4568,4569,4570,4571,4572,4573,4574,4575,4576,4577,4578,
+4579,4580,4581,4582,4583,4584,4585,4586,4587,4588,4589,4590,4591,4592,4593,4594,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,4595,4596,4597,4598,4599,
+4600,4601,4602,4603,4604,4605,4345,4606,4346,4607,4608,4609,4610,4611,4349,4612,
+4613,4614,4615,4616,4352,4617,4618,4354,4619,4620,4621,4622,4623,4624,4625,4626,
+4627,4628,4629,4630,4631, 320,4632,4633,4634,4635,4636,4637,4638,1374,4639,4640,
+4641,4642,4643,4644,4645,4646,4647,4648, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
},
{
-4519,4520,4521,4522,4520,4523,4524,4525,4526,4527,4528,4530,4531,4532,4533,4534,
-4535,4537,4539,4532,4541,4542,4543,4544,4545,4546,4547, 295, 28, 29, 30, 31,
+4649,4650,4651,4652,4650,4653,4654,4655,4656,4657,4658,4660,4661,4662,4663,4664,
+4665,4667,4669,4662,4671,4672,4673,4674,4675,4676,4677, 295, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 33, 39, 40, 41, 42, 43, 44, 45, 46,
47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
@@ -10638,30 +10771,30 @@ const unsigned short banks[75][256] =
111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
- 295, 295, 295, 127,4536, 128,4538, 130, 131, 132,4540, 134, 135, 136, 137, 138,
- 139, 140, 141, 142, 143, 144,4529, 146, 147, 148, 149, 150, 151, 152, 153, 154,
+ 295, 295, 295, 127,4666, 128,4668, 130, 131, 132,4670, 134, 135, 136, 137, 138,
+ 139, 140, 141, 142, 143, 144,4659, 146, 147, 148, 149, 150, 151, 152, 153, 154,
155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
},
{
-4549,4550,4551,4552,4553,4554,4555,4556,4557,4558,4559,4560,4561,3295,4558,4562,
-3298,4563,4564,3298,4565,4566,4566,4566, 868, 869, 870,4567,4568,4569,4570,4571,
-4572,4573,4574,4574,4575,4572,4576,4577,3842,4578,4579,4579,4580,4581,4582,4583,
-4584,4585,4586,4586,4587,4096,3322,4588,4589,4590,4591,4592,4593,4589,4589,4594,
-3329, 769,3330,3331,4595,4596,4597,4598,4599,4600,4601,4602,4603,4600,1300,4604,
-4605,4606,4600,4565,4607,4589,4608,4609,3347,4610,4611,4612,4613,1314,4614,4615,
-4616,4617,4618,4611,4611,1322,4619,4620,4621,4622,4623,4622,3295,4624,3842,4625,
-4626,1334,4626,4627,4628,4629, 792,4630,1341,1342,1343,1344,4631,4632,4633,1348,
- 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806,
- 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806,
- 806, 806, 806,4634,4634,4635,4636,4635,4637,4638,4639,4640,4641,4642,4643,4644,
-4645,4646,4647,4648,4649,4650,4651,4652,4653,4646,4654,4655,4656,4657,4658,4659,
-4660,4661,4662,4663,4664,4665,4666,4663,4664,4665,4667,4668,4669,4670,1375,1371,
-4671,4672, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806,
- 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806,
- 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806, 806,
+4679,4680,4681,4682,4683,4684,4685,4686,4687,4688,4689,4690,4691,3423,4688,4692,
+3426,4693,4694,3426,4695,4696,4696,4696, 868, 869, 870,4697,4698,4699,4700,4701,
+4702,4703,4704,4704,4705,4702,4706,4707,3970,4708,4709,4709,4710,4711,4712,4713,
+4714,4715,4716,4716,4717,4224,3450,4718,4719,4720,4721,4722,4723,4719,4719,4724,
+3457, 769,3458,3459,4725,4726,4727,4728,4729,4730,4731,4732,4733,4730,1300,4734,
+4735,4736,4730,4695,4737,4719,4738,4739,3475,4740,4741,4742,4743,1314,4744,4745,
+4746,4747,4748,4741,4741,1322,4749,4750,4751,4752,4753,4752,3423,4754,3970,4755,
+4756,1334,4756,4757,4758,4759, 792,4760,1341,1342,1343,1344,4761,4762,4763,1348,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295,4764,4764,4765,4766,4765,4767,4768,4769,4770,4771,4772,4773,4774,
+4775,4776,4777,4778,4779,4780,4781,4782,4783,4776,4784,4785,4786,4787,4788,4789,
+4790,4791,4792,4793,4794,4795,4796,4793,4794,4795,4797,4798,4799,4800,1375, 295,
+4801,4802, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
},
};
@@ -10741,5 +10874,5 @@ const AdlBankSetup adlbanksetup[75] =
{3, 0, 0, 0, 0}, //Bank 71, TMB (Nam)
{0, 0, 0, 0, 0}, //Bank 72, WOPL (DMXOPL3 bank by Sneakernets)
{1, 0, 0, 0, 0}, //Bank 73, EA (Cartooners)
- {0, 1, 0, 0, 0} //Bank 74, WOPL (Apogee IMF 90-ish)
+ {0, 0, 1, 0, 0} //Bank 74, WOPL (Apogee IMF 90-ish)
};
diff --git a/src/adldata.hh b/src/adldata.hh
index e9ff00b..104db82 100644
--- a/src/adldata.hh
+++ b/src/adldata.hh
@@ -24,8 +24,16 @@
#ifndef ADLDATA_H
#define ADLDATA_H
+#include <string.h>
#include <stdint.h>
+#pragma pack(push, 1)
+#define ADLDATA_BYTE_COMPARABLE(T) \
+ inline bool operator==(const T &a, const T &b) \
+ { return !memcmp(&a, &b, sizeof(T)); } \
+ inline bool operator!=(const T &a, const T &b) \
+ { return !operator==(a, b); }
+
extern const struct adldata
{
uint32_t modulator_E862, carrier_E862; // See below
@@ -34,22 +42,46 @@ extern const struct adldata
int8_t finetune;
} adl[];
+ADLDATA_BYTE_COMPARABLE(struct adldata)
+enum { adlDefaultNumber = 189 };
extern const struct adlinsdata
{
- enum { Flag_Pseudo4op = 0x01, Flag_NoSound = 0x02 };
+ enum { Flag_Pseudo4op = 0x01, Flag_NoSound = 0x02, Flag_Real4op = 0x04 };
uint16_t adlno1, adlno2;
uint8_t tone;
uint8_t flags;
uint16_t ms_sound_kon; // Number of milliseconds it produces sound;
uint16_t ms_sound_koff;
- double voice2_fine_tune;
+ double voice2_fine_tune;
} adlins[];
+ADLDATA_BYTE_COMPARABLE(struct adlinsdata)
int maxAdlBanks();
extern const unsigned short banks[][256];
extern const char* const banknames[];
+enum { adlNoteOnMaxTime = 40000 };
+
+/**
+ * @brief Instrument data with operators included
+ */
+struct adlinsdata2
+{
+ adldata adl[2];
+ uint8_t tone;
+ uint8_t flags;
+ uint16_t ms_sound_kon; // Number of milliseconds it produces sound;
+ uint16_t ms_sound_koff;
+ double voice2_fine_tune;
+ adlinsdata2() {}
+ explicit adlinsdata2(const adlinsdata &d);
+};
+ADLDATA_BYTE_COMPARABLE(struct adlinsdata2)
+
+#undef ADLDATA_BYTE_COMPARABLE
+#pragma pack(pop)
+
/**
* @brief Bank global setup
*/
@@ -62,4 +94,26 @@ extern const struct AdlBankSetup
bool scaleModulators;
} adlbanksetup[];
+/**
+ * @brief Conversion of storage formats
+ */
+inline adlinsdata2::adlinsdata2(const adlinsdata &d)
+ : tone(d.tone), flags(d.flags),
+ ms_sound_kon(d.ms_sound_kon), ms_sound_koff(d.ms_sound_koff),
+ voice2_fine_tune(d.voice2_fine_tune)
+{
+ adl[0] = ::adl[d.adlno1];
+ adl[1] = ::adl[d.adlno2];
+}
+
+/**
+ * @brief Convert external instrument to internal instrument
+ */
+void cvt_ADLI_to_FMIns(adlinsdata2 &dst, const struct ADL_Instrument &src);
+
+/**
+ * @brief Convert internal instrument to external instrument
+ */
+void cvt_FMIns_to_ADLI(struct ADL_Instrument &dst, const adlinsdata2 &src);
+
#endif //ADLDATA_H
diff --git a/src/adlmidi.cpp b/src/adlmidi.cpp
index bf03285..a0c7d8a 100644
--- a/src/adlmidi.cpp
+++ b/src/adlmidi.cpp
@@ -120,7 +120,7 @@ ADLMIDI_EXPORT int adl_setBank(ADL_MIDIPlayer *device, int bank)
if(static_cast<uint32_t>(bankno) >= NumBanks)
{
char errBuf[150];
- snprintf(errBuf, 150, "Embedded bank number may only be 0..%" PRIu32 "!\n", (NumBanks - 1));
+ snprintf(errBuf, 150, "Embedded bank number may only be 0..%u!\n", static_cast<unsigned int>(NumBanks - 1));
play->setErrorString(errBuf);
return -1;
}
@@ -143,6 +143,142 @@ ADLMIDI_EXPORT const char *const *adl_getBankNames()
return banknames;
}
+ADLMIDI_EXPORT int adl_reserveBanks(ADL_MIDIPlayer *device, unsigned banks)
+{
+ if(!device)
+ return -1;
+ MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
+ OPL3::BankMap &map = play->opl.dynamic_banks;
+ map.reserve(banks);
+ return (int)map.capacity();
+}
+
+ADLMIDI_EXPORT int adl_getBank(ADL_MIDIPlayer *device, const ADL_BankId *idp, int flags, ADL_Bank *bank)
+{
+ if(!device || !idp || !bank)
+ return -1;
+
+ ADL_BankId id = *idp;
+ if(id.lsb > 127 || id.msb > 127 || id.percussive > 1)
+ return -1;
+ unsigned idnumber = (id.msb << 8) | id.lsb | (id.percussive ? OPL3::PercussionTag : 0);
+
+ MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
+ OPL3::BankMap &map = play->opl.dynamic_banks;
+
+ OPL3::BankMap::iterator it;
+ if(!(flags & ADLMIDI_Bank_Create))
+ {
+ it = map.find(idnumber);
+ if(it == map.end())
+ return -1;
+ }
+ else
+ {
+ std::pair<uint16_t, OPL3::Bank> value;
+ value.first = idnumber;
+ memset(&value.second, 0, sizeof(value.second));
+ for (unsigned i = 0; i < 128; ++i)
+ value.second.ins[i].flags = adlinsdata::Flag_NoSound;
+
+ std::pair<OPL3::BankMap::iterator, bool> ir;
+ if(flags & ADLMIDI_Bank_CreateRt)
+ {
+ ir = map.insert(value, OPL3::BankMap::do_not_expand_t());
+ if(ir.first == map.end())
+ return -1;
+ }
+ else
+ ir = map.insert(value);
+ it = ir.first;
+ }
+
+ it.to_ptrs(bank->pointer);
+ return 0;
+}
+
+ADLMIDI_EXPORT int adl_getBankId(ADL_MIDIPlayer *device, const ADL_Bank *bank, ADL_BankId *id)
+{
+ if(!device || !bank)
+ return -1;
+
+ OPL3::BankMap::iterator it = OPL3::BankMap::iterator::from_ptrs(bank->pointer);
+ unsigned idnumber = it->first;
+ id->msb = (idnumber >> 8) & 127;
+ id->lsb = idnumber & 127;
+ id->percussive = (idnumber & OPL3::PercussionTag) ? 1 : 0;
+ return 0;
+}
+
+ADLMIDI_EXPORT int adl_removeBank(ADL_MIDIPlayer *device, ADL_Bank *bank)
+{
+ if(!device || !bank)
+ return -1;
+
+ MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
+ OPL3::BankMap &map = play->opl.dynamic_banks;
+ OPL3::BankMap::iterator it = OPL3::BankMap::iterator::from_ptrs(bank->pointer);
+ size_t size = map.size();
+ map.erase(it);
+ return (map.size() != size) ? 0 : -1;
+}
+
+ADLMIDI_EXPORT int adl_getFirstBank(ADL_MIDIPlayer *device, ADL_Bank *bank)
+{
+ if(!device)
+ return -1;
+
+ MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
+ OPL3::BankMap &map = play->opl.dynamic_banks;
+
+ OPL3::BankMap::iterator it = map.begin();
+ if(it == map.end())
+ return -1;
+
+ it.to_ptrs(bank->pointer);
+ return 0;
+}
+
+ADLMIDI_EXPORT int adl_getNextBank(ADL_MIDIPlayer *device, ADL_Bank *bank)
+{
+ if(!device)
+ return -1;
+
+ MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
+ OPL3::BankMap &map = play->opl.dynamic_banks;
+
+ OPL3::BankMap::iterator it = OPL3::BankMap::iterator::from_ptrs(bank->pointer);
+ if(++it == map.end())
+ return -1;
+
+ it.to_ptrs(bank->pointer);
+ return 0;
+}
+
+ADLMIDI_EXPORT int adl_getInstrument(ADL_MIDIPlayer *device, const ADL_Bank *bank, unsigned index, ADL_Instrument *ins)
+{
+ if(!device || !bank || index > 127 || !ins)
+ return 1;
+
+ OPL3::BankMap::iterator it = OPL3::BankMap::iterator::from_ptrs(bank->pointer);
+ cvt_FMIns_to_ADLI(*ins, it->second.ins[index]);
+ ins->version = 0;
+ return 0;
+}
+
+ADLMIDI_EXPORT int adl_setInstrument(ADL_MIDIPlayer *device, ADL_Bank *bank, unsigned index, const ADL_Instrument *ins)
+{
+ if(!device || !bank || index > 127 || !ins)
+ return 1;
+
+ if(ins->version != 0)
+ return 1;
+
+ OPL3::BankMap::iterator it = OPL3::BankMap::iterator::from_ptrs(bank->pointer);
+ cvt_ADLI_to_FMIns(it->second.ins[index], *ins);
+ return 0;
+}
+
ADLMIDI_EXPORT int adl_setNumFourOpsChn(ADL_MIDIPlayer *device, int ops4)
{
if(!device)
@@ -177,7 +313,9 @@ ADLMIDI_EXPORT void adl_setPercMode(ADL_MIDIPlayer *device, int percmod)
if(!device) return;
MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
play->m_setup.AdlPercussionMode = percmod;
- play->opl.AdlPercussionMode = play->m_setup.AdlPercussionMode;
+ play->opl.AdlPercussionMode = play->m_setup.AdlPercussionMode < 0 ?
+ play->opl.dynamic_bank_setup.adLibPercussions :
+ (play->m_setup.AdlPercussionMode != 0);
play->opl.updateFlags();
}
@@ -186,7 +324,9 @@ ADLMIDI_EXPORT void adl_setHVibrato(ADL_MIDIPlayer *device, int hvibro)
if(!device) return;
MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
play->m_setup.HighVibratoMode = hvibro;
- play->opl.HighVibratoMode = play->m_setup.HighVibratoMode;
+ play->opl.HighVibratoMode = play->m_setup.HighVibratoMode < 0 ?
+ play->opl.dynamic_bank_setup.deepVibrato :
+ (play->m_setup.HighVibratoMode != 0);
play->opl.updateDeepFlags();
}
@@ -195,7 +335,9 @@ ADLMIDI_EXPORT void adl_setHTremolo(ADL_MIDIPlayer *device, int htremo)
if(!device) return;
MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
play->m_setup.HighTremoloMode = htremo;
- play->opl.HighTremoloMode = play->m_setup.HighTremoloMode;
+ play->opl.HighTremoloMode = play->m_setup.HighTremoloMode < 0 ?
+ play->opl.dynamic_bank_setup.deepTremolo :
+ (play->m_setup.HighTremoloMode != 0);
play->opl.updateDeepFlags();
}
@@ -204,14 +346,16 @@ ADLMIDI_EXPORT void adl_setScaleModulators(ADL_MIDIPlayer *device, int smod)
if(!device) return;
MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
play->m_setup.ScaleModulators = smod;
- play->opl.ScaleModulators = play->m_setup.ScaleModulators;
+ play->opl.ScaleModulators = play->m_setup.ScaleModulators < 0 ?
+ play->opl.dynamic_bank_setup.scaleModulators :
+ (play->m_setup.ScaleModulators != 0);
}
ADLMIDI_EXPORT void adl_setFullRangeBrightness(struct ADL_MIDIPlayer *device, int fr_brightness)
{
if(!device) return;
MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
- play->m_setup.fullRangeBrightnessCC74 = fr_brightness;
+ play->m_setup.fullRangeBrightnessCC74 = (fr_brightness != 0);
}
ADLMIDI_EXPORT void adl_setLoopEnabled(ADL_MIDIPlayer *device, int loopEn)
@@ -221,12 +365,16 @@ ADLMIDI_EXPORT void adl_setLoopEnabled(ADL_MIDIPlayer *device, int loopEn)
play->m_setup.loopingIsEnabled = (loopEn != 0);
}
+/* !!!DEPRECATED!!! */
ADLMIDI_EXPORT void adl_setLogarithmicVolumes(struct ADL_MIDIPlayer *device, int logvol)
{
if(!device) return;
MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
- play->m_setup.LogarithmicVolumes = logvol;
- play->opl.LogarithmicVolumes = play->m_setup.LogarithmicVolumes;
+ play->m_setup.LogarithmicVolumes = (logvol != 0);
+ if(play->m_setup.LogarithmicVolumes)
+ play->opl.ChangeVolumeRangesModel(ADLMIDI_VolumeModel_NativeOPL3);
+ else
+ play->opl.ChangeVolumeRangesModel(static_cast<ADLMIDI_VolumeModels>(play->opl.m_volumeScale));
}
ADLMIDI_EXPORT void adl_setVolumeRangeModel(struct ADL_MIDIPlayer *device, int volumeModel)
@@ -234,7 +382,10 @@ ADLMIDI_EXPORT void adl_setVolumeRangeModel(struct ADL_MIDIPlayer *device, int v
if(!device) return;
MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
play->m_setup.VolumeModel = volumeModel;
- play->opl.ChangeVolumeRangesModel(static_cast<ADLMIDI_VolumeModels>(volumeModel));
+ if(play->m_setup.VolumeModel == ADLMIDI_VolumeModel_AUTO)//Use bank default volume model
+ play->opl.m_volumeScale = (OPL3::VolumesScale)play->opl.dynamic_bank_setup.volumeModel;
+ else
+ play->opl.ChangeVolumeRangesModel(static_cast<ADLMIDI_VolumeModels>(volumeModel));
}
ADLMIDI_EXPORT int adl_openBankFile(struct ADL_MIDIPlayer *device, const char *filePath)
@@ -367,7 +518,11 @@ ADLMIDI_EXPORT int adl_switchEmulator(struct ADL_MIDIPlayer *device, int emulato
ADLMIDI_EXPORT const char *adl_linkedLibraryVersion()
{
+#if !defined(ADLMIDI_ENABLE_HQ_RESAMPLER)
return ADLMIDI_VERSION;
+#else
+ return ADLMIDI_VERSION " (HQ)";
+#endif
}
ADLMIDI_EXPORT const ADL_Version *adl_linkedVersion()
@@ -421,7 +576,7 @@ ADLMIDI_EXPORT void adl_reset(struct ADL_MIDIPlayer *device)
play->m_setup.tick_skip_samples_delay = 0;
play->opl.Reset(play->m_setup.emulator, play->m_setup.PCM_RATE);
play->ch.clear();
- play->ch.resize(play->opl.NumChannels);
+ play->ch.resize((size_t)play->opl.NumChannels);
}
ADLMIDI_EXPORT double adl_totalTimeLength(struct ADL_MIDIPlayer *device)
@@ -614,7 +769,7 @@ ADLMIDI_EXPORT void adl_setDebugMessageHook(struct ADL_MIDIPlayer *device, ADL_D
play->hooks.onDebugMessage_userData = userData;
}
-
+#ifndef ADLMIDI_HW_OPL
template <class Dst>
static void CopySamplesRaw(ADL_UInt8 *dstLeft, ADL_UInt8 *dstRight, const int32_t *src,
size_t frameCount, unsigned sampleOffset)
@@ -659,6 +814,8 @@ static int SendStereoAudio(int samples_requested,
right += (outputOffset / 2) * sampleOffset;
typedef int32_t(&pfnConvert)(int32_t);
+ typedef float(&ffnConvert)(int32_t);
+ typedef double(&dfnConvert)(int32_t);
switch(sampleType) {
case ADLMIDI_SampleType_S8:
@@ -723,22 +880,28 @@ static int SendStereoAudio(int samples_requested,
break;
}
case ADLMIDI_SampleType_F32:
+ {
if(containerSize != sizeof(float))
return -1;
- CopySamplesTransformed<float>(left, right, _in, toCopy / 2, sampleOffset, adl_cvtReal<float>);
+ ffnConvert cvt = adl_cvtReal<float>;
+ CopySamplesTransformed<float>(left, right, _in, toCopy / 2, sampleOffset, cvt);
break;
+ }
case ADLMIDI_SampleType_F64:
+ {
if(containerSize != sizeof(double))
return -1;
- CopySamplesTransformed<double>(left, right, _in, toCopy / 2, sampleOffset, adl_cvtReal<double>);
+ dfnConvert cvt = adl_cvtReal<double>;
+ CopySamplesTransformed<double>(left, right, _in, toCopy / 2, sampleOffset, cvt);
break;
+ }
default:
return -1;
}
return 0;
}
-
+#endif
ADLMIDI_EXPORT int adl_play(struct ADL_MIDIPlayer *device, int sampleCount, short *out)
{
diff --git a/src/adlmidi_bankmap.h b/src/adlmidi_bankmap.h
new file mode 100644
index 0000000..e4534cd
--- /dev/null
+++ b/src/adlmidi_bankmap.h
@@ -0,0 +1,127 @@
+/*
+ * libADLMIDI is a free MIDI to WAV conversion library with OPL3 emulation
+ *
+ * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
+ * ADLMIDI Library API: Copyright (c) 2015-2018 Vitaly Novichkov <admin@wohlnet.ru>
+ *
+ * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
+ * http://iki.fi/bisqwit/source/adlmidi.html
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ADLMIDI_BANKMAP_H
+#define ADLMIDI_BANKMAP_H
+
+#include <list>
+#include <utility>
+#include <stdint.h>
+#include <stddef.h>
+
+#include "adlmidi_ptr.hpp"
+
+/**
+ * A simple hash map which accepts bank numbers as keys, can be reserved to a
+ * fixed size, offers O(1) search and insertion, has a hash function to
+ * optimize for the worst case, and has some good cache locality properties.
+ */
+template <class T>
+class BasicBankMap
+{
+public:
+ typedef uint16_t key_type; /* the bank identifier */
+ typedef T mapped_type;
+ typedef std::pair<key_type, T> value_type;
+
+ BasicBankMap();
+ void reserve(size_t capacity);
+
+ size_t size() const
+ { return m_size; }
+ size_t capacity() const
+ { return m_capacity; }
+ bool empty() const
+ { return m_size == 0; }
+
+ class iterator;
+ iterator begin() const;
+ iterator end() const;
+
+ struct do_not_expand_t {};
+
+ iterator find(key_type key);
+ void erase(iterator it);
+ std::pair<iterator, bool> insert(const value_type &value);
+ std::pair<iterator, bool> insert(const value_type &value, do_not_expand_t);
+ void clear();
+
+ T &operator[](key_type key);
+
+private:
+ struct Slot;
+ enum { minimum_allocation = 4 };
+ enum
+ {
+ hash_bits = 8, /* worst case # of collisions: 128^2/2^hash_bits */
+ hash_buckets = 1 << hash_bits,
+ };
+
+public:
+ class iterator
+ {
+ public:
+ iterator();
+ value_type &operator*() const { return slot->value; }
+ value_type *operator->() const { return &slot->value; }
+ iterator &operator++();
+ bool operator==(const iterator &o) const;
+ bool operator!=(const iterator &o) const;
+ void to_ptrs(void *ptrs[3]);
+ static iterator from_ptrs(void *const ptrs[3]);
+ private:
+ Slot **buckets;
+ Slot *slot;
+ size_t index;
+ iterator(Slot **buckets, Slot *slot, size_t index);
+#ifdef _MSC_VER
+ template<class _T>
+ friend class BasicBankMap;
+#else
+ friend class BasicBankMap<T>;
+#endif
+ };
+
+private:
+ struct Slot {
+ Slot *next, *prev;
+ value_type value;
+ Slot() : next(NULL), prev(NULL) {}
+ };
+ AdlMIDI_SPtrArray<Slot *> m_buckets;
+ std::list< AdlMIDI_SPtrArray<Slot> > m_allocations;
+ Slot *m_freeslots;
+ size_t m_size;
+ size_t m_capacity;
+ static size_t hash(key_type key);
+ Slot *allocate_slot();
+ Slot *ensure_allocate_slot();
+ void free_slot(Slot *slot);
+ Slot *bucket_find(size_t index, key_type key);
+ void bucket_add(size_t index, Slot *slot);
+ void bucket_remove(size_t index, Slot *slot);
+};
+
+#include "adlmidi_bankmap.tcc"
+
+#endif // ADLMIDI_BANKMAP_H
diff --git a/src/adlmidi_bankmap.tcc b/src/adlmidi_bankmap.tcc
new file mode 100644
index 0000000..76e7001
--- /dev/null
+++ b/src/adlmidi_bankmap.tcc
@@ -0,0 +1,283 @@
+/*
+ * libADLMIDI is a free MIDI to WAV conversion library with OPL3 emulation
+ *
+ * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
+ * ADLMIDI Library API: Copyright (c) 2015-2018 Vitaly Novichkov <admin@wohlnet.ru>
+ *
+ * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
+ * http://iki.fi/bisqwit/source/adlmidi.html
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "adlmidi_bankmap.h"
+#include <cassert>
+
+template <class T>
+inline BasicBankMap<T>::BasicBankMap()
+ : m_freeslots(NULL),
+ m_size(0),
+ m_capacity(0)
+{
+ m_buckets.reset(new Slot *[hash_buckets]());
+}
+
+template <class T>
+inline size_t BasicBankMap<T>::hash(key_type key)
+{
+ // disregard the 0 high bit in LSB
+ key = (key & 127) | ((key >> 8) << 7);
+ // take low part as hash value
+ return key & (hash_buckets - 1);
+}
+
+template <class T>
+void BasicBankMap<T>::reserve(size_t capacity)
+{
+ if(m_capacity >= capacity)
+ return;
+
+ size_t need = capacity - m_capacity;
+ const size_t minalloc = static_cast<size_t>(minimum_allocation);
+ need = (need < minalloc) ? minalloc : need;
+
+ AdlMIDI_SPtrArray<Slot> slotz;
+ slotz.reset(new Slot[need]);
+ m_allocations.push_back(slotz);
+ m_capacity += need;
+
+ for(size_t i = need; i-- > 0;)
+ free_slot(&slotz[i]);
+}
+
+template <class T>
+typename BasicBankMap<T>::iterator
+BasicBankMap<T>::begin() const
+{
+ iterator it(m_buckets.get(), NULL, 0);
+ while(it.index < hash_buckets && !(it.slot = m_buckets[it.index]))
+ ++it.index;
+ return it;
+}
+
+template <class T>
+typename BasicBankMap<T>::iterator
+BasicBankMap<T>::end() const
+{
+ iterator it(m_buckets.get(), NULL, hash_buckets);
+ return it;
+}
+
+template <class T>
+typename BasicBankMap<T>::iterator BasicBankMap<T>::find(key_type key)
+{
+ size_t index = hash(key);
+ Slot *slot = bucket_find(index, key);
+ if(!slot)
+ return end();
+ return iterator(m_buckets.get(), slot, index);
+}
+
+template <class T>
+void BasicBankMap<T>::erase(iterator it)
+{
+ bucket_remove(it.index, it.slot);
+ free_slot(it.slot);
+ --m_size;
+}
+
+template <class T>
+inline BasicBankMap<T>::iterator::iterator()
+ : buckets(NULL), slot(NULL), index(0)
+{
+}
+
+template <class T>
+inline BasicBankMap<T>::iterator::iterator(Slot **buckets, Slot *slot, size_t index)
+ : buckets(buckets), slot(slot), index(index)
+{
+}
+
+template <class T>
+typename BasicBankMap<T>::iterator &
+BasicBankMap<T>::iterator::operator++()
+{
+ if(slot->next)
+ slot = slot->next;
+ else {
+ Slot *slot = NULL;
+ ++index;
+ while(index < hash_buckets && !(slot = buckets[index]))
+ ++index;
+ this->slot = slot;
+ }
+ return *this;
+}
+
+template <class T>
+bool BasicBankMap<T>::iterator::operator==(const iterator &o) const
+{
+ return buckets == o.buckets && slot == o.slot && index == o.index;
+}
+
+template <class T>
+inline bool BasicBankMap<T>::iterator::operator!=(const iterator &o) const
+{
+ return !operator==(o);
+}
+
+template <class T>
+void BasicBankMap<T>::iterator::to_ptrs(void *ptrs[3])
+{
+ ptrs[0] = buckets;
+ ptrs[1] = slot;
+ ptrs[2] = (void *)index;
+}
+
+template <class T>
+typename BasicBankMap<T>::iterator
+BasicBankMap<T>::iterator::from_ptrs(void *const ptrs[3])
+{
+ iterator it;
+ it.buckets = (Slot **)ptrs[0];
+ it.slot = (Slot *)ptrs[1];
+ it.index = (size_t)ptrs[2];
+ return it;
+}
+
+template <class T>
+std::pair<typename BasicBankMap<T>::iterator, bool>
+BasicBankMap<T>::insert(const value_type &value)
+{
+ size_t index = hash(value.first);
+ Slot *slot = bucket_find(index, value.first);
+ if(slot)
+ return std::make_pair(iterator(m_buckets.get(), slot, index), false);
+ slot = allocate_slot();
+ if(!slot) {
+ reserve(m_capacity + minimum_allocation);
+ slot = ensure_allocate_slot();
+ }
+ slot->value = value;
+ bucket_add(index, slot);
+ ++m_size;
+ return std::make_pair(iterator(m_buckets.get(), slot, index), true);
+}
+
+template <class T>
+std::pair<typename BasicBankMap<T>::iterator, bool>
+BasicBankMap<T>::insert(const value_type &value, do_not_expand_t)
+{
+ size_t index = hash(value.first);
+ Slot *slot = bucket_find(index, value.first);
+ if(slot)
+ return std::make_pair(iterator(m_buckets.get(), slot, index), false);
+ slot = allocate_slot();
+ if(!slot)
+ return std::make_pair(end(), false);
+ slot->value = value;
+ bucket_add(index, slot);
+ ++m_size;
+ return std::make_pair(iterator(m_buckets.get(), slot, index), true);
+}
+
+template <class T>
+void BasicBankMap<T>::clear()
+{
+ for(size_t i = 0; i < hash_buckets; ++i) {
+ Slot *slot = m_buckets[i];
+ while (Slot *cur = slot) {
+ slot = slot->next;
+ free_slot(cur);
+ }
+ m_buckets[i] = NULL;
+ }
+ m_size = 0;
+}
+
+template <class T>
+inline T &BasicBankMap<T>::operator[](key_type key)
+{
+ return insert(value_type(key, T())).first->second;
+}
+
+template <class T>
+typename BasicBankMap<T>::Slot *
+BasicBankMap<T>::allocate_slot()
+{
+ Slot *slot = m_freeslots;
+ if(!slot)
+ return NULL;
+ Slot *next = slot->next;
+ if(next)
+ next->prev = NULL;
+ m_freeslots = next;
+ return slot;
+}
+
+template <class T>
+inline typename BasicBankMap<T>::Slot *
+BasicBankMap<T>::ensure_allocate_slot()
+{
+ Slot *slot = allocate_slot();
+ assert(slot);
+ return slot;
+}
+
+template <class T>
+void BasicBankMap<T>::free_slot(Slot *slot)
+{
+ Slot *next = m_freeslots;
+ if(next)
+ next->prev = slot;
+ slot->prev = NULL;
+ slot->next = next;
+ m_freeslots = slot;
+ m_freeslots->value.second = T();
+}
+
+template <class T>
+typename BasicBankMap<T>::Slot *
+BasicBankMap<T>::bucket_find(size_t index, key_type key)
+{
+ Slot *slot = m_buckets[index];
+ while(slot && slot->value.first != key)
+ slot = slot->next;
+ return slot;
+}
+
+template <class T>
+void BasicBankMap<T>::bucket_add(size_t index, Slot *slot)
+{
+ assert(slot);
+ Slot *next = m_buckets[index];
+ if(next)
+ next->prev = slot;
+ slot->next = next;
+ m_buckets[index] = slot;
+}
+
+template <class T>
+void BasicBankMap<T>::bucket_remove(size_t index, Slot *slot)
+{
+ assert(slot);
+ Slot *prev = slot->prev;
+ Slot *next = slot->next;
+ if(!prev)
+ m_buckets[index] = next;
+ else
+ prev->next = next;
+ if(next)
+ next->prev = prev;
+}
diff --git a/src/adlmidi_load.cpp b/src/adlmidi_load.cpp
index 703f34a..9e19ab6 100644
--- a/src/adlmidi_load.cpp
+++ b/src/adlmidi_load.cpp
@@ -72,65 +72,128 @@ bool MIDIplay::LoadBank(const void *data, size_t size)
return LoadBank(file);
}
-
-struct WOPL_Inst
-{
- bool fourOps;
- char padding[7];
- struct adlinsdata adlins;
- struct adldata op[2];
- uint16_t ms_sound_kon;
- uint16_t ms_sound_koff;
-};
-
-static void cvt_WOPLI_to_FMIns(WOPL_Inst &ins, WOPLInstrument &in)
+template <class WOPLI>
+static void cvt_generic_to_FMIns(adlinsdata2 &ins, const WOPLI &in)
{
- ins.op[0].finetune = in.note_offset1;
- ins.op[1].finetune = in.note_offset2;
-
- ins.adlins.voice2_fine_tune = 0.0;
+ ins.voice2_fine_tune = 0.0;
int8_t voice2_fine_tune = in.second_voice_detune;
if(voice2_fine_tune != 0)
{
if(voice2_fine_tune == 1)
- ins.adlins.voice2_fine_tune = 0.000025;
+ ins.voice2_fine_tune = 0.000025;
else if(voice2_fine_tune == -1)
- ins.adlins.voice2_fine_tune = -0.000025;
+ ins.voice2_fine_tune = -0.000025;
else
- ins.adlins.voice2_fine_tune = ((voice2_fine_tune * 15.625) / 1000.0);
+ ins.voice2_fine_tune = voice2_fine_tune * (15.625 / 1000.0);
}
- ins.adlins.tone = in.percussion_key_number;
+ ins.tone = in.percussion_key_number;
+ ins.flags = (in.inst_flags & WOPL_Ins_4op) && (in.inst_flags & WOPL_Ins_Pseudo4op) ? adlinsdata::Flag_Pseudo4op : 0;
+ ins.flags|= (in.inst_flags & WOPL_Ins_4op) && ((in.inst_flags & WOPL_Ins_Pseudo4op) == 0) ? adlinsdata::Flag_Real4op : 0;
+ ins.flags|= (in.inst_flags & WOPL_Ins_IsBlank) ? adlinsdata::Flag_NoSound : 0;
- ins.adlins.flags = (in.inst_flags & WOPL_Ins_4op) && (in.inst_flags & WOPL_Ins_Pseudo4op) ? adlinsdata::Flag_Pseudo4op : 0;
- ins.adlins.flags|= (in.inst_flags & WOPL_Ins_IsBlank) ? adlinsdata::Flag_NoSound : 0;
- ins.fourOps = (in.inst_flags & WOPL_Ins_4op) || (in.inst_flags & WOPL_Ins_Pseudo4op);
-
- ins.op[0].feedconn = in.fb_conn1_C0;
- ins.op[1].feedconn = in.fb_conn2_C0;
-
- for(size_t op = 0, slt = 0; op < 4; op++, slt++)
+ bool fourOps = (in.inst_flags & WOPL_Ins_4op) || (in.inst_flags & WOPL_Ins_Pseudo4op);
+ for(size_t op = 0, slt = 0; op < static_cast<size_t>(fourOps ? 4 : 2); op++, slt++)
{
- ins.op[slt].carrier_E862 =
+ ins.adl[slt].carrier_E862 =
((static_cast<uint32_t>(in.operators[op].waveform_E0) << 24) & 0xFF000000) //WaveForm
| ((static_cast<uint32_t>(in.operators[op].susrel_80) << 16) & 0x00FF0000) //SusRel
| ((static_cast<uint32_t>(in.operators[op].atdec_60) << 8) & 0x0000FF00) //AtDec
| ((static_cast<uint32_t>(in.operators[op].avekf_20) << 0) & 0x000000FF); //AVEKM
- ins.op[slt].carrier_40 = in.operators[op].ksl_l_40;//KSLL
+ ins.adl[slt].carrier_40 = in.operators[op].ksl_l_40;//KSLL
op++;
- ins.op[slt].modulator_E862 =
+ ins.adl[slt].modulator_E862 =
((static_cast<uint32_t>(in.operators[op].waveform_E0) << 24) & 0xFF000000) //WaveForm
| ((static_cast<uint32_t>(in.operators[op].susrel_80) << 16) & 0x00FF0000) //SusRel
| ((static_cast<uint32_t>(in.operators[op].atdec_60) << 8) & 0x0000FF00) //AtDec
| ((static_cast<uint32_t>(in.operators[op].avekf_20) << 0) & 0x000000FF); //AVEKM
- ins.op[slt].modulator_40 = in.operators[op].ksl_l_40;//KSLL
+ ins.adl[slt].modulator_40 = in.operators[op].ksl_l_40;//KSLL
+ }
+
+ ins.adl[0].finetune = static_cast<int8_t>(in.note_offset1);
+ ins.adl[0].feedconn = in.fb_conn1_C0;
+ if(!fourOps)
+ ins.adl[1] = ins.adl[0];
+ else
+ {
+ ins.adl[1].finetune = static_cast<int8_t>(in.note_offset2);
+ ins.adl[1].feedconn = in.fb_conn2_C0;
}
ins.ms_sound_kon = in.delay_on_ms;
ins.ms_sound_koff = in.delay_off_ms;
}
+template <class WOPLI>
+static void cvt_FMIns_to_generic(WOPLI &ins, const adlinsdata2 &in)
+{
+ ins.second_voice_detune = 0;
+ double voice2_fine_tune = in.voice2_fine_tune;
+ if(voice2_fine_tune != 0)
+ {
+ if(voice2_fine_tune > 0 && voice2_fine_tune <= 0.000025)
+ ins.second_voice_detune = 1;
+ else if(voice2_fine_tune < 0 && voice2_fine_tune >= -0.000025)
+ ins.second_voice_detune = -1;
+ else
+ {
+ long value = lround(voice2_fine_tune * (1000.0 / 15.625));
+ value = (value < -128) ? -128 : value;
+ value = (value > +127) ? +127 : value;
+ ins.second_voice_detune = static_cast<int8_t>(value);
+ }
+ }
+
+ ins.percussion_key_number = in.tone;
+ bool fourOps = (in.flags & adlinsdata::Flag_Pseudo4op) || in.adl[0] != in.adl[1];
+ ins.inst_flags = fourOps ? WOPL_Ins_4op : 0;
+ ins.inst_flags|= (in.flags & adlinsdata::Flag_Pseudo4op) ? WOPL_Ins_Pseudo4op : 0;
+ ins.inst_flags|= (in.flags & adlinsdata::Flag_NoSound) ? WOPL_Ins_IsBlank : 0;
+
+ for(size_t op = 0, slt = 0; op < static_cast<size_t>(fourOps ? 4 : 2); op++, slt++)
+ {
+ ins.operators[op].waveform_E0 = static_cast<uint8_t>(in.adl[slt].carrier_E862 >> 24);
+ ins.operators[op].susrel_80 = static_cast<uint8_t>(in.adl[slt].carrier_E862 >> 16);
+ ins.operators[op].atdec_60 = static_cast<uint8_t>(in.adl[slt].carrier_E862 >> 8);
+ ins.operators[op].avekf_20 = static_cast<uint8_t>(in.adl[slt].carrier_E862 >> 0);
+ ins.operators[op].ksl_l_40 = in.adl[slt].carrier_40;
+
+ op++;
+ ins.operators[op].waveform_E0 = static_cast<uint8_t>(in.adl[slt].carrier_E862 >> 24);
+ ins.operators[op].susrel_80 = static_cast<uint8_t>(in.adl[slt].carrier_E862 >> 16);
+ ins.operators[op].atdec_60 = static_cast<uint8_t>(in.adl[slt].carrier_E862 >> 8);
+ ins.operators[op].avekf_20 = static_cast<uint8_t>(in.adl[slt].carrier_E862 >> 0);
+ ins.operators[op].ksl_l_40 = in.adl[slt].carrier_40;
+ }
+
+ ins.note_offset1 = in.adl[0].finetune;
+ ins.fb_conn1_C0 = in.adl[0].feedconn;
+ if(!fourOps)
+ {
+ ins.operators[2] = ins.operators[0];
+ ins.operators[3] = ins.operators[1];
+ }
+ else
+ {
+ ins.note_offset2 = in.adl[1].finetune;
+ ins.fb_conn2_C0 = in.adl[1].feedconn;
+ }
+
+ ins.delay_on_ms = in.ms_sound_kon;
+ ins.delay_off_ms = in.ms_sound_koff;
+}
+
+void cvt_ADLI_to_FMIns(adlinsdata2 &ins, const ADL_Instrument &in)
+{
+ return cvt_generic_to_FMIns(ins, in);
+}
+
+void cvt_FMIns_to_ADLI(ADL_Instrument &ins, const adlinsdata2 &in)
+{
+ cvt_FMIns_to_generic(ins, in);
+}
+
bool MIDIplay::LoadBank(MIDIplay::fileReader &fr)
{
int err = 0;
@@ -187,54 +250,41 @@ bool MIDIplay::LoadBank(MIDIplay::fileReader &fr)
}
}
- m_setup.HighTremoloMode = (wopl->opl_flags & WOPL_FLAG_DEEP_TREMOLO) != 0;
- m_setup.HighVibratoMode = (wopl->opl_flags & WOPL_FLAG_DEEP_VIBRATO) != 0;
- m_setup.VolumeModel = wopl->volume_model;
-
- /* TODO: Avoid memory reallocation in nearest future! */
- opl.dynamic_melodic_banks.clear();
- opl.dynamic_percussion_banks.clear();
+ opl.dynamic_bank_setup.adLibPercussions = false;
+ opl.dynamic_bank_setup.scaleModulators = false;
+ opl.dynamic_bank_setup.deepTremolo = (wopl->opl_flags & WOPL_FLAG_DEEP_TREMOLO) != 0;
+ opl.dynamic_bank_setup.deepVibrato = (wopl->opl_flags & WOPL_FLAG_DEEP_VIBRATO) != 0;
+ opl.dynamic_bank_setup.volumeModel = wopl->volume_model;
+ m_setup.HighTremoloMode = -1;
+ m_setup.HighVibratoMode = -1;
+ m_setup.VolumeModel = ADLMIDI_VolumeModel_AUTO;
opl.setEmbeddedBank(m_setup.AdlBank);
- OPL3::BankMap *slots_banks[2] = { &opl.dynamic_melodic_banks, &opl.dynamic_percussion_banks};
uint16_t slots_counts[2] = {wopl->banks_count_melodic, wopl->banks_count_percussion};
WOPLBank *slots_src_ins[2] = { wopl->banks_melodic, wopl->banks_percussive };
- for(int ss = 0; ss < 2; ss++)
+ for(unsigned ss = 0; ss < 2; ss++)
{
- for(int i = 0; i < slots_counts[ss]; i++)
+ for(unsigned i = 0; i < slots_counts[ss]; i++)
{
- uint16_t bank = (slots_src_ins[ss][i].bank_midi_msb * 256) + slots_src_ins[ss][i].bank_midi_lsb;
- size_t offset = slots_banks[ss]->size();
- (*slots_banks[ss])[bank] = offset;
-
+ unsigned bankno =
+ (slots_src_ins[ss][i].bank_midi_msb * 256) +
+ slots_src_ins[ss][i].bank_midi_lsb +
+ (ss ? OPL3::PercussionTag : 0);
+ OPL3::Bank &bank = opl.dynamic_banks[bankno];
for(int j = 0; j < 128; j++)
{
- WOPL_Inst ins;
- std::memset(&ins, 0, sizeof(WOPL_Inst));
+ adlinsdata2 &ins = bank.ins[j];
+ std::memset(&ins, 0, sizeof(adlinsdata2));
WOPLInstrument &inIns = slots_src_ins[ss][i].ins[j];
-
- cvt_WOPLI_to_FMIns(ins, inIns);
-
- ins.adlins.ms_sound_kon = ins.ms_sound_kon;
- ins.adlins.ms_sound_koff = ins.ms_sound_koff;
- ins.adlins.adlno1 = static_cast<uint16_t>(opl.dynamic_instruments.size() | opl.DynamicInstrumentTag);
- opl.dynamic_instruments.push_back(ins.op[0]);
- ins.adlins.adlno2 = ins.adlins.adlno1;
- if(ins.fourOps)
- {
- ins.adlins.adlno2 = static_cast<uint16_t>(opl.dynamic_instruments.size() | opl.DynamicInstrumentTag);
- opl.dynamic_instruments.push_back(ins.op[1]);
- }
- opl.dynamic_metainstruments.push_back(ins.adlins);
+ cvt_generic_to_FMIns(ins, inIns);
}
}
}
opl.AdlBank = ~0u; // Use dynamic banks!
//Percussion offset is count of instruments multipled to count of melodic banks
- opl.dynamic_percussion_offset = 128 * wopl->banks_count_melodic;
applySetup();
WOPL_Free(wopl);
@@ -268,7 +318,7 @@ bool MIDIplay::LoadMIDI(MIDIplay::fileReader &fr)
errorString.clear();
#ifdef DISABLE_EMBEDDED_BANKS
- if((opl.AdlBank != ~0u) || (opl.dynamic_metainstruments.size() < 256))
+ if((opl.AdlBank != ~0u) || opl.dynamic_banks.empty())
{
errorStringOut = "Bank is not set! Please load any instruments bank by using of adl_openBankFile() or adl_openBankData() functions!";
return false;
@@ -392,8 +442,7 @@ riffskip:
#endif //ADLMIDI_DISABLE_XMI_SUPPORT
else if(std::memcmp(HeaderBuf, "CTMF", 4) == 0)
{
- opl.dynamic_instruments.clear();
- opl.dynamic_metainstruments.clear();
+ opl.dynamic_banks.clear();
// Creative Music Format (CMF).
// When playing CTMF files, use the following commandline:
// adlmidi song8.ctmf -p -v 1 1 0
@@ -415,13 +464,19 @@ riffskip:
//std::printf("%u instruments\n", ins_count);
for(unsigned i = 0; i < ins_count; ++i)
{
+ unsigned bank = i / 256;
+ bank = (bank & 127) + ((bank >> 7) << 8);
+ if(bank > 127 + (127 << 8))
+ break;
+ bank += (i % 256 < 128) ? 0 : OPL3::PercussionTag;
+
unsigned char InsData[16];
fr.read(InsData, 1, 16);
/*std::printf("Ins %3u: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
i, InsData[0],InsData[1],InsData[2],InsData[3], InsData[4],InsData[5],InsData[6],InsData[7],
InsData[8],InsData[9],InsData[10],InsData[11], InsData[12],InsData[13],InsData[14],InsData[15]);*/
- struct adldata adl;
- struct adlinsdata adlins;
+ adlinsdata2 &adlins = opl.dynamic_banks[bank].ins[i % 128];
+ adldata adl;
adl.modulator_E862 =
((static_cast<uint32_t>(InsData[8] & 0x07) << 24) & 0xFF000000) //WaveForm
| ((static_cast<uint32_t>(InsData[6]) << 16) & 0x00FF0000) //Sustain/Release
@@ -436,15 +491,13 @@ riffskip:
adl.carrier_40 = InsData[3];
adl.feedconn = InsData[10] & 0x0F;
adl.finetune = 0;
- adlins.adlno1 = static_cast<uint16_t>(opl.dynamic_instruments.size() | opl.DynamicInstrumentTag);
- adlins.adlno2 = adlins.adlno1;
+ adlins.adl[0] = adl;
+ adlins.adl[1] = adl;
adlins.ms_sound_kon = 1000;
adlins.ms_sound_koff = 500;
adlins.tone = 0;
adlins.flags = 0;
adlins.voice2_fine_tune = 0.0;
- opl.dynamic_metainstruments.push_back(adlins);
- opl.dynamic_instruments.push_back(adl);
}
fr.seeku(mus_start, SEEK_SET);
@@ -452,10 +505,9 @@ riffskip:
DeltaTicks = (size_t)ticks;
opl.AdlBank = ~0u; // Ignore AdlBank number, use dynamic banks instead
//std::printf("CMF deltas %u ticks %u, basictempo = %u\n", deltas, ticks, basictempo);
- opl.LogarithmicVolumes = true;
opl.AdlPercussionMode = true;
opl.m_musicMode = OPL3::MODE_CMF;
- opl.m_volumeScale = OPL3::VOLUME_CMF;
+ opl.m_volumeScale = OPL3::VOLUME_NATIVE;
}
else
{
@@ -470,10 +522,9 @@ riffskip:
fr.seek(0x7D, SEEK_SET);
TrackCount = 1;
DeltaTicks = 60;
- opl.LogarithmicVolumes = true;
//opl.CartoonersVolumes = true;
opl.m_musicMode = OPL3::MODE_RSXX;
- opl.m_volumeScale = OPL3::VOLUME_CMF;
+ opl.m_volumeScale = OPL3::VOLUME_NATIVE;
}
}
@@ -531,11 +582,11 @@ riffskip:
TrackData.clear();
TrackData.resize(TrackCount, std::vector<uint8_t>());
- //CurrentPosition.track.clear();
- //CurrentPosition.track.resize(TrackCount);
InvDeltaTicks = fraction<uint64_t>(1, 1000000l * static_cast<uint64_t>(DeltaTicks));
- //Tempo = 1000000l * InvDeltaTicks;
- Tempo = fraction<uint64_t>(1, static_cast<uint64_t>(DeltaTicks));
+ if(is_CMF || is_RSXX)
+ Tempo = fraction<uint64_t>(1, static_cast<uint64_t>(DeltaTicks));
+ else
+ Tempo = fraction<uint64_t>(1, static_cast<uint64_t>(DeltaTicks) * 2);
static const unsigned char EndTag[4] = {0xFF, 0x2F, 0x00, 0x00};
size_t totalGotten = 0;
diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp
index 7c40fa0..0623ce7 100644
--- a/src/adlmidi_midiplay.cpp
+++ b/src/adlmidi_midiplay.cpp
@@ -25,7 +25,7 @@
// Mapping from MIDI volume level to OPL level value.
-static const uint32_t DMX_volume_mapping_table[] =
+static const uint8_t DMX_volume_mapping_table[128] =
{
0, 1, 3, 5, 6, 8, 10, 11,
13, 14, 16, 17, 19, 20, 22, 23,
@@ -43,23 +43,6 @@ static const uint32_t DMX_volume_mapping_table[] =
116, 117, 117, 118, 118, 119, 119, 120,
120, 121, 121, 122, 122, 123, 123, 123,
124, 124, 125, 125, 126, 126, 127, 127,
- //Protection entries to avoid crash if value more than 127
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
};
static const uint8_t W9X_volume_mapping_table[32] =
@@ -117,17 +100,16 @@ inline bool isXgPercChannel(uint8_t msb, uint8_t lsb)
void MIDIplay::AdlChannel::AddAge(int64_t ms)
{
+ const int64_t neg = static_cast<int64_t>(-0x1FFFFFFFl);
if(users_empty())
- koff_time_until_neglible =
- std::max(int64_t(koff_time_until_neglible - ms), static_cast<int64_t>(-0x1FFFFFFFl));
+ koff_time_until_neglible = std::max(int64_t(koff_time_until_neglible - ms), neg);
else
{
koff_time_until_neglible = 0;
-
for(LocationData *i = users_first; i; i = i->next)
{
- i->kon_time_until_neglible =
- std::max(i->kon_time_until_neglible - ms, static_cast<int64_t>(-0x1FFFFFFFl));
+ if(!i->fixed_sustain)
+ i->kon_time_until_neglible = std::max(i->kon_time_until_neglible - ms, neg);
i->vibdelay += ms;
}
}
@@ -222,7 +204,9 @@ void MIDIplay::MidiTrackRow::sortEvents(bool *noteStates)
j = noteOffs.erase(j);
markAsOn.erase(note_i);
continue;
- } else {
+ }
+ else
+ {
//When same row has many note-offs on same row
//that means a zero-length note follows previous note
//it must be shuted down
@@ -451,17 +435,17 @@ bool MIDIplay::buildTrackData()
if(track.empty())
continue;//Empty track is useless!
- #ifdef DEBUG_TIME_CALCULATION
+#ifdef DEBUG_TIME_CALCULATION
std::fprintf(stdout, "\n============Track %" PRIuPTR "=============\n", tk);
std::fflush(stdout);
- #endif
+#endif
MidiTrackRow *posPrev = &(*(track.begin()));//First element
for(MidiTrackQueue::iterator it = track.begin(); it != track.end(); it++)
{
- #ifdef DEBUG_TIME_CALCULATION
+#ifdef DEBUG_TIME_CALCULATION
bool tempoChanged = false;
- #endif
+#endif
MidiTrackRow &pos = *it;
if((posPrev != &pos) && //Skip first event
(!tempos.empty()) && //Only when in-track tempo events are available
@@ -507,9 +491,9 @@ bool MIDIplay::buildTrackData()
//Apply next tempo
currentTempo = points[j].tempo;
- #ifdef DEBUG_TIME_CALCULATION
+#ifdef DEBUG_TIME_CALCULATION
tempoChanged = true;
- #endif
+#endif
}
//Then calculate time between last tempo change point and end point
TempoChangePoint tailTempo = points.back();
@@ -552,10 +536,10 @@ bool MIDIplay::buildTrackData()
loopEndTime = pos.time;
}
- #ifdef DEBUG_TIME_CALCULATION
+#ifdef DEBUG_TIME_CALCULATION
std::fprintf(stdout, "= %10" PRId64 " = %10f%s\n", pos.absPos, pos.time, tempoChanged ? " <----TEMPO CHANGED" : "");
std::fflush(stdout);
- #endif
+#endif
abs_position += pos.delay;
posPrev = &pos;
@@ -575,7 +559,7 @@ bool MIDIplay::buildTrackData()
//Resolve "hell of all times" of too short drum notes:
//move too short percussion note-offs far far away as possible
/********************************************************************************/
- #if 1 //Use this to record WAVEs for comparison before/after implementing of this
+#if 1 //Use this to record WAVEs for comparison before/after implementing of this
if(opl.m_musicMode == OPL3::MODE_MIDI)//Percussion fix is needed for MIDI only, not for IMF/RSXX or CMF
{
//! Minimal real time in seconds
@@ -625,8 +609,8 @@ bool MIDIplay::buildTrackData()
}
bool percussion = (et->channel == 9) ||
- banks[et->channel] == 0x7E00 || //XG SFX1/SFX2 channel (16128 signed decimal)
- banks[et->channel] == 0x7F00; //XG Percussion channel (16256 signed decimal)
+ banks[et->channel] == 0x7E00 || //XG SFX1/SFX2 channel (16128 signed decimal)
+ banks[et->channel] == 0x7F00; //XG Percussion channel (16256 signed decimal)
if(!percussion)
continue;
@@ -687,7 +671,7 @@ bool MIDIplay::buildTrackData()
#undef DRUM_NOTE_MIN_TIME
#undef DRUM_NOTE_MIN_TICKS
}
- #endif
+#endif
return true;
}
@@ -695,7 +679,8 @@ bool MIDIplay::buildTrackData()
MIDIplay::MIDIplay(unsigned long sampleRate):
- cmf_percussion_mode(false)
+ cmf_percussion_mode(false),
+ m_arpeggioCounter(0)
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
, fullSongTimeLength(0.0),
postSongWaitDelay(1.0),
@@ -740,16 +725,28 @@ MIDIplay::MIDIplay(unsigned long sampleRate):
void MIDIplay::applySetup()
{
m_setup.tick_skip_samples_delay = 0;
- opl.HighTremoloMode = m_setup.HighTremoloMode == -1 ? adlbanksetup[m_setup.AdlBank].deepTremolo : (bool)m_setup.HighTremoloMode;
- opl.HighVibratoMode = m_setup.HighVibratoMode == -1 ? adlbanksetup[m_setup.AdlBank].deepVibrato : (bool)m_setup.HighVibratoMode;
- opl.AdlPercussionMode = m_setup.AdlPercussionMode == -1 ? adlbanksetup[m_setup.AdlBank].adLibPercussions : (bool)m_setup.AdlPercussionMode;
- opl.ScaleModulators = m_setup.ScaleModulators == -1 ? adlbanksetup[m_setup.AdlBank].scaleModulators : (bool)m_setup.ScaleModulators;
- opl.LogarithmicVolumes = m_setup.LogarithmicVolumes;
- //opl.CartoonersVolumes = false;
+
+ if(opl.AdlBank != ~0u)
+ opl.dynamic_bank_setup = adlbanksetup[m_setup.AdlBank];
+
+ opl.HighTremoloMode = m_setup.HighTremoloMode < 0 ?
+ opl.dynamic_bank_setup.deepTremolo :
+ (m_setup.HighTremoloMode != 0);
+ opl.HighVibratoMode = m_setup.HighVibratoMode < 0 ?
+ opl.dynamic_bank_setup.deepVibrato :
+ (m_setup.HighVibratoMode != 0);
+ opl.AdlPercussionMode = m_setup.AdlPercussionMode < 0 ?
+ opl.dynamic_bank_setup.adLibPercussions :
+ (m_setup.AdlPercussionMode != 0);
+ opl.ScaleModulators = m_setup.ScaleModulators < 0 ?
+ opl.dynamic_bank_setup.scaleModulators :
+ (m_setup.ScaleModulators != 0);
+ if(m_setup.LogarithmicVolumes)
+ opl.ChangeVolumeRangesModel(ADLMIDI_VolumeModel_NativeOPL3);
opl.m_musicMode = OPL3::MODE_MIDI;
opl.ChangeVolumeRangesModel(static_cast<ADLMIDI_VolumeModels>(m_setup.VolumeModel));
if(m_setup.VolumeModel == ADLMIDI_VolumeModel_AUTO)//Use bank default volume model
- opl.m_volumeScale = (OPL3::VolumesScale)adlbanksetup[m_setup.AdlBank].volumeModel;
+ opl.m_volumeScale = (OPL3::VolumesScale)opl.dynamic_bank_setup.volumeModel;
opl.NumCards = m_setup.NumCards;
opl.NumFourOps = m_setup.NumFourOps;
@@ -758,6 +755,9 @@ void MIDIplay::applySetup()
opl.Reset(m_setup.emulator, m_setup.PCM_RATE);
ch.clear();
ch.resize(opl.NumChannels);
+
+ // Reset the arpeggio counter
+ m_arpeggioCounter = 0;
}
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
@@ -796,9 +796,9 @@ uint64_t MIDIplay::ReadVarLenEx(uint8_t **ptr, uint8_t *end, bool &ok)
double MIDIplay::Tick(double s, double granularity)
{
s *= tempoMultiplier;
- #ifdef ENABLE_BEGIN_SILENCE_SKIPPING
+#ifdef ENABLE_BEGIN_SILENCE_SKIPPING
if(CurrentPositionNew.began)
- #endif
+#endif
CurrentPositionNew.wait -= s;
CurrentPositionNew.absTimePosition += s;
@@ -827,7 +827,7 @@ double MIDIplay::Tick(double s, double granularity)
return CurrentPositionNew.wait;
}
-#endif
+#endif /* ADLMIDI_DISABLE_MIDI_SEQUENCER */
void MIDIplay::TickIteratos(double s)
{
@@ -944,7 +944,7 @@ void MIDIplay::setTempo(double tempo)
{
tempoMultiplier = tempo;
}
-#endif
+#endif /* ADLMIDI_DISABLE_MIDI_SEQUENCER */
void MIDIplay::realTime_ResetState()
{
@@ -964,6 +964,9 @@ void MIDIplay::realTime_ResetState()
bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
{
+ if(note >= 128)
+ note = 127;
+
if((opl.m_musicMode == OPL3::MODE_RSXX) && (velocity != 0))
{
// Check if this is just a note after-touch
@@ -986,14 +989,16 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
if(velocity == 0)
return false;
- size_t midiins = Ch[channel].patch;
- bool isPercussion = (channel % 16 == 9);
+ MIDIchannel &midiChan = Ch[channel];
+
+ size_t midiins = midiChan.patch;
+ bool isPercussion = (channel % 16 == 9);
bool isXgPercussion = false;
uint16_t bank = 0;
- if(Ch[channel].bank_msb || Ch[channel].bank_lsb)
+ if(midiChan.bank_msb || midiChan.bank_lsb)
{
- bank = (uint16_t(Ch[channel].bank_msb) * 256) + uint16_t(Ch[channel].bank_lsb);
+ bank = (uint16_t(midiChan.bank_msb) * 256) + uint16_t(midiChan.bank_lsb);
//0x7E00 - XG SFX1/SFX2 channel (16128 signed decimal)
//0x7F00 - XG Percussion channel (16256 signed decimal)
if(bank == 0x7E00 || bank == 0x7F00)
@@ -1001,7 +1006,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
//Let XG SFX1/SFX2 bank will have LSB==1 (128...255 range in WOPN file)
//Let XG Percussion bank will use (0...127 range in WOPN file)
bank = (uint16_t)midiins + ((bank == 0x7E00) ? 128 : 0); // MIDI instrument defines the patch
- midiins = opl.dynamic_percussion_offset + note; // Percussion instrument
+ midiins = note; // Percussion instrument
isXgPercussion = true;
isPercussion = false;
}
@@ -1010,43 +1015,43 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
if(isPercussion)
{
bank = (uint16_t)midiins; // MIDI instrument defines the patch
- midiins = opl.dynamic_percussion_offset + note; // Percussion instrument
+ midiins = note; // Percussion instrument
}
+ if(isPercussion || isXgPercussion)
+ bank += OPL3::PercussionTag;
+
+ const adlinsdata2 *ains = &OPL3::emptyInstrument;
//Set bank bank
- if(bank > 0)
+ const OPL3::Bank *bnk = NULL;
+ if((bank & ~(uint16_t)OPL3::PercussionTag) > 0)
{
- if(isPercussion || isXgPercussion)
- {
- OPL3::BankMap::iterator b = opl.dynamic_percussion_banks.find(bank);
- if(b != opl.dynamic_percussion_banks.end())
- midiins += b->second * 128;
- else
- if(hooks.onDebugMessage)
- {
- if(!caugh_missing_banks_melodic.count(bank))
- {
- hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing percussion MIDI bank %i (patch %i)", channel, bank, midiins);
- caugh_missing_banks_melodic.insert(bank);
- }
- }
- }
- else
+ OPL3::BankMap::iterator b = opl.dynamic_banks.find(bank);
+ if(b != opl.dynamic_banks.end())
+ bnk = &b->second;
+
+ if(bnk)
+ ains = &bnk->ins[midiins];
+ else if(hooks.onDebugMessage)
{
- OPL3::BankMap::iterator b = opl.dynamic_melodic_banks.find(bank);
- if(b != opl.dynamic_melodic_banks.end())
- midiins += b->second * 128;
- else
- if(hooks.onDebugMessage)
- {
- if(!caugh_missing_banks_percussion.count(bank))
- {
- hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing melodic MIDI bank %i (patch %i)", channel, bank, midiins);
- caugh_missing_banks_percussion.insert(bank);
- }
- }
+ std::set<uint16_t> &missing = (isPercussion || isXgPercussion) ?
+ caugh_missing_banks_percussion : caugh_missing_banks_melodic;
+ const char *text = (isPercussion || isXgPercussion) ?
+ "percussion" : "melodic";
+ if(missing.insert(bank).second)
+ hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing %s MIDI bank %i (patch %i)", channel, text, bank, midiins);
}
}
+ //Or fall back to first bank
+ if(ains->flags & adlinsdata::Flag_NoSound)
+ {
+ OPL3::BankMap::iterator b = opl.dynamic_banks.find(bank & OPL3::PercussionTag);
+ if(b != opl.dynamic_banks.end())
+ bnk = &b->second;
+
+ if(bnk)
+ ains = &bnk->ins[midiins];
+ }
/*
if(MidCh%16 == 9 || (midiins != 32 && midiins != 46 && midiins != 48 && midiins != 50))
@@ -1057,8 +1062,6 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
//if(midiins == 56) vol = vol*6/10; // HACK
//int meta = banks[opl.AdlBank][midiins];
- size_t meta = opl.GetAdlMetaNumber(midiins);
- const adlinsdata *ains = &opl.GetAdlMetaIns(meta);
int16_t tone = note;
if(!isPercussion && !isXgPercussion && (bank > 0)) // For non-zero banks
@@ -1067,23 +1070,18 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
{
if(hooks.onDebugMessage)
{
- if(!caugh_missing_instruments.count(static_cast<uint8_t>(midiins)))
- {
+ if(caugh_missing_instruments.insert(static_cast<uint8_t>(midiins)).second)
hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Caugh a blank instrument %i (offset %i) in the MIDI bank %u", channel, Ch[channel].patch, midiins, bank);
- caugh_missing_instruments.insert(static_cast<uint8_t>(midiins));
- }
}
bank = 0;
- midiins = Ch[channel].patch;
- meta = opl.GetAdlMetaNumber(midiins);
- ains = &opl.GetAdlMetaIns(meta);
+ midiins = midiChan.patch;
}
}
if(ains->tone)
{
- /*if(ains.tone < 20)
- tone += ains.tone;
+ /*if(ains->tone < 20)
+ tone += ains->tone;
else*/
if(ains->tone < 128)
tone = ains->tone;
@@ -1091,24 +1089,32 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
tone -= ains->tone - 128;
}
- //uint16_t i[2] = { ains.adlno1, ains.adlno2 };
+ //uint16_t i[2] = { ains->adlno1, ains->adlno2 };
bool pseudo_4op = ains->flags & adlinsdata::Flag_Pseudo4op;
+#ifndef __WATCOMC__
MIDIchannel::NoteInfo::Phys voices[MIDIchannel::NoteInfo::MaxNumPhysChans] =
{
- {0, ains->adlno1, false},
- {0, ains->adlno2, pseudo_4op}
+ {0, ains->adl[0], false},
+ {0, ains->adl[1], pseudo_4op}
};
+#else /* Unfortunately, WatCom can't brace-initialize structure that incluses structure fields */
+ MIDIchannel::NoteInfo::Phys voices[MIDIchannel::NoteInfo::MaxNumPhysChans];
+ voices[0].chip_chan = 0;
+ voices[0].ains = ains->adl[0];
+ voices[0].pseudo4op = false;
+ voices[1].chip_chan = 0;
+ voices[1].ains = ains->adl[1];
+ voices[1].pseudo4op = pseudo_4op;
+#endif /* __WATCOMC__ */
if((opl.AdlPercussionMode == 1) && PercussionMap[midiins & 0xFF])
voices[1] = voices[0];//i[1] = i[0];
if(hooks.onDebugMessage)
{
- if(!caugh_missing_instruments.count(static_cast<uint8_t>(midiins)) && (ains->flags & adlinsdata::Flag_NoSound))
- {
+ if((ains->flags & adlinsdata::Flag_NoSound) &&
+ caugh_missing_instruments.insert(static_cast<uint8_t>(midiins)).second)
hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing instrument %i", channel, midiins);
- caugh_missing_instruments.insert(static_cast<uint8_t>(midiins));
- }
}
// Allocate AdLib channel (the physical sound channel for the note)
@@ -1132,7 +1138,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
if(ccount == 1 && static_cast<int32_t>(a) == adlchannel[0]) continue;
// ^ Don't use the same channel for primary&secondary
- if(voices[0].insId == voices[1].insId || pseudo_4op/*i[0] == i[1] || pseudo_4op*/)
+ if(voices[0].ains == voices[1].ains || pseudo_4op/*i[0] == i[1] || pseudo_4op*/)
{
// Only use regular channels
uint8_t expected_mode = 0;
@@ -1177,7 +1183,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
if(hooks.onDebugMessage)
hooks.onDebugMessage(hooks.onDebugMessage_userData,
"ignored unplaceable note [bank %i, inst %i, note %i, MIDI channel %i]",
- bank, Ch[channel].patch, note, channel);
+ bank, midiChan.patch, note, channel);
continue; // Could not play this note. Ignore it.
}
@@ -1196,11 +1202,12 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
// Allocate active note for MIDI channel
std::pair<MIDIchannel::activenoteiterator, bool>
- ir = Ch[channel].activenotes_insert(note);
+ ir = midiChan.activenotes_insert(note);
ir.first->vol = velocity;
+ ir.first->vibrato = midiChan.noteAftertouch[note];
ir.first->tone = tone;
ir.first->midiins = midiins;
- ir.first->insmeta = meta;
+ ir.first->ains = ains;
ir.first->chip_channels_count = 0;
for(unsigned ccount = 0; ccount < MIDIchannel::NoteInfo::MaxNumPhysChans; ++ccount)
@@ -1224,29 +1231,28 @@ void MIDIplay::realTime_NoteOff(uint8_t channel, uint8_t note)
void MIDIplay::realTime_NoteAfterTouch(uint8_t channel, uint8_t note, uint8_t atVal)
{
channel = channel % 16;
- MIDIchannel::activenoteiterator
- i = Ch[channel].activenotes_find(note);
- if(!i)
+ MIDIchannel &chan = Ch[channel];
+ MIDIchannel::activenoteiterator i = Ch[channel].activenotes_find(note);
+ if(i)
{
- // Ignore touch if note is not active
- return;
+ i->vibrato = atVal;
+ }
+
+ uint8_t oldAtVal = chan.noteAftertouch[note % 128];
+ if(atVal != oldAtVal)
+ {
+ chan.noteAftertouch[note % 128] = atVal;
+ bool inUse = atVal != 0;
+ for(unsigned n = 0; !inUse && n < 128; ++n)
+ inUse = chan.noteAftertouch[n] != 0;
+ chan.noteAfterTouchInUse = inUse;
}
- i->vol = 127 - atVal;
- NoteUpdate(channel, i, Upd_Volume);
}
void MIDIplay::realTime_ChannelAfterTouch(uint8_t channel, uint8_t atVal)
{
- // TODO: Verify, is this correct action?
channel = channel % 16;
- for(MIDIchannel::activenoteiterator
- i = Ch[channel].activenotes_begin(); i; ++i)
- {
- // Set this pressure to all active notes on the channel
- i->vol = 127 - atVal;
- }
-
- NoteUpdate_All(channel, Upd_Volume);
+ Ch[channel].aftertouch = atVal;
}
void MIDIplay::realTime_Controller(uint8_t channel, uint8_t type, uint8_t value)
@@ -1393,14 +1399,14 @@ void MIDIplay::realTime_PatchChange(uint8_t channel, uint8_t patch)
void MIDIplay::realTime_PitchBend(uint8_t channel, uint16_t pitch)
{
channel = channel % 16;
- Ch[channel].bend = (uint32_t(pitch) - 8192) * Ch[channel].bendsense;
+ Ch[channel].bend = int(pitch) - 8192;
NoteUpdate_All(channel, Upd_Pitch);
}
void MIDIplay::realTime_PitchBend(uint8_t channel, uint8_t msb, uint8_t lsb)
{
channel = channel % 16;
- Ch[channel].bend = (int(lsb) + int(msb) * 128 - 8192) * Ch[channel].bendsense;
+ Ch[channel].bend = int(lsb) + int(msb) * 128 - 8192;
NoteUpdate_All(channel, Upd_Pitch);
}
@@ -1438,9 +1444,8 @@ void MIDIplay::NoteUpdate(uint16_t MidCh,
MIDIchannel::NoteInfo &info = *i;
const int16_t tone = info.tone;
const uint8_t vol = info.vol;
- const int midiins = info.midiins;
- const size_t insmeta = info.insmeta;
- const adlinsdata &ains = opl.GetAdlMetaIns(insmeta);
+ const int midiins = static_cast<int>(info.midiins);
+ const adlinsdata2 &ains = *info.ains;
AdlChannel::Location my_loc;
my_loc.MidCh = MidCh;
my_loc.note = info.note;
@@ -1454,11 +1459,13 @@ void MIDIplay::NoteUpdate(uint16_t MidCh,
if(props_mask & Upd_Patch)
{
- opl.Patch(c, ins.insId);
+ opl.Patch(c, ins.ains);
AdlChannel::LocationData *d = ch[c].users_find_or_create(my_loc);
- if(d) { // inserts if necessary
+ if(d) // inserts if necessary
+ {
d->sustained = false;
d->vibdelay = 0;
+ d->fixed_sustain = (ains.ms_sound_kon == static_cast<uint16_t>(adlNoteOnMaxTime));
d->kon_time_until_neglible = ains.ms_sound_kon;
d->ins = ins;
}
@@ -1492,7 +1499,9 @@ void MIDIplay::NoteUpdate(uint16_t MidCh,
{
opl.Touch_Real(c, 0);
ch[c].koff_time_until_neglible = 0;
- } else {
+ }
+ else
+ {
ch[c].koff_time_until_neglible = ains.ms_sound_koff;
}
}
@@ -1533,8 +1542,8 @@ void MIDIplay::NoteUpdate(uint16_t MidCh,
switch(opl.m_volumeScale)
{
+
case OPL3::VOLUME_Generic:
- case OPL3::VOLUME_CMF:
{
volume = vol * Ch[MidCh].volume * Ch[MidCh].expression;
@@ -1547,25 +1556,29 @@ void MIDIplay::NoteUpdate(uint16_t MidCh,
*/
//volume = (int)(volume * std::sqrt( (double) ch[c].users.size() ));
- if(opl.LogarithmicVolumes)
- volume = volume * 127 / (127 * 127 * 127) / 2;
- else
- {
- // The formula below: SOLVE(V=127^3 * 2^( (A-63.49999) / 8), A)
- volume = volume > 8725 ? static_cast<uint32_t>(std::log(static_cast<double>(volume)) * 11.541561 + (0.5 - 104.22845)) : 0;
- // The incorrect formula below: SOLVE(V=127^3 * (2^(A/63)-1), A)
- //opl.Touch_Real(c, volume>11210 ? 91.61112 * std::log(4.8819E-7*volume + 1.0)+0.5 : 0);
- }
+ // The formula below: SOLVE(V=127^3 * 2^( (A-63.49999) / 8), A)
+ volume = volume > 8725 ? static_cast<uint32_t>(std::log(static_cast<double>(volume)) * 11.541561 + (0.5 - 104.22845)) : 0;
+ // The incorrect formula below: SOLVE(V=127^3 * (2^(A/63)-1), A)
+ //opl.Touch_Real(c, volume>11210 ? 91.61112 * std::log(4.8819E-7*volume + 1.0)+0.5 : 0);
+
opl.Touch_Real(c, volume, brightness);
//opl.Touch(c, volume);
}
break;
+ case OPL3::VOLUME_NATIVE:
+ {
+ volume = vol * Ch[MidCh].volume * Ch[MidCh].expression;
+ volume = volume * 127 / (127 * 127 * 127) / 2;
+ opl.Touch_Real(c, volume, brightness);
+ }
+ break;
+
case OPL3::VOLUME_DMX:
{
volume = 2 * ((Ch[MidCh].volume * Ch[MidCh].expression) * 127 / 16129) + 1;
//volume = 2 * (Ch[MidCh].volume) + 1;
- volume = (DMX_volume_mapping_table[vol] * volume) >> 9;
+ volume = (DMX_volume_mapping_table[(vol < 128) ? vol : 127] * volume) >> 9;
opl.Touch_Real(c, volume, brightness);
}
break;
@@ -1610,26 +1623,29 @@ void MIDIplay::NoteUpdate(uint16_t MidCh,
// Don't bend a sustained note
if(!d || !d->sustained)
{
- double bend = Ch[MidCh].bend + opl.GetAdlIns(ins.insId).finetune;
+ double midibend = Ch[MidCh].bend * Ch[MidCh].bendsense;
+ double bend = midibend + ins.ains.finetune;
double phase = 0.0;
+ uint8_t vibrato = std::max(Ch[MidCh].vibrato, Ch[MidCh].aftertouch);
+ vibrato = std::max(vibrato, i->vibrato);
if((ains.flags & adlinsdata::Flag_Pseudo4op) && ins.pseudo4op)
{
phase = ains.voice2_fine_tune;//0.125; // Detune the note slightly (this is what Doom does)
}
- if(Ch[MidCh].vibrato && (!d || d->vibdelay >= Ch[MidCh].vibdelay))
- bend += Ch[MidCh].vibrato * Ch[MidCh].vibdepth * std::sin(Ch[MidCh].vibpos);
+ if(vibrato && (!d || d->vibdelay >= Ch[MidCh].vibdelay))
+ bend += static_cast<double>(vibrato) * Ch[MidCh].vibdepth * std::sin(Ch[MidCh].vibpos);
- #ifdef ADLMIDI_USE_DOSBOX_OPL
-#define BEND_COEFFICIENT 172.00093
- #else
-#define BEND_COEFFICIENT 172.4387
- #endif
- opl.NoteOn(c, BEND_COEFFICIENT * std::exp(0.057762265 * (tone + bend + phase)));
+#ifdef ADLMIDI_USE_DOSBOX_OPL
+# define BEND_COEFFICIENT 172.00093
+#else
+# define BEND_COEFFICIENT 172.4387
+#endif
+ opl.NoteOn(c, BEND_COEFFICIENT * std::exp(0.057762265 * (static_cast<double>(tone) + bend + phase)));
#undef BEND_COEFFICIENT
if(hooks.onNote)
- hooks.onNote(hooks.onNote_userData, c, tone, midiins, vol, Ch[MidCh].bend);
+ hooks.onNote(hooks.onNote_userData, c, tone, midiins, vol, midibend);
}
}
}
@@ -1650,9 +1666,9 @@ bool MIDIplay::ProcessEventsNew(bool isSeek)
const size_t TrackCount = CurrentPositionNew.track.size();
const PositionNew RowBeginPosition(CurrentPositionNew);
- #ifdef DEBUG_TIME_CALCULATION
+#ifdef DEBUG_TIME_CALCULATION
double maxTime = 0.0;
- #endif
+#endif
for(size_t tk = 0; tk < TrackCount; ++tk)
{
@@ -1670,10 +1686,10 @@ bool MIDIplay::ProcessEventsNew(bool isSeek)
for(size_t i = 0; i < track.pos->events.size(); i++)
{
const MidiEvent &evt = track.pos->events[i];
- #ifdef ENABLE_BEGIN_SILENCE_SKIPPING
+#ifdef ENABLE_BEGIN_SILENCE_SKIPPING
if(!CurrentPositionNew.began && (evt.type == MidiEvent::T_NOTEON))
CurrentPositionNew.began = true;
- #endif
+#endif
if(isSeek && (evt.type == MidiEvent::T_NOTEON))
continue;
HandleEvent(tk, evt, track.status);
@@ -1681,10 +1697,10 @@ bool MIDIplay::ProcessEventsNew(bool isSeek)
break;//Stop event handling on catching loopEnd event!
}
- #ifdef DEBUG_TIME_CALCULATION
+#ifdef DEBUG_TIME_CALCULATION
if(maxTime < track.pos->time)
maxTime = track.pos->time;
- #endif
+#endif
// Read next event time (unless the track just ended)
if(track.status >= 0)
{
@@ -1694,11 +1710,11 @@ bool MIDIplay::ProcessEventsNew(bool isSeek)
}
}
- #ifdef DEBUG_TIME_CALCULATION
+#ifdef DEBUG_TIME_CALCULATION
std::fprintf(stdout, " \r");
std::fprintf(stdout, "Time: %10f; Audio: %10f\r", maxTime, CurrentPositionNew.absTimePosition);
std::fflush(stdout);
- #endif
+#endif
// Find shortest delay from all track
uint64_t shortest = 0;
@@ -1722,9 +1738,9 @@ bool MIDIplay::ProcessEventsNew(bool isSeek)
fraction<uint64_t> t = shortest * Tempo;
- #ifdef ENABLE_BEGIN_SILENCE_SKIPPING
+#ifdef ENABLE_BEGIN_SILENCE_SKIPPING
if(CurrentPositionNew.began)
- #endif
+#endif
CurrentPositionNew.wait += t.value();
//if(shortest > 0) UI.PrintLn("Delay %ld (%g)", shortest, (double)t.valuel());
@@ -1750,9 +1766,7 @@ bool MIDIplay::ProcessEventsNew(bool isSeek)
return true;//Has events in queue
}
-#endif
-#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
MIDIplay::MidiEvent MIDIplay::parseEvent(uint8_t **pptr, uint8_t *end, int &status)
{
uint8_t *&ptr = *pptr;
@@ -1800,6 +1814,14 @@ MIDIplay::MidiEvent MIDIplay::parseEvent(uint8_t **pptr, uint8_t *end, int &stat
evt.subtype = evtype;
evt.data.insert(evt.data.begin(), data.begin(), data.end());
+#if 0 /* Print all tempo events */
+ if(evt.subtype == MidiEvent::ST_TEMPOCHANGE)
+ {
+ if(hooks.onDebugMessage)
+ hooks.onDebugMessage(hooks.onDebugMessage_userData, "Temp Change: %02X%02X%02X", evt.data[0], evt.data[1], evt.data[2]);
+ }
+#endif
+
/* TODO: Store those meta-strings separately and give ability to read them
* by external functions (to display song title and copyright in the player) */
if(evt.subtype == MidiEvent::ST_COPYRIGHT)
@@ -1930,9 +1952,16 @@ MIDIplay::MidiEvent MIDIplay::parseEvent(uint8_t **pptr, uint8_t *end, int &stat
evt.data.push_back(*(ptr++));
evt.data.push_back(*(ptr++));
- if((evType == MidiEvent::T_NOTEON) && (evt.data[1] == 0))
+ /* TODO: Implement conversion of RSXX's note volumes out of synthesizer */
+ /*if((opl.m_musicMode == OPL3::MODE_RSXX) && (evType == MidiEvent::T_NOTEON) && (evt.data[1] != 0))
+ {
+ //NOT WORKING YET
+ evt.type = MidiEvent::T_NOTETOUCH;
+ }
+ else */if((evType == MidiEvent::T_NOTEON) && (evt.data[1] == 0))
+ {
evt.type = MidiEvent::T_NOTEOFF; // Note ON with zero velocity is Note OFF!
- //111'th loopStart controller (RPG Maker and others)
+ } //111'th loopStart controller (RPG Maker and others)
else if((evType == MidiEvent::T_CTRLCHANGE) && (evt.data[0] == 111))
{
//Change event type to custom Loop Start event and clear data
@@ -1956,7 +1985,7 @@ MIDIplay::MidiEvent MIDIplay::parseEvent(uint8_t **pptr, uint8_t *end, int &stat
return evt;
}
-#endif
+#endif /* ADLMIDI_DISABLE_MIDI_SEQUENCER */
const std::string &MIDIplay::getErrorString()
{
@@ -2045,7 +2074,7 @@ void MIDIplay::HandleEvent(size_t tk, const MIDIplay::MidiEvent &evt, int &statu
v |= 0x30;
//std::printf("OPL poke %02X, %02X\n", i, v);
//std::fflush(stdout);
- opl.PokeN(0, i, v);
+ opl.Poke(0, i, v);
return;
}
@@ -2125,15 +2154,15 @@ void MIDIplay::HandleEvent(size_t tk, const MIDIplay::MidiEvent &evt, int &statu
}
}
}
-#endif
+#endif /* ADLMIDI_DISABLE_MIDI_SEQUENCER */
-int64_t MIDIplay::CalculateAdlChannelGoodness(unsigned c, const MIDIchannel::NoteInfo::Phys &ins, uint16_t) const
+int64_t MIDIplay::CalculateAdlChannelGoodness(size_t c, const MIDIchannel::NoteInfo::Phys &ins, uint16_t) const
{
int64_t s = -ch[c].koff_time_until_neglible;
// Same midi-instrument = some stability
//if(c == MidCh) s += 4;
- for (AdlChannel::LocationData *j = ch[c].users_first; j; j = j->next)
+ for(AdlChannel::LocationData *j = ch[c].users_first; j; j = j->next)
{
s -= 4000;
@@ -2174,7 +2203,7 @@ int64_t MIDIplay::CalculateAdlChannelGoodness(unsigned c, const MIDIchannel::Not
// increase the score slightly.
unsigned n_evacuation_stations = 0;
- for(unsigned c2 = 0; c2 < opl.NumChannels; ++c2)
+ for(size_t c2 = 0; c2 < static_cast<size_t>(opl.NumChannels); ++c2)
{
if(c2 == c) continue;
@@ -2275,11 +2304,11 @@ void MIDIplay::KillOrEvacuate(size_t from_channel,
hooks.onNote(hooks.onNote_userData,
(int)from_channel,
i->tone,
- i->midiins, 0, 0.0);
+ static_cast<int>(i->midiins), 0, 0.0);
hooks.onNote(hooks.onNote_userData,
(int)c,
i->tone,
- i->midiins,
+ static_cast<int>(i->midiins),
i->vol, 0.0);
}
@@ -2358,7 +2387,12 @@ void MIDIplay::SetRPN(unsigned MidCh, unsigned value, bool MSB)
switch(addr + nrpn * 0x10000 + MSB * 0x20000)
{
case 0x0000 + 0*0x10000 + 1*0x20000: // Pitch-bender sensitivity
- Ch[MidCh].bendsense = value / 8192.0;
+ Ch[MidCh].bendsense_msb = value;
+ Ch[MidCh].updateBendSensitivity();
+ break;
+ case 0x0000 + 0*0x10000 + 0*0x20000: // Pitch-bender sensitivity LSB
+ Ch[MidCh].bendsense_lsb = value;
+ Ch[MidCh].updateBendSensitivity();
break;
case 0x0108 + 1*0x10000 + 1*0x20000: // Vibrato speed
if(value == 64) Ch[MidCh].vibspeed = 1.0;
@@ -2412,7 +2446,7 @@ void MIDIplay::UpdateVibrato(double amount)
{
for(size_t a = 0, b = Ch.size(); a < b; ++a)
{
- if(Ch[a].vibrato && !Ch[a].activenotes_empty())
+ if(Ch[a].hasVibrato() && !Ch[a].activenotes_empty())
{
NoteUpdate_All(static_cast<uint16_t>(a), Upd_Pitch);
Ch[a].vibpos += amount * Ch[a].vibspeed;
@@ -2442,9 +2476,9 @@ void MIDIplay::UpdateArpeggio(double) // amount = amount of time passed
{
// If there is an adlib channel that has multiple notes
// simulated on the same channel, arpeggio them.
- #if 0
+#if 0
const unsigned desired_arpeggio_rate = 40; // Hz (upper limit)
- #if 1
+# if 1
static unsigned cache = 0;
amount = amount; // Ignore amount. Assume we get a constant rate.
cache += MaxSamplesAtTime * desired_arpeggio_rate;
@@ -2452,17 +2486,17 @@ void MIDIplay::UpdateArpeggio(double) // amount = amount of time passed
if(cache < PCM_RATE) return;
cache %= PCM_RATE;
- #else
+# else
static double arpeggio_cache = 0;
arpeggio_cache += amount * desired_arpeggio_rate;
if(arpeggio_cache < 1.0) return;
arpeggio_cache = 0.0;
- #endif
- #endif
- static unsigned arpeggio_counter = 0;
- ++arpeggio_counter;
+# endif
+#endif
+
+ ++m_arpeggioCounter;
for(uint32_t c = 0; c < opl.NumChannels; ++c)
{
@@ -2483,8 +2517,8 @@ retry_arpeggio:
if(n_users >= 4)
rate_reduction = 1;
- for(unsigned count = (arpeggio_counter / rate_reduction) % n_users,
- n = 0; n < count; ++n)
+ for(size_t count = (m_arpeggioCounter / rate_reduction) % n_users,
+ n = 0; n < count; ++n)
i = i->next;
if(i->sustained == false)
@@ -2512,36 +2546,48 @@ retry_arpeggio:
#ifndef ADLMIDI_DISABLE_CPP_EXTRAS
+struct AdlInstrumentTester::Impl
+{
+ uint32_t cur_gm;
+ uint32_t ins_idx;
+ std::vector<uint32_t> adl_ins_list;
+ OPL3 *opl;
+ MIDIplay *play;
+};
+
ADLMIDI_EXPORT AdlInstrumentTester::AdlInstrumentTester(ADL_MIDIPlayer *device)
+ : P(new Impl)
{
- cur_gm = 0;
- ins_idx = 0;
- play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
- if(!play)
- return;
- opl = &play->opl;
+ MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
+ P->cur_gm = 0;
+ P->ins_idx = 0;
+ P->play = play;
+ P->opl = play ? &play->opl : NULL;
}
ADLMIDI_EXPORT AdlInstrumentTester::~AdlInstrumentTester()
-{}
+{
+ delete P;
+}
ADLMIDI_EXPORT void AdlInstrumentTester::FindAdlList()
{
const unsigned NumBanks = (unsigned)adl_getBanksCount();
std::set<unsigned> adl_ins_set;
for(unsigned bankno = 0; bankno < NumBanks; ++bankno)
- adl_ins_set.insert(banks[bankno][cur_gm]);
- adl_ins_list.assign(adl_ins_set.begin(), adl_ins_set.end());
- ins_idx = 0;
+ adl_ins_set.insert(banks[bankno][P->cur_gm]);
+ P->adl_ins_list.assign(adl_ins_set.begin(), adl_ins_set.end());
+ P->ins_idx = 0;
NextAdl(0);
- opl->Silence();
+ P->opl->Silence();
}
ADLMIDI_EXPORT void AdlInstrumentTester::Touch(unsigned c, unsigned volume) // Volume maxes at 127*127*127
{
- if(opl->LogarithmicVolumes)
+ OPL3 *opl = P->opl;
+ if(opl->m_volumeScale == OPL3::VOLUME_NATIVE)
opl->Touch_Real(c, volume * 127 / (127 * 127 * 127) / 2);
else
{
@@ -2554,11 +2600,13 @@ ADLMIDI_EXPORT void AdlInstrumentTester::Touch(unsigned c, unsigned volume) // V
ADLMIDI_EXPORT void AdlInstrumentTester::DoNote(int note)
{
- if(adl_ins_list.empty()) FindAdlList();
- const unsigned meta = adl_ins_list[ins_idx];
- const adlinsdata &ains = opl->GetAdlMetaIns(meta);
+ MIDIplay *play = P->play;
+ OPL3 *opl = P->opl;
+ if(P->adl_ins_list.empty()) FindAdlList();
+ const unsigned meta = P->adl_ins_list[P->ins_idx];
+ const adlinsdata2 ains(adlins[meta]);
- int tone = (cur_gm & 128) ? (cur_gm & 127) : (note + 50);
+ int tone = (P->cur_gm & 128) ? (P->cur_gm & 127) : (note + 50);
if(ains.tone)
{
/*if(ains.tone < 20)
@@ -2570,16 +2618,15 @@ ADLMIDI_EXPORT void AdlInstrumentTester::DoNote(int note)
tone -= ains.tone - 128;
}
double hertz = 172.00093 * std::exp(0.057762265 * (tone + 0.0));
- int i[2] = { ains.adlno1, ains.adlno2 };
int32_t adlchannel[2] = { 0, 3 };
- if(i[0] == i[1])
+ if(ains.adl[0] == ains.adl[1])
{
adlchannel[1] = -1;
adlchannel[0] = 6; // single-op
if(play->hooks.onDebugMessage)
{
play->hooks.onDebugMessage(play->hooks.onDebugMessage_userData,
- "noteon at %d(%d) for %g Hz\n", adlchannel[0], i[0], hertz);
+ "noteon at %d for %g Hz\n", adlchannel[0], hertz);
}
}
else
@@ -2587,7 +2634,7 @@ ADLMIDI_EXPORT void AdlInstrumentTester::DoNote(int note)
if(play->hooks.onDebugMessage)
{
play->hooks.onDebugMessage(play->hooks.onDebugMessage_userData,
- "noteon at %d(%d) and %d(%d) for %g Hz\n", adlchannel[0], i[0], adlchannel[1], i[1], hertz);
+ "noteon at %d and %d for %g Hz\n", adlchannel[0], adlchannel[1], hertz);
}
}
@@ -2597,7 +2644,7 @@ ADLMIDI_EXPORT void AdlInstrumentTester::DoNote(int note)
for(unsigned c = 0; c < 2; ++c)
{
if(adlchannel[c] < 0) continue;
- opl->Patch((uint16_t)adlchannel[c], (uint16_t)i[c]);
+ opl->Patch((uint16_t)adlchannel[c], ains.adl[c]);
opl->Touch_Real((uint16_t)adlchannel[c], 127 * 127 * 100);
opl->Pan((uint16_t)adlchannel[c], 0x30);
opl->NoteOn((uint16_t)adlchannel[c], hertz);
@@ -2606,17 +2653,18 @@ ADLMIDI_EXPORT void AdlInstrumentTester::DoNote(int note)
ADLMIDI_EXPORT void AdlInstrumentTester::NextGM(int offset)
{
- cur_gm = (cur_gm + 256 + (uint32_t)offset) & 0xFF;
+ P->cur_gm = (P->cur_gm + 256 + (uint32_t)offset) & 0xFF;
FindAdlList();
}
ADLMIDI_EXPORT void AdlInstrumentTester::NextAdl(int offset)
{
- if(adl_ins_list.empty()) FindAdlList();
+ //OPL3 *opl = P->opl;
+ if(P->adl_ins_list.empty()) FindAdlList();
const unsigned NumBanks = (unsigned)adl_getBanksCount();
- ins_idx = (uint32_t)((int32_t)ins_idx + (int32_t)adl_ins_list.size() + offset) % adl_ins_list.size();
+ P->ins_idx = (uint32_t)((int32_t)P->ins_idx + (int32_t)P->adl_ins_list.size() + offset) % P->adl_ins_list.size();
- #if 0
+#if 0
UI.Color(15);
std::fflush(stderr);
std::printf("SELECTED G%c%d\t%s\n",
@@ -2625,12 +2673,12 @@ ADLMIDI_EXPORT void AdlInstrumentTester::NextAdl(int offset)
std::fflush(stdout);
UI.Color(7);
std::fflush(stderr);
- #endif
+#endif
- for(unsigned a = 0; a < adl_ins_list.size(); ++a)
+ for(unsigned a = 0, n = P->adl_ins_list.size(); a < n; ++a)
{
- const unsigned i = adl_ins_list[a];
- const adlinsdata &ains = opl->GetAdlMetaIns(i);
+ const unsigned i = P->adl_ins_list[a];
+ const adlinsdata2 ains(adlins[i]);
char ToneIndication[8] = " ";
if(ains.tone)
@@ -2645,13 +2693,13 @@ ADLMIDI_EXPORT void AdlInstrumentTester::NextAdl(int offset)
}
std::printf("%s%s%s%u\t",
ToneIndication,
- ains.adlno1 != ains.adlno2 ? "[2]" : " ",
- (ins_idx == a) ? "->" : "\t",
+ ains.adl[0] != ains.adl[1] ? "[2]" : " ",
+ (P->ins_idx == a) ? "->" : "\t",
i
);
for(unsigned bankno = 0; bankno < NumBanks; ++bankno)
- if(banks[bankno][cur_gm] == i)
+ if(banks[bankno][P->cur_gm] == i)
std::printf(" %u", bankno);
std::printf("\n");
@@ -2685,9 +2733,9 @@ ADLMIDI_EXPORT bool AdlInstrumentTester::HandleInputChar(char ch)
NextGM(+1);
break;
case 3:
- #if !((!defined(__WIN32__) || defined(__CYGWIN__)) && !defined(__DJGPP__))
+#if !((!defined(__WIN32__) || defined(__CYGWIN__)) && !defined(__DJGPP__))
case 27:
- #endif
+#endif
return false;
default:
const char *p = std::strchr(notes, ch);
@@ -2697,7 +2745,7 @@ ADLMIDI_EXPORT bool AdlInstrumentTester::HandleInputChar(char ch)
return true;
}
-#endif//ADLMIDI_DISABLE_CPP_EXTRAS
+#endif /* ADLMIDI_DISABLE_CPP_EXTRAS */
// Implement the user map data structure.
@@ -2737,13 +2785,15 @@ MIDIplay::AdlChannel::LocationData *MIDIplay::AdlChannel::users_allocate()
MIDIplay::AdlChannel::LocationData *MIDIplay::AdlChannel::users_find_or_create(Location loc)
{
LocationData *user = users_find(loc);
- if(!user) {
+ if(!user)
+ {
user = users_allocate();
if(!user)
return NULL;
LocationData *prev = user->prev, *next = user->next;
*user = LocationData();
- user->prev = prev; user->next = next;
+ user->prev = prev;
+ user->next = next;
user->loc = loc;
}
return user;
@@ -2759,7 +2809,8 @@ MIDIplay::AdlChannel::LocationData *MIDIplay::AdlChannel::users_insert(const Loc
return NULL;
LocationData *prev = user->prev, *next = user->next;
*user = x;
- user->prev = prev; user->next = next;
+ user->prev = prev;
+ user->next = next;
}
return user;
}
@@ -2792,8 +2843,10 @@ void MIDIplay::AdlChannel::users_clear()
void MIDIplay::AdlChannel::users_assign(const LocationData *users, size_t count)
{
+ ADL_UNUSED(count);//Avoid warning for release builds
assert(count <= users_max);
- if(users == users_first && users) {
+ if(users == users_first && users)
+ {
// self assignment
assert(users_size == count);
return;
@@ -2801,17 +2854,20 @@ void MIDIplay::AdlChannel::users_assign(const LocationData *users, size_t count)
users_clear();
const LocationData *src_cell = users;
// move to the last
- if(src_cell) {
+ if(src_cell)
+ {
while(src_cell->next)
src_cell = src_cell->next;
}
// push cell copies in reverse order
- while(src_cell) {
+ while(src_cell)
+ {
LocationData *dst_cell = users_allocate();
assert(dst_cell);
LocationData *prev = dst_cell->prev, *next = dst_cell->next;
*dst_cell = *src_cell;
- dst_cell->prev = prev; dst_cell->next = next;
+ dst_cell->prev = prev;
+ dst_cell->next = next;
src_cell = src_cell->prev;
}
assert(users_size == count);
diff --git a/src/adlmidi_mus2mid.c b/src/adlmidi_mus2mid.c
index 8268198..3f3e1b8 100644
--- a/src/adlmidi_mus2mid.c
+++ b/src/adlmidi_mus2mid.c
@@ -416,7 +416,7 @@ int AdlMidi_mus2midi(uint8_t *in, uint32_t insize,
memcpy(ctx.dst_ptr, temp_buffer, out_local - temp_buffer);
ctx.dst_ptr += out_local - temp_buffer;
- ctx.dstrem -= out_local - temp_buffer;
+ ctx.dstrem -= (uint32_t)(out_local - temp_buffer);
}
if (event & 128) {
diff --git a/src/adlmidi_opl3.cpp b/src/adlmidi_opl3.cpp
index 66254b6..16a481d 100644
--- a/src/adlmidi_opl3.cpp
+++ b/src/adlmidi_opl3.cpp
@@ -129,81 +129,56 @@ static const unsigned short Channels[23] =
Ports: ???
*/
-
-const adlinsdata &OPL3::GetAdlMetaIns(size_t n)
+void OPL3::setEmbeddedBank(unsigned int bank)
{
- return (n & DynamicMetaInstrumentTag) ?
- dynamic_metainstruments[n & ~DynamicMetaInstrumentTag]
- : adlins[n];
-}
+ AdlBank = bank;
+ //Embedded banks are supports 128:128 GM set only
+ dynamic_banks.clear();
-size_t OPL3::GetAdlMetaNumber(size_t midiins)
-{
- return (AdlBank == ~0u) ?
- (midiins | DynamicMetaInstrumentTag)
- : banks[AdlBank][midiins];
-}
+ if(bank >= static_cast<unsigned int>(maxAdlBanks()))
+ return;
-const adldata &OPL3::GetAdlIns(size_t insno)
-{
- return (insno & DynamicInstrumentTag)
- ? dynamic_instruments[insno & ~DynamicInstrumentTag]
- : adl[insno];
+ Bank *bank_pair[2] =
+ {
+ &dynamic_banks[0],
+ &dynamic_banks[PercussionTag]
+ };
+
+ for(unsigned i = 0; i < 256; ++i)
+ {
+ size_t meta = banks[bank][i];
+ adlinsdata2 &ins = bank_pair[i / 128]->ins[i % 128];
+ ins = adlinsdata2(adlins[meta]);
+ }
}
-void OPL3::setEmbeddedBank(unsigned int bank)
+static adlinsdata2 makeEmptyInstrument()
{
- AdlBank = bank;
- //Embedded banks are supports 128:128 GM set only
- dynamic_percussion_offset = 128;
- dynamic_melodic_banks.clear();
- dynamic_percussion_banks.clear();
+ adlinsdata2 ins;
+ memset(&ins, 0, sizeof(adlinsdata2));
+ ins.flags = adlinsdata::Flag_NoSound;
+ return ins;
}
+const adlinsdata2 OPL3::emptyInstrument = makeEmptyInstrument();
OPL3::OPL3() :
- dynamic_percussion_offset(128),
- DynamicInstrumentTag(0x8000u),
- DynamicMetaInstrumentTag(0x4000000u),
NumCards(1),
- AdlBank(0),
NumFourOps(0),
HighTremoloMode(false),
HighVibratoMode(false),
AdlPercussionMode(false),
- LogarithmicVolumes(false),
- //CartoonersVolumes(false),
m_musicMode(MODE_MIDI),
m_volumeScale(VOLUME_Generic)
-{}
-
-void OPL3::Poke(size_t card, uint32_t index, uint32_t value)
{
- #ifdef ADLMIDI_HW_OPL
- (void)card;
- unsigned o = index >> 8;
- unsigned port = OPLBase + o * 2;
-
- #ifdef __DJGPP__
- outportb(port, index);
- for(unsigned c = 0; c < 6; ++c) inportb(port);
- outportb(port + 1, value);
- for(unsigned c = 0; c < 35; ++c) inportb(port);
- #endif//__DJGPP__
-
- #ifdef __WATCOMC__
- outp(port, index);
- for(uint16_t c = 0; c < 6; ++c) inp(port);
- outp(port + 1, value);
- for(uint16_t c = 0; c < 35; ++c) inp(port);
- #endif//__WATCOMC__
-
- #else//ADLMIDI_HW_OPL
- cardsOP2[card]->writeReg(static_cast<uint16_t>(index), static_cast<uint8_t>(value));
- #endif//ADLMIDI_HW_OPL
+#ifdef DISABLE_EMBEDDED_BANKS
+ AdlBank = ~0u;
+#else
+ setEmbeddedBank(0);
+#endif
}
-void OPL3::PokeN(size_t card, uint16_t index, uint8_t value)
+void OPL3::Poke(size_t card, uint16_t index, uint8_t value)
{
#ifdef ADLMIDI_HW_OPL
(void)card;
@@ -282,10 +257,9 @@ void OPL3::Touch_Real(unsigned c, unsigned volume, uint8_t brightness)
volume = 63;
size_t card = c / 23, cc = c % 23;
- size_t i = ins[c];
+ const adldata &adli = ins[c];
uint16_t o1 = Operators[cc * 2 + 0];
uint16_t o2 = Operators[cc * 2 + 1];
- const adldata &adli = GetAdlIns(i);
uint8_t x = adli.modulator_40, y = adli.carrier_40;
uint16_t mode = 1; // 2-op AM
@@ -295,22 +269,22 @@ void OPL3::Touch_Real(unsigned c, unsigned volume, uint8_t brightness)
}
else if(four_op_category[c] == 1 || four_op_category[c] == 2)
{
- size_t i0, i1;
+ const adldata *i0, *i1;
if(four_op_category[c] == 1)
{
- i0 = i;
- i1 = ins[c + 3];
+ i0 = &adli;
+ i1 = &ins[c + 3];
mode = 2; // 4-op xx-xx ops 1&2
}
else
{
- i0 = ins[c - 3];
- i1 = i;
+ i0 = &ins[c - 3];
+ i1 = &adli;
mode = 6; // 4-op xx-xx ops 3&4
}
- mode += (GetAdlIns(i0).feedconn & 1) + (GetAdlIns(i1).feedconn & 1) * 2;
+ mode += (i0->feedconn & 1) + (i1->feedconn & 1) * 2;
}
static const bool do_ops[10][2] =
@@ -377,14 +351,13 @@ void OPL3::Touch(unsigned c, unsigned volume) // Volume maxes at 127*127*127
}
}*/
-void OPL3::Patch(uint16_t c, size_t i)
+void OPL3::Patch(uint16_t c, const adldata &adli)
{
uint16_t card = c / 23, cc = c % 23;
static const uint8_t data[4] = {0x20, 0x60, 0x80, 0xE0};
- ins[c] = i;
+ ins[c] = adli;
uint16_t o1 = Operators[cc * 2 + 0];
uint16_t o2 = Operators[cc * 2 + 1];
- const adldata &adli = GetAdlIns(i);
unsigned x = adli.modulator_E862, y = adli.carrier_E862;
for(unsigned a = 0; a < 4; ++a, x >>= 8, y >>= 8)
@@ -400,7 +373,7 @@ void OPL3::Pan(unsigned c, unsigned value)
unsigned card = c / 23, cc = c % 23;
if(Channels[cc] != 0xFFF)
- Poke(card, 0xC0 + Channels[cc], GetAdlIns(ins[c]).feedconn | value);
+ Poke(card, 0xC0 + Channels[cc], ins[c].feedconn | value);
}
void OPL3::Silence() // Silence all OPL channels.
@@ -484,9 +457,8 @@ void OPL3::ChangeVolumeRangesModel(ADLMIDI_VolumeModels volumeModel)
m_volumeScale = OPL3::VOLUME_Generic;
break;
- case ADLMIDI_VolumeModel_CMF:
- LogarithmicVolumes = true;
- m_volumeScale = OPL3::VOLUME_CMF;
+ case ADLMIDI_VolumeModel_NativeOPL3:
+ m_volumeScale = OPL3::VOLUME_NATIVE;
break;
case ADLMIDI_VolumeModel_DMX:
@@ -517,6 +489,7 @@ void OPL3::Reset(int emulator, unsigned long PCM_RATE)
#ifndef ADLMIDI_HW_OPL
ClearChips();
#endif
+ (void)emulator;
(void)PCM_RATE;
ins.clear();
pit.clear();
@@ -527,7 +500,7 @@ void OPL3::Reset(int emulator, unsigned long PCM_RATE)
#endif
NumChannels = NumCards * 23;
- ins.resize(NumChannels, 189);
+ ins.resize(NumChannels, adl[adlDefaultNumber]);
pit.resize(NumChannels, 0);
regBD.resize(NumCards, 0);
four_op_category.resize(NumChannels, 0);
@@ -571,7 +544,7 @@ void OPL3::Reset(int emulator, unsigned long PCM_RATE)
for(unsigned a = 0; a < 18; ++a) Poke(i, 0xB0 + Channels[a], 0x00);
for(unsigned a = 0; a < sizeof(data) / sizeof(*data); a += 2)
- PokeN(i, data[a], static_cast<uint8_t>(data[a + 1]));
+ Poke(i, data[a], static_cast<uint8_t>(data[a + 1]));
Poke(i, 0x0BD, regBD[i] = (HighTremoloMode * 0x80
+ HighVibratoMode * 0x40
+ AdlPercussionMode * 0x20));
diff --git a/src/adlmidi_private.cpp b/src/adlmidi_private.cpp
index 1f3cb7d..77319d7 100644
--- a/src/adlmidi_private.cpp
+++ b/src/adlmidi_private.cpp
@@ -34,19 +34,22 @@ int adlRefreshNumCards(ADL_MIDIPlayer *device)
if(play->opl.AdlBank == ~0u)
{
//For custom bank
- for(size_t a = 0; a < play->opl.dynamic_metainstruments.size(); ++a)
+ OPL3::BankMap::iterator it = play->opl.dynamic_banks.begin();
+ OPL3::BankMap::iterator end = play->opl.dynamic_banks.end();
+ for(; it != end; ++it)
{
- size_t div = (a >= play->opl.dynamic_percussion_offset) ? 1 : 0;
- ++n_total[div];
- adlinsdata &ins = play->opl.dynamic_metainstruments[a];
- if((ins.adlno1 != ins.adlno2) && ((ins.flags & adlinsdata::Flag_Pseudo4op) == 0))
- ++n_fourop[div];
+ uint16_t bank = it->first;
+ unsigned div = (bank & OPL3::PercussionTag) ? 1 : 0;
+ for(unsigned i = 0; i < 128; ++i)
+ {
+ adlinsdata2 &ins = it->second.ins[i];
+ if(ins.flags & adlinsdata::Flag_NoSound)
+ continue;
+ if((ins.adl[0] != ins.adl[1]) && ((ins.flags & adlinsdata::Flag_Pseudo4op) == 0))
+ ++n_fourop[div];
+ ++n_total[div];
+ }
}
-
- play->m_setup.NumFourOps =
- (n_fourop[0] >= 128 * 7 / 8) ? play->m_setup.NumCards * 6
- : (n_fourop[0] < 128 * 1 / 8) ? (n_fourop[1] > 0 ? 4 : 0)
- : (play->m_setup.NumCards == 1 ? 1 : play->m_setup.NumCards * 4);
}
else
{
@@ -57,27 +60,34 @@ int adlRefreshNumCards(ADL_MIDIPlayer *device)
if(insno == 198)
continue;
++n_total[a / 128];
- const adlinsdata &ins = adlins[insno];
- if((ins.adlno1 != ins.adlno2) && ((ins.flags & adlinsdata::Flag_Pseudo4op) == 0))
+ adlinsdata2 ins(adlins[insno]);
+ if(ins.flags & adlinsdata::Flag_Real4op)
++n_fourop[a / 128];
}
-
- play->m_setup.NumFourOps =
- (n_fourop[0] >= (n_total[0] % 128) * 7 / 8) ? play->m_setup.NumCards * 6
- : (n_fourop[0] < (n_total[0] % 128) * 1 / 8) ? 0
- : (play->m_setup.NumCards == 1 ? 1 : play->m_setup.NumCards * 4);
}
- play->opl.NumFourOps = play->m_setup.NumFourOps;
+ unsigned numFourOps = 0;
- if(n_fourop[0] >= n_total[0] * 15 / 16 && play->m_setup.NumFourOps == 0)
- {
- play->setErrorString("ERROR: You have selected a bank that consists almost exclusively of four-op patches.\n"
- " The results (silence + much cpu load) would be probably\n"
- " not what you want, therefore ignoring the request.\n");
- return -1;
- }
+ // All 2ops (no 4ops)
+ if((n_fourop[0] == 0) && (n_fourop[1] == 0))
+ numFourOps = 0;
+ // All 2op melodics and Some (or All) 4op drums
+ else if((n_fourop[0] == 0) && (n_fourop[1] > 0))
+ numFourOps = 2;
+ // Many 4op melodics
+ else if((n_fourop[0] >= (n_total[0] * 7) / 8))
+ numFourOps = 6;
+ // Few 4op melodics
+ else if(n_fourop[0] > 0)
+ numFourOps = 4;
+
+/* //Old formula
+ unsigned NumFourOps = ((n_fourop[0] == 0) && (n_fourop[1] == 0)) ? 0
+ : (n_fourop[0] >= (n_total[0] * 7) / 8) ? play->m_setup.NumCards * 6
+ : (play->m_setup.NumCards == 1 ? 1 : play->m_setup.NumCards * 4);
+*/
+
+ play->opl.NumFourOps = play->m_setup.NumFourOps = (numFourOps * play->m_setup.NumCards);
return 0;
}
-
diff --git a/src/adlmidi_private.hpp b/src/adlmidi_private.hpp
index 9fd6f97..2499bad 100644
--- a/src/adlmidi_private.hpp
+++ b/src/adlmidi_private.hpp
@@ -35,6 +35,9 @@
# endif
#endif
+// Require declarations of unstable API for extern "C"
+#define ADLMIDI_UNSTABLE_API
+
#ifdef _WIN32
#define NOMINMAX
#endif
@@ -88,17 +91,13 @@ typedef int32_t ssize_t;
#include <cstdarg>
#include <cstdio>
#include <cassert>
-#if !(defined(__APPLE__) && defined(__GLIBCXX__)) && !defined(__ANDROID__)
-#include <cinttypes> //PRId32, PRIu32, etc.
-#else
-#include <inttypes.h>
-#endif
#include <vector> // vector
#include <deque> // deque
#include <cmath> // exp, log, ceil
#if defined(__WATCOMC__)
#include <math.h> // round, sqrt
#endif
+#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits> // numeric_limit
@@ -110,11 +109,26 @@ typedef int32_t ssize_t;
#include <deque>
#include <algorithm>
-#ifdef _MSC_VER
-#pragma warning(disable:4319)
-#pragma warning(disable:4267)
-#pragma warning(disable:4244)
-#pragma warning(disable:4146)
+/*
+ * Workaround for some compilers are has no those macros in their headers!
+ */
+#ifndef INT8_MIN
+#define INT8_MIN (-0x7f - 1)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-0x7fff - 1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-0x7fffffff - 1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX 0x7f
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX 0x7fff
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX 0x7fffffff
#endif
#include "fraction.hpp"
@@ -127,6 +141,8 @@ typedef int32_t ssize_t;
#ifndef ADLMIDI_DISABLE_CPP_EXTRAS
#include "adlmidi.hpp" //Extra C++ API
#endif
+#include "adlmidi_ptr.hpp"
+#include "adlmidi_bankmap.h"
#define ADL_UNUSED(x) (void)x
@@ -144,12 +160,14 @@ inline Real adl_cvtReal(int32_t x)
{
return x * ((Real)1 / INT16_MAX);
}
+
inline int32_t adl_cvtS16(int32_t x)
{
- x = (x < INT16_MIN) ? INT16_MIN : x;
- x = (x > INT16_MAX) ? INT16_MAX : x;
+ x = (x < INT16_MIN) ? (INT16_MIN) : x;
+ x = (x > INT16_MAX) ? (INT16_MAX) : x;
return x;
}
+
inline int32_t adl_cvtS8(int32_t x)
{
return adl_cvtS16(x) / 256;
@@ -181,117 +199,6 @@ inline int32_t adl_cvtU32(int32_t x)
return (uint32_t)adl_cvtS32(x) - (uint32_t)INT32_MIN;
}
-/*
- Smart pointer for C heaps, created with malloc() call.
- FAQ: Why not std::shared_ptr? Because of Android NDK now doesn't supports it
-*/
-template<class PTR>
-class AdlMIDI_CPtr
-{
- PTR *m_p;
-public:
- AdlMIDI_CPtr() : m_p(NULL) {}
- ~AdlMIDI_CPtr()
- {
- reset(NULL);
- }
-
- void reset(PTR *p = NULL)
- {
- if(p != m_p) {
- if(m_p)
- free(m_p);
- m_p = p;
- }
- }
-
- PTR *get()
- {
- return m_p;
- }
- PTR &operator*()
- {
- return *m_p;
- }
- PTR *operator->()
- {
- return m_p;
- }
-private:
- AdlMIDI_CPtr(const AdlMIDI_CPtr &);
- AdlMIDI_CPtr &operator=(const AdlMIDI_CPtr &);
-};
-
-/*
- Shared pointer with non-atomic counter
- FAQ: Why not std::shared_ptr? Because of Android NDK now doesn't supports it
-*/
-template<class VALUE>
-class AdlMIDI_SPtr
-{
- VALUE *m_p;
- size_t *m_counter;
-public:
- AdlMIDI_SPtr() : m_p(NULL), m_counter(NULL) {}
- ~AdlMIDI_SPtr()
- {
- reset(NULL);
- }
-
- AdlMIDI_SPtr(const AdlMIDI_SPtr &other)
- : m_p(other.m_p), m_counter(other.m_counter)
- {
- if(m_counter)
- ++*m_counter;
- }
-
- AdlMIDI_SPtr &operator=(const AdlMIDI_SPtr &other)
- {
- if(this == &other)
- return *this;
- reset();
- m_p = other.m_p;
- m_counter = other.m_counter;
- if(m_counter)
- ++*m_counter;
- return *this;
- }
-
- void reset(VALUE *p = NULL)
- {
- if(p != m_p) {
- if(m_p && --*m_counter == 0)
- delete m_p;
- m_p = p;
- if(!p) {
- if(m_counter) {
- delete m_counter;
- m_counter = NULL;
- }
- }
- else
- {
- if(!m_counter)
- m_counter = new size_t;
- *m_counter = 1;
- }
- }
- }
-
- VALUE *get()
- {
- return m_p;
- }
- VALUE &operator*()
- {
- return *m_p;
- }
- VALUE *operator->()
- {
- return m_p;
- }
-};
-
class MIDIplay;
struct ADL_MIDIPlayer;
class OPL3
@@ -306,27 +213,23 @@ public:
std::vector<AdlMIDI_SPtr<OPLChipBase > > cardsOP2;
#endif
private:
- std::vector<size_t> ins; // index to adl[], cached, needed by Touch()
+ std::vector<adldata> ins; // patch data, cached, needed by Touch()
std::vector<uint8_t> pit; // value poked to B0, cached, needed by NoteOff)(
std::vector<uint8_t> regBD;
friend int adlRefreshNumCards(ADL_MIDIPlayer *device);
- //! Meta information about every instrument
- std::vector<adlinsdata> dynamic_metainstruments; // Replaces adlins[] when CMF file
- //! Raw instrument data ready to be sent to the chip
- std::vector<adldata> dynamic_instruments; // Replaces adl[] when CMF file
- size_t dynamic_percussion_offset;
-
- typedef std::map<uint16_t, size_t> BankMap;
- BankMap dynamic_melodic_banks;
- BankMap dynamic_percussion_banks;
- const unsigned DynamicInstrumentTag /* = 0x8000u*/,
- DynamicMetaInstrumentTag /* = 0x4000000u*/;
- const adlinsdata &GetAdlMetaIns(size_t n);
- size_t GetAdlMetaNumber(size_t midiins);
- const adldata &GetAdlIns(size_t insno);
+public:
+ struct Bank
+ {
+ adlinsdata2 ins[128];
+ };
+ typedef BasicBankMap<Bank> BankMap;
+ BankMap dynamic_banks;
+ AdlBankSetup dynamic_bank_setup;
public:
void setEmbeddedBank(unsigned int bank);
+ static const adlinsdata2 emptyInstrument;
+ enum { PercussionTag = 1 << 15 };
//! Total number of running concurrent emulated chips
unsigned int NumCards;
@@ -342,8 +245,8 @@ public:
bool AdlPercussionMode;
//! Carriers-only are scaled by default by volume level. This flag will tell to scale modulators too.
bool ScaleModulators;
- //! Required to play CMF files. Can be turned on by using of "CMF" volume model
- bool LogarithmicVolumes;
+ // ! Required to play CMF files. Can be turned on by using of "CMF" volume model
+ //bool LogarithmicVolumes; //[REPLACED WITH "m_volumeScale == VOLUME_NATIVE", DEPRECATED!!!]
// ! Required to play EA-MUS files [REPLACED WITH "m_musicMode", DEPRECATED!!!]
//bool CartoonersVolumes;
enum MusicMode
@@ -359,7 +262,7 @@ public:
enum VolumesScale
{
VOLUME_Generic,
- VOLUME_CMF,
+ VOLUME_NATIVE,
VOLUME_DMX,
VOLUME_APOGEE,
VOLUME_9X
@@ -375,15 +278,14 @@ public:
// 7 = percussion Hihat
// 8 = percussion slave
- void Poke(size_t card, uint32_t index, uint32_t value);
- void PokeN(size_t card, uint16_t index, uint8_t value);
+ void Poke(size_t card, uint16_t index, uint8_t value);
void NoteOff(size_t c);
void NoteOn(unsigned c, double hertz);
void Touch_Real(unsigned c, unsigned volume, uint8_t brightness = 127);
//void Touch(unsigned c, unsigned volume)
- void Patch(uint16_t c, size_t i);
+ void Patch(uint16_t c, const adldata &adli);
void Pan(unsigned c, unsigned value);
void Silence();
void updateFlags();
@@ -578,7 +480,7 @@ public:
bool eof()
{
if(fp)
- return std::feof(fp);
+ return (std::feof(fp) != 0);
else
return mp_tell >= mp_size;
}
@@ -596,9 +498,15 @@ public:
uint8_t bank_lsb, bank_msb;
uint8_t patch;
uint8_t volume, expression;
- uint8_t panning, vibrato, sustain;
+ uint8_t panning, vibrato, aftertouch, sustain;
+ //! Per note Aftertouch values
+ uint8_t noteAftertouch[128];
+ //! Is note aftertouch has any non-zero value
+ bool noteAfterTouchInUse;
char ____padding[6];
- double bend, bendsense;
+ int bend;
+ double bendsense;
+ int bendsense_lsb, bendsense_msb;
double vibpos, vibspeed, vibdepth;
int64_t vibdelay;
uint8_t lastlrpn, lastmrpn;
@@ -611,14 +519,15 @@ public:
bool active;
// Current pressure
uint8_t vol;
- char ____padding[1];
+ // Note vibrato (a part of Note Aftertouch feature)
+ uint8_t vibrato;
// Tone selected on noteon:
int16_t tone;
char ____padding2[4];
- // Patch selected on noteon; index to banks[AdlBank][]
+ // Patch selected on noteon; index to bank.ins[]
size_t midiins;
- // Index to physical adlib data structure, adlins[]
- size_t insmeta;
+ // Patch selected
+ const adlinsdata2 *ains;
enum
{
MaxNumPhysChans = 2,
@@ -629,18 +538,18 @@ public:
//! Destination chip channel
uint16_t chip_chan;
//! ins, inde to adl[]
- size_t insId;
+ adldata ains;
//! Is this voice must be detunable?
bool pseudo4op;
void assign(const Phys &oth)
{
- insId = oth.insId;
+ ains = oth.ains;
pseudo4op = oth.pseudo4op;
}
bool operator==(const Phys &oth) const
{
- return (insId == oth.insId) && (pseudo4op == oth.pseudo4op);
+ return (ains == oth.ains) && (pseudo4op == oth.pseudo4op);
}
bool operator!=(const Phys &oth) const
{
@@ -660,7 +569,7 @@ public:
ph = &chip_channels[i];
return ph;
}
- Phys *phys_find_or_create(unsigned chip_chan)
+ Phys *phys_find_or_create(uint16_t chip_chan)
{
Phys *ph = phys_find(chip_chan);
if(!ph) {
@@ -671,7 +580,7 @@ public:
}
return ph;
}
- Phys *phys_ensure_find_or_create(unsigned chip_chan)
+ Phys *phys_ensure_find_or_create(uint16_t chip_chan)
{
Phys *ph = phys_find_or_create(chip_chan);
assert(ph);
@@ -679,9 +588,9 @@ public:
}
void phys_erase_at(const Phys *ph)
{
- unsigned pos = ph - chip_channels;
- assert(pos < chip_channels_count);
- for(unsigned i = pos + 1; i < chip_channels_count; ++i)
+ intptr_t pos = ph - chip_channels;
+ assert(pos < static_cast<intptr_t>(chip_channels_count));
+ for(intptr_t i = pos + 1; i < static_cast<intptr_t>(chip_channels_count); ++i)
chip_channels[i - 1] = chip_channels[i];
--chip_channels_count;
}
@@ -707,7 +616,7 @@ public:
for(++ptr; ptr && !ptr->active;)
ptr = (ptr->note == 127) ? 0 : (ptr + 1);
return *this;
- };
+ }
activenoteiterator operator++(int)
{
activenoteiterator pos = *this;
@@ -770,7 +679,7 @@ public:
void activenotes_clear()
{
- for(unsigned i = 0; i < 128; ++i) {
+ for(uint8_t i = 0; i < 128; ++i) {
activenotes[i].note = i;
activenotes[i].active = false;
}
@@ -790,12 +699,17 @@ public:
}
void resetAllControllers()
{
- bend = 0.0;
- bendsense = 2 / 8192.0;
+ bend = 0;
+ bendsense_msb = 2;
+ bendsense_lsb = 0;
+ updateBendSensitivity();
volume = 100;
expression = 127;
sustain = 0;
vibrato = 0;
+ aftertouch = 0;
+ std::memset(noteAftertouch, 0, 128);
+ noteAfterTouchInUse = false;
vibspeed = 2 * 3.141592653 * 5.0;
vibdepth = 0.5 / 127;
vibdelay = 0;
@@ -803,6 +717,15 @@ public:
portamento = 0;
brightness = 127;
}
+ bool hasVibrato()
+ {
+ return (vibrato > 0) || (aftertouch > 0) || noteAfterTouchInUse;
+ }
+ void updateBendSensitivity()
+ {
+ int cent = bendsense_msb * 128 + bendsense_lsb;
+ bendsense = cent * (1.0 / (128 * 8192));
+ }
MIDIchannel()
{
activenotes_clear();
@@ -829,6 +752,9 @@ public:
bool sustained;
char ____padding[7];
MIDIchannel::NoteInfo::Phys ins; // a copy of that in phys[]
+ //! Has fixed sustain, don't iterate "on" timeout
+ bool fixed_sustain;
+ //! Timeout until note will be allowed to be killed by channel manager while it is on
int64_t kon_time_until_neglible;
int64_t vibdelay;
};
@@ -858,15 +784,21 @@ public:
AdlChannel(const AdlChannel &oth): koff_time_until_neglible(oth.koff_time_until_neglible)
{
- users_assign(oth.users_first, oth.users_size);
+ if(oth.users_first)
+ {
+ users_first = NULL;
+ users_assign(oth.users_first, oth.users_size);
+ }
+ else
+ users_clear();
}
AdlChannel &operator=(const AdlChannel &oth)
- {
- koff_time_until_neglible = oth.koff_time_until_neglible;
- users_assign(oth.users_first, oth.users_size);
- return *this;
- }
+ {
+ koff_time_until_neglible = oth.koff_time_until_neglible;
+ users_assign(oth.users_first, oth.users_size);
+ return *this;
+ }
void AddAge(int64_t ms);
};
@@ -1049,6 +981,8 @@ private:
char ____padding[7];
std::vector<AdlChannel> ch;
+ //! Counter of arpeggio processing
+ size_t m_arpeggioCounter;
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
std::vector<std::vector<uint8_t> > TrackData;
@@ -1272,7 +1206,7 @@ private:
// Determine how good a candidate this adlchannel
// would be for playing a note from this instrument.
- int64_t CalculateAdlChannelGoodness(unsigned c, const MIDIchannel::NoteInfo::Phys &ins, uint16_t /*MidCh*/) const;
+ int64_t CalculateAdlChannelGoodness(size_t c, const MIDIchannel::NoteInfo::Phys &ins, uint16_t /*MidCh*/) const;
// A new note will be played on this channel using this instrument.
// Kill existing notes on this channel (or don't, if we do arpeggio)
diff --git a/src/adlmidi_ptr.hpp b/src/adlmidi_ptr.hpp
new file mode 100644
index 0000000..7d1086b
--- /dev/null
+++ b/src/adlmidi_ptr.hpp
@@ -0,0 +1,217 @@
+/*
+ * libADLMIDI is a free MIDI to WAV conversion library with OPL3 emulation
+ *
+ * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
+ * ADLMIDI Library API: Copyright (c) 2015-2018 Vitaly Novichkov <admin@wohlnet.ru>
+ *
+ * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
+ * http://iki.fi/bisqwit/source/adlmidi.html
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ADLMIDI_PTR_HPP_THING
+#define ADLMIDI_PTR_HPP_THING
+
+#include <algorithm> // swap
+#include <stddef.h>
+#include <stdlib.h>
+
+/*
+ Generic deleters for smart pointers
+ */
+template <class T>
+struct ADLMIDI_DefaultDelete
+{
+ void operator()(T *x) { delete x; }
+};
+template <class T>
+struct ADLMIDI_DefaultArrayDelete
+{
+ void operator()(T *x) { delete[] x; }
+};
+struct ADLMIDI_CDelete
+{
+ void operator()(void *x) { free(x); }
+};
+
+/*
+ Safe unique pointer for C++98, non-copyable but swappable.
+*/
+template< class T, class Deleter = ADLMIDI_DefaultDelete<T> >
+class AdlMIDI_UPtr
+{
+ T *m_p;
+public:
+ explicit AdlMIDI_UPtr(T *p)
+ : m_p(p) {}
+ ~AdlMIDI_UPtr()
+ {
+ reset();
+ }
+
+ void reset(T *p = NULL)
+ {
+ if(p != m_p) {
+ if(m_p) {
+ Deleter del;
+ del(m_p);
+ }
+ m_p = p;
+ }
+ }
+
+ void swap(AdlMIDI_UPtr &other)
+ {
+ std::swap(m_p, other.m_p);
+ }
+
+ T *get() const
+ {
+ return m_p;
+ }
+ T &operator*() const
+ {
+ return *m_p;
+ }
+ T *operator->() const
+ {
+ return m_p;
+ }
+ T &operator[](size_t index) const
+ {
+ return m_p[index];
+ }
+private:
+ AdlMIDI_UPtr(const AdlMIDI_UPtr &);
+ AdlMIDI_UPtr &operator=(const AdlMIDI_UPtr &);
+};
+
+template <class T>
+void swap(AdlMIDI_UPtr<T> &a, AdlMIDI_UPtr<T> &b)
+{
+ a.swap(b);
+}
+
+/**
+ Unique pointer for arrays.
+ */
+template<class T>
+class AdlMIDI_UPtrArray :
+ public AdlMIDI_UPtr< T, ADLMIDI_DefaultArrayDelete<T> >
+{
+public:
+ explicit AdlMIDI_UPtrArray(T *p = NULL)
+ : AdlMIDI_UPtr< T, ADLMIDI_DefaultArrayDelete<T> >(p) {}
+};
+
+/**
+ Unique pointer for C memory.
+ */
+template<class T>
+class AdlMIDI_CPtr :
+ public AdlMIDI_UPtr< T, ADLMIDI_CDelete >
+{
+public:
+ explicit AdlMIDI_CPtr(T *p = NULL)
+ : AdlMIDI_UPtr< T, ADLMIDI_CDelete >(p) {}
+};
+
+/*
+ Shared pointer with non-atomic counter
+ FAQ: Why not std::shared_ptr? Because of Android NDK now doesn't supports it
+*/
+template< class T, class Deleter = ADLMIDI_DefaultDelete<T> >
+class AdlMIDI_SPtr
+{
+ T *m_p;
+ size_t *m_counter;
+public:
+ explicit AdlMIDI_SPtr(T *p = NULL)
+ : m_p(p), m_counter(p ? new size_t(1) : NULL) {}
+ ~AdlMIDI_SPtr()
+ {
+ reset(NULL);
+ }
+
+ AdlMIDI_SPtr(const AdlMIDI_SPtr &other)
+ : m_p(other.m_p), m_counter(other.m_counter)
+ {
+ if(m_counter)
+ ++*m_counter;
+ }
+
+ AdlMIDI_SPtr &operator=(const AdlMIDI_SPtr &other)
+ {
+ if(this == &other)
+ return *this;
+ reset();
+ m_p = other.m_p;
+ m_counter = other.m_counter;
+ if(m_counter)
+ ++*m_counter;
+ return *this;
+ }
+
+ void reset(T *p = NULL)
+ {
+ if(p != m_p) {
+ if(m_p && --*m_counter == 0) {
+ Deleter del;
+ del(m_p);
+ if(!p) {
+ delete m_counter;
+ m_counter = NULL;
+ }
+ }
+ m_p = p;
+ if(p) {
+ if(!m_counter)
+ m_counter = new size_t;
+ *m_counter = 1;
+ }
+ }
+ }
+
+ T *get() const
+ {
+ return m_p;
+ }
+ T &operator*() const
+ {
+ return *m_p;
+ }
+ T *operator->() const
+ {
+ return m_p;
+ }
+ T &operator[](size_t index) const
+ {
+ return m_p[index];
+ }
+};
+
+/**
+ Shared pointer for arrays.
+ */
+template<class T>
+class AdlMIDI_SPtrArray :
+ public AdlMIDI_SPtr< T, ADLMIDI_DefaultArrayDelete<T> >
+{
+public:
+ explicit AdlMIDI_SPtrArray(T *p = NULL)
+ : AdlMIDI_SPtr< T, ADLMIDI_DefaultArrayDelete<T> >(p) {}
+};
+
+#endif //ADLMIDI_PTR_HPP_THING
diff --git a/src/chips/dosbox/dbopl.cpp b/src/chips/dosbox/dbopl.cpp
index 3e21772..7d78c5f 100644
--- a/src/chips/dosbox/dbopl.cpp
+++ b/src/chips/dosbox/dbopl.cpp
@@ -1,10 +1,5 @@
-//#ifdef ADLMIDI_USE_DOSBOX_OPL
-
-#ifdef __MINGW32__
-typedef struct vswprintf {} swprintf;
-#endif
/*
- * Copyright (C) 2002-2010 The DOSBox Team
+ * Copyright (C) 2002-2018 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,22 +17,21 @@ typedef struct vswprintf {} swprintf;
*/
/*
- DOSBox implementation of a combined Yamaha YMF262 and Yamaha YM3812 emulator.
- Enabling the opl3 bit will switch the emulator to stereo opl3 output instead of regular mono opl2
- Except for the table generation it's all integer math
- Can choose different types of generators, using muls and bigger tables, try different ones for slower platforms
- The generation was based on the MAME implementation but tried to have it use less memory and be faster in general
- MAME uses much bigger envelope tables and this will be the biggest cause of it sounding different at times
-
- //TODO Don't delay first operator 1 sample in opl3 mode
- //TODO Maybe not use class method pointers but a regular function pointers with operator as first parameter
- //TODO Fix panning for the Percussion channels, would any opl3 player use it and actually really change it though?
- //TODO Check if having the same accuracy in all frequency multipliers sounds better or not
-
- //DUNNO Keyon in 4op, switch to 2op without keyoff.
+ DOSBox implementation of a combined Yamaha YMF262 and Yamaha YM3812 emulator.
+ Enabling the opl3 bit will switch the emulator to stereo opl3 output instead of regular mono opl2
+ Except for the table generation it's all integer math
+ Can choose different types of generators, using muls and bigger tables, try different ones for slower platforms
+ The generation was based on the MAME implementation but tried to have it use less memory and be faster in general
+ MAME uses much bigger envelope tables and this will be the biggest cause of it sounding different at times
+
+ //TODO Don't delay first operator 1 sample in opl3 mode
+ //TODO Maybe not use class method pointers but a regular function pointers with operator as first parameter
+ //TODO Fix panning for the Percussion channels, would any opl3 player use it and actually really change it though?
+ //TODO Check if having the same accuracy in all frequency multipliers sounds better or not
+
+ //DUNNO Keyon in 4op, switch to 2op without keyoff.
*/
-/* $Id: dbopl.cpp,v 1.10 2009-06-10 19:54:51 harekiet Exp $ */
#include <math.h>
@@ -45,2001 +39,1580 @@ typedef struct vswprintf {} swprintf;
#include <string.h>
#include "dbopl.h"
-#define DB_MAX(x, y) ((x) > (y) ? (x) : (y))
-#define DB_MIN(x, y) ((x) < (y) ? (x) : (y))
+#if defined(__GNUC__) && __GNUC__ > 3
+#define INLINE inline __attribute__((__always_inline__))
+#elif defined(_MSC_VER)
+#define INLINE __forceinline
+#else
+#define INLINE inline
+#endif
-#define DBOPL_CLAMP(V, MIN, MAX) DB_MAX(DB_MIN(V, (MAX)), (MIN))
+#if defined(__GNUC__)
+#if !defined(__clang__)
+#define GCC_LIKELY(x) __builtin_expect(x, 1)
+#define GCC_UNLIKELY(x) __builtin_expect(x, 0)
+#else // !defined(__clang__)
+#if !defined (__c2__) && defined(__has_builtin)
+#if __has_builtin(__builtin_expect)
+#define GCC_LIKELY(x) __builtin_expect(x, 1)
+#define GCC_UNLIKELY(x) __builtin_expect(x, 0)
+#endif // __has_builtin(__builtin_expect)
+#endif // !defined (__c2__) && defined(__has_builtin)
+#endif // !defined(__clang__)
+#endif // defined(__GNUC__)
+
+#if !defined(GCC_LIKELY)
+#define GCC_LIKELY(x) (x)
+#define GCC_UNLIKELY(x) (x)
+#endif
#ifndef PI
#define PI 3.14159265358979323846
#endif
-namespace DBOPL
-{
+namespace DBOPL {
-#define OPLRATE ((double)(14318180.0 / 288.0))
+#define OPLRATE ((double)(14318180.0 / 288.0))
#define TREMOLO_TABLE 52
- //Try to use most precision for frequencies
- //Else try to keep different waves in synch
- //#define WAVE_PRECISION 1
- #ifndef WAVE_PRECISION
- //Wave bits available in the top of the 32bit range
- //Original adlib uses 10.10, we use 10.22
-#define WAVE_BITS 10
- #else
- //Need some extra bits at the top to have room for octaves and frequency multiplier
- //We support to 8 times lower rate
- //128 * 15 * 8 = 15350, 2^13.9, so need 14 bits
-#define WAVE_BITS 14
- #endif
-#define WAVE_SH ( 32 - WAVE_BITS )
-#define WAVE_MASK ( ( 1 << WAVE_SH ) - 1 )
-
- //Use the same accuracy as the waves
+//Try to use most precision for frequencies
+//Else try to keep different waves in synch
+//#define WAVE_PRECISION 1
+#ifndef WAVE_PRECISION
+//Wave bits available in the top of the 32bit range
+//Original adlib uses 10.10, we use 10.22
+#define WAVE_BITS 10
+#else
+//Need some extra bits at the top to have room for octaves and frequency multiplier
+//We support to 8 times lower rate
+//128 * 15 * 8 = 15350, 2^13.9, so need 14 bits
+#define WAVE_BITS 14
+#endif
+#define WAVE_SH ( 32 - WAVE_BITS )
+#define WAVE_MASK ( ( 1 << WAVE_SH ) - 1 )
+
+//Use the same accuracy as the waves
#define LFO_SH ( WAVE_SH - 10 )
- //LFO is controlled by our tremolo 256 sample limit
+//LFO is controlled by our tremolo 256 sample limit
#define LFO_MAX ( 256 << ( LFO_SH ) )
- //Maximum amount of attenuation bits
- //Envelope goes to 511, 9 bits
- #if (DBOPL_WAVE == WAVE_TABLEMUL )
- //Uses the value directly
-#define ENV_BITS ( 9 )
- #else
- //Add 3 bits here for more accuracy and would have to be shifted up either way
-#define ENV_BITS ( 9 )
- #endif
- //Limits of the envelope with those bits and when the envelope goes silent
-#define ENV_MIN 0
-#define ENV_EXTRA ( ENV_BITS - 9 )
-#define ENV_MAX ( 511 << ENV_EXTRA )
-#define ENV_LIMIT ( ( 12 * 256) >> ( 3 - ENV_EXTRA ) )
+//Maximum amount of attenuation bits
+//Envelope goes to 511, 9 bits
+#if (DBOPL_WAVE == WAVE_TABLEMUL )
+//Uses the value directly
+#define ENV_BITS ( 9 )
+#else
+//Add 3 bits here for more accuracy and would have to be shifted up either way
+#define ENV_BITS ( 9 )
+#endif
+//Limits of the envelope with those bits and when the envelope goes silent
+#define ENV_MIN 0
+#define ENV_EXTRA ( ENV_BITS - 9 )
+#define ENV_MAX ( 511 << ENV_EXTRA )
+#define ENV_LIMIT ( ( 12 * 256) >> ( 3 - ENV_EXTRA ) )
#define ENV_SILENT( _X_ ) ( (_X_) >= ENV_LIMIT )
- //Attack/decay/release rate counter shift
-#define RATE_SH 24
-#define RATE_MASK ( ( 1 << RATE_SH ) - 1 )
- //Has to fit within 16bit lookuptable
-#define MUL_SH 16
+//Attack/decay/release rate counter shift
+#define RATE_SH 24
+#define RATE_MASK ( ( 1 << RATE_SH ) - 1 )
+//Has to fit within 16bit lookuptable
+#define MUL_SH 16
- //Check some ranges
- #if ENV_EXTRA > 3
+//Check some ranges
+#if ENV_EXTRA > 3
#error Too many envelope bits
- #endif
+#endif
- //How much to substract from the base value for the final attenuation
- static const Bit8u KslCreateTable[16] =
- {
- //0 will always be be lower than 7 * 8
- 64, 32, 24, 19,
- 16, 12, 11, 10,
- 8, 6, 5, 4,
- 3, 2, 1, 0,
- };
+//How much to substract from the base value for the final attenuation
+static const Bit8u KslCreateTable[16] = {
+ //0 will always be be lower than 7 * 8
+ 64, 32, 24, 19,
+ 16, 12, 11, 10,
+ 8, 6, 5, 4,
+ 3, 2, 1, 0,
+};
#define M(_X_) ((Bit8u)( (_X_) * 2))
- static const Bit8u FreqCreateTable[16] =
- {
- M(0.5), M(1), M(2), M(3), M(4), M(5), M(6), M(7),
- M(8), M(9), M(10), M(10), M(12), M(12), M(15), M(15)
- };
+static const Bit8u FreqCreateTable[16] = {
+ M(0.5), M(1 ), M(2 ), M(3 ), M(4 ), M(5 ), M(6 ), M(7 ),
+ M(8 ), M(9 ), M(10), M(10), M(12), M(12), M(15), M(15)
+};
#undef M
- //We're not including the highest attack rate, that gets a special value
- static const Bit8u AttackSamplesTable[13] =
- {
- 69, 55, 46, 40,
- 35, 29, 23, 20,
- 19, 15, 11, 10,
- 9
- };
- //On a real opl these values take 8 samples to reach and are based upon larger tables
- static const Bit8u EnvelopeIncreaseTable[13] =
- {
- 4, 5, 6, 7,
- 8, 10, 12, 14,
- 16, 20, 24, 28,
- 32,
- };
-
- #if ( DBOPL_WAVE == WAVE_HANDLER ) || ( DBOPL_WAVE == WAVE_TABLELOG )
- static Bit16u ExpTable[ 256 ];
- #endif
-
- #if ( DBOPL_WAVE == WAVE_HANDLER )
- //PI table used by WAVEHANDLER
- static Bit16u SinTable[ 512 ];
- #endif
-
- #if ( DBOPL_WAVE > WAVE_HANDLER )
- //Layout of the waveform table in 512 entry intervals
- //With overlapping waves we reduce the table to half it's size
-
- // | |//\\|____|WAV7|//__|/\ |____|/\/\|
- // |\\//| | |WAV7| | \/| | |
- // |06 |0126|17 |7 |3 |4 |4 5 |5 |
-
- //6 is just 0 shifted and masked
-
- static Bit16s WaveTable[ 8 * 512 ];
- //Distance into WaveTable the wave starts
- static const Bit16u WaveBaseTable[8] =
- {
- 0x000, 0x200, 0x200, 0x800,
- 0xa00, 0xc00, 0x100, 0x400,
-
- };
- //Mask the counter with this
- static const Bit16u WaveMaskTable[8] =
- {
- 1023, 1023, 511, 511,
- 1023, 1023, 512, 1023,
- };
-
- //Where to start the counter on at keyon
- static const Bit16u WaveStartTable[8] =
- {
- 512, 0, 0, 0,
- 0, 512, 512, 256,
- };
- #endif
-
- #if ( DBOPL_WAVE == WAVE_TABLEMUL )
- static Bit16u MulTable[ 384 ];
- #endif
-
- static Bit8u KslTable[ 8 * 16 ];
- static Bit8u TremoloTable[ TREMOLO_TABLE ];
- //Start of a channel behind the chip struct start
- static Bit16u ChanOffsetTable[32];
- //Start of an operator behind the chip struct start
- static Bit16u OpOffsetTable[64];
-
- //The lower bits are the shift of the operator vibrato value
- //The highest bit is right shifted to generate -1 or 0 for negation
- //So taking the highest input value of 7 this gives 3, 7, 3, 0, -3, -7, -3, 0
- static const Bit8s VibratoTable[ 8 ] =
- {
- 1 - 0x00, 0 - 0x00, 1 - 0x00, 30 - 0x00,
- 1 - 0x80, 0 - 0x80, 1 - 0x80, 30 - 0x80
- };
-
- //Shift strength for the ksl value determined by ksl strength
- static const Bit8u KslShiftTable[4] =
- {
- 31, 1, 2, 0
- };
-
- //Generate a table index and table shift value using input value from a selected rate
- static void EnvelopeSelect(Bit8u val, Bit8u &index, Bit8u &shift)
- {
- if(val < 13 * 4) //Rate 0 - 12
- {
- shift = 12 - (val >> 2);
- index = val & 3;
- }
- else if(val < 15 * 4) //rate 13 - 14
- {
- shift = 0;
- index = val - 12 * 4;
- }
- else //rate 15 and up
- {
- shift = 0;
- index = 12;
- }
- }
-
- #if ( DBOPL_WAVE == WAVE_HANDLER )
- /*
- Generate the different waveforms out of the sine/exponetial table using handlers
- */
- static inline Bits MakeVolume(Bitu wave, Bitu volume)
- {
- Bitu total = wave + volume;
- Bitu index = total & 0xff;
- Bitu sig = ExpTable[ index ];
- Bitu exp = total >> 8;
- #if 0
-
- //Check if we overflow the 31 shift limit
- if(exp >= 32)
- LOG_MSG("WTF %d %d", total, exp);
-
- #endif
- return (sig >> exp);
- };
-
- static Bits DB_FASTCALL WaveForm0(Bitu i, Bitu volume)
- {
- Bits neg = 0 - ((i >> 9) & 1); //Create ~0 or 0
- Bitu wave = SinTable[i & 511];
- return (MakeVolume(wave, volume) ^ neg) - neg;
- }
- static Bits DB_FASTCALL WaveForm1(Bitu i, Bitu volume)
- {
- Bit32u wave = SinTable[i & 511];
- wave |= (((i ^ 512) & 512) - 1) >> (32 - 12);
- return MakeVolume(wave, volume);
- }
- static Bits DB_FASTCALL WaveForm2(Bitu i, Bitu volume)
- {
- Bitu wave = SinTable[i & 511];
- return MakeVolume(wave, volume);
- }
- static Bits DB_FASTCALL WaveForm3(Bitu i, Bitu volume)
- {
- Bitu wave = SinTable[i & 255];
- wave |= (((i ^ 256) & 256) - 1) >> (32 - 12);
- return MakeVolume(wave, volume);
- }
- static Bits DB_FASTCALL WaveForm4(Bitu i, Bitu volume)
- {
- //Twice as fast
- i <<= 1;
- Bits neg = 0 - ((i >> 9) & 1); //Create ~0 or 0
- Bitu wave = SinTable[i & 511];
- wave |= (((i ^ 512) & 512) - 1) >> (32 - 12);
- return (MakeVolume(wave, volume) ^ neg) - neg;
- }
- static Bits DB_FASTCALL WaveForm5(Bitu i, Bitu volume)
- {
- //Twice as fast
- i <<= 1;
- Bitu wave = SinTable[i & 511];
- wave |= (((i ^ 512) & 512) - 1) >> (32 - 12);
- return MakeVolume(wave, volume);
- }
- static Bits DB_FASTCALL WaveForm6(Bitu i, Bitu volume)
- {
- Bits neg = 0 - ((i >> 9) & 1); //Create ~0 or 0
- return (MakeVolume(0, volume) ^ neg) - neg;
- }
- static Bits DB_FASTCALL WaveForm7(Bitu i, Bitu volume)
- {
- //Negative is reversed here
- Bits neg = ((i >> 9) & 1) - 1;
- Bitu wave = (i << 3);
- //When negative the volume also runs backwards
- wave = ((wave ^ neg) - neg) & 4095;
- return (MakeVolume(wave, volume) ^ neg) - neg;
- }
-
- static const WaveHandler WaveHandlerTable[8] =
- {
- WaveForm0, WaveForm1, WaveForm2, WaveForm3,
- WaveForm4, WaveForm5, WaveForm6, WaveForm7
- };
-
- #endif
-
- /*
- Operator
- */
-
- //We zero out when rate == 0
- inline void Operator::UpdateAttack(const Chip *chip)
- {
- Bit8u rate = reg60 >> 4;
-
- if(rate)
- {
- Bit8u val = (rate << 2) + ksr;
- attackAdd = chip->attackRates[ val ];
- rateZero &= ~(1 << ATTACK);
- }
- else
- {
- attackAdd = 0;
- rateZero |= (1 << ATTACK);
- }
- }
- inline void Operator::UpdateDecay(const Chip *chip)
- {
- Bit8u rate = reg60 & 0xf;
-
- if(rate)
- {
- Bit8u val = (rate << 2) + ksr;
- decayAdd = chip->linearRates[ val ];
- rateZero &= ~(1 << DECAY);
- }
- else
- {
- decayAdd = 0;
- rateZero |= (1 << DECAY);
- }
- }
- inline void Operator::UpdateRelease(const Chip *chip)
- {
- Bit8u rate = reg80 & 0xf;
-
- if(rate)
- {
- Bit8u val = (rate << 2) + ksr;
- releaseAdd = chip->linearRates[ val ];
- rateZero &= ~(1 << RELEASE);
-
- if(!(reg20 & MASK_SUSTAIN))
- rateZero &= ~(1 << SUSTAIN);
- }
- else
- {
- rateZero |= (1 << RELEASE);
- releaseAdd = 0;
-
- if(!(reg20 & MASK_SUSTAIN))
- rateZero |= (1 << SUSTAIN);
- }
- }
-
- inline void Operator::UpdateAttenuation()
- {
- Bit8u kslBase = (Bit8u)((chanData >> SHIFT_KSLBASE) & 0xff);
- Bit32u tl = reg40 & 0x3f;
- Bit8u kslShift = KslShiftTable[ reg40 >> 6 ];
- //Make sure the attenuation goes to the right bits
- totalLevel = tl << (ENV_BITS - 7); //Total level goes 2 bits below max
- totalLevel += (kslBase << ENV_EXTRA) >> kslShift;
- }
-
- void Operator::UpdateFrequency()
- {
- Bit32u freq = chanData & ((1 << 10) - 1);
- Bit32u block = (chanData >> 10) & 0xff;
- #ifdef WAVE_PRECISION
- block = 7 - block;
- waveAdd = (freq * freqMul) >> block;
- #else
- waveAdd = (freq << block) * freqMul;
- #endif
-
- if(reg20 & MASK_VIBRATO)
- {
- vibStrength = (Bit8u)(freq >> 7);
- #ifdef WAVE_PRECISION
- vibrato = (vibStrength * freqMul) >> block;
- #else
- vibrato = (vibStrength << block) * freqMul;
- #endif
- }
- else
- {
- vibStrength = 0;
- vibrato = 0;
- }
- }
-
- void Operator::UpdateRates(const Chip *chip)
- {
- //Mame seems to reverse this where enabling ksr actually lowers
- //the rate, but pdf manuals says otherwise?
- Bit8u newKsr = (Bit8u)((chanData >> SHIFT_KEYCODE) & 0xff);
-
- if(!(reg20 & MASK_KSR))
- newKsr >>= 2;
-
- if(ksr == newKsr)
- return;
-
- ksr = newKsr;
- UpdateAttack(chip);
- UpdateDecay(chip);
- UpdateRelease(chip);
- }
-
- INLINE Bit32s Operator::RateForward(Bit32u add)
- {
- rateIndex += add;
- Bit32s ret = rateIndex >> RATE_SH;
- rateIndex = rateIndex & RATE_MASK;
- return ret;
- }
-
- template< Operator::State yes>
- Bits Operator::TemplateVolume()
- {
- Bit32s vol = volume;
- Bit32s change;
-
- switch(yes)
- {
- case OFF:
- return ENV_MAX;
-
- case ATTACK:
- change = RateForward(attackAdd);
-
- if(!change)
- return vol;
-
- vol += ((~vol) * change) >> 3;
-
- if(vol < ENV_MIN)
- {
- volume = ENV_MIN;
- rateIndex = 0;
- SetState(DECAY);
- return ENV_MIN;
- }
-
- break;
-
- case DECAY:
- vol += RateForward(decayAdd);
-
- if(GCC_UNLIKELY(vol >= sustainLevel))
- {
- //Check if we didn't overshoot max attenuation, then just go off
- if(GCC_UNLIKELY(vol >= ENV_MAX))
- {
- volume = ENV_MAX;
- SetState(OFF);
- return ENV_MAX;
- }
-
- //Continue as sustain
- rateIndex = 0;
- SetState(SUSTAIN);
- }
-
- break;
-
- case SUSTAIN:
- if(reg20 & MASK_SUSTAIN)
- return vol;
-
- //In sustain phase, but not sustaining, do regular release
- case RELEASE:
- vol += RateForward(releaseAdd);;
-
- if(GCC_UNLIKELY(vol >= ENV_MAX))
- {
- volume = ENV_MAX;
- SetState(OFF);
- return ENV_MAX;
- }
-
- break;
- }
-
- volume = vol;
- return vol;
- }
-
- static const VolumeHandler VolumeHandlerTable[5] =
- {
- &Operator::TemplateVolume< Operator::OFF >,
- &Operator::TemplateVolume< Operator::RELEASE >,
- &Operator::TemplateVolume< Operator::SUSTAIN >,
- &Operator::TemplateVolume< Operator::DECAY >,
- &Operator::TemplateVolume< Operator::ATTACK >
- };
-
- INLINE Bitu Operator::ForwardVolume()
- {
- return currentLevel + (this->*volHandler)();
- }
-
-
- INLINE Bitu Operator::ForwardWave()
- {
- waveIndex += waveCurrent;
- return waveIndex >> WAVE_SH;
- }
-
- void Operator::Write20(const Chip *chip, Bit8u val)
- {
- Bit8u change = (reg20 ^ val);
-
- if(!change)
- return;
-
- reg20 = val;
- //Shift the tremolo bit over the entire register, saved a branch, YES!
- tremoloMask = (Bit8s)(val) >> 7;
- tremoloMask &= ~((1 << ENV_EXTRA) - 1);
-
- //Update specific features based on changes
- if(change & MASK_KSR)
- UpdateRates(chip);
-
- //With sustain enable the volume doesn't change
- if(reg20 & MASK_SUSTAIN || (!releaseAdd))
- rateZero |= (1 << SUSTAIN);
- else
- rateZero &= ~(1 << SUSTAIN);
-
- //Frequency multiplier or vibrato changed
- if(change & (0xf | MASK_VIBRATO))
- {
- freqMul = chip->freqMul[ val & 0xf ];
- UpdateFrequency();
- }
- }
-
- void Operator::Write40(const Chip * /*chip*/, Bit8u val)
- {
- if(!(reg40 ^ val))
- return;
-
- reg40 = val;
- UpdateAttenuation();
- }
-
- void Operator::Write60(const Chip *chip, Bit8u val)
- {
- Bit8u change = reg60 ^ val;
- reg60 = val;
-
- if(change & 0x0f)
- UpdateDecay(chip);
-
- if(change & 0xf0)
- UpdateAttack(chip);
- }
-
- void Operator::Write80(const Chip *chip, Bit8u val)
- {
- Bit8u change = (reg80 ^ val);
-
- if(!change)
- return;
-
- reg80 = val;
- Bit8u sustain = val >> 4;
- //Turn 0xf into 0x1f
- sustain |= (sustain + 1) & 0x10;
- sustainLevel = sustain << (ENV_BITS - 5);
-
- if(change & 0x0f)
- UpdateRelease(chip);
- }
-
- void Operator::WriteE0(const Chip *chip, Bit8u val)
- {
- if(!(regE0 ^ val))
- return;
-
- //in opl3 mode you can always selet 7 waveforms regardless of waveformselect
- Bit8u waveForm = val & ((0x3 & chip->waveFormMask) | (0x7 & chip->opl3Active));
- regE0 = val;
- #if ( DBOPL_WAVE == WAVE_HANDLER )
- waveHandler = WaveHandlerTable[ waveForm ];
- #else
- waveBase = WaveTable + WaveBaseTable[ waveForm ];
- waveStart = WaveStartTable[ waveForm ] << WAVE_SH;
- waveMask = WaveMaskTable[ waveForm ];
- #endif
- }
-
- INLINE void Operator::SetState(Bit8u s)
- {
- state = s;
- volHandler = VolumeHandlerTable[ s ];
- }
-
- INLINE bool Operator::Silent() const
- {
- if(!ENV_SILENT(totalLevel + volume))
- return false;
-
- if(!(rateZero & (1 << state)))
- return false;
-
- return true;
- }
-
- INLINE void Operator::Prepare(const Chip *chip)
- {
- currentLevel = totalLevel + (chip->tremoloValue & tremoloMask);
- waveCurrent = waveAdd;
-
- if(vibStrength >> chip->vibratoShift)
- {
- Bit32s add = vibrato >> chip->vibratoShift;
- //Sign extend over the shift value
- Bit32s neg = chip->vibratoSign;
- //Negate the add with -1 or 0
- add = (add ^ neg) - neg;
- waveCurrent += add;
- }
- }
-
- void Operator::KeyOn(Bit8u mask)
- {
- if(!keyOn)
- {
- //Restart the frequency generator
- #if ( DBOPL_WAVE > WAVE_HANDLER )
- waveIndex = waveStart;
- #else
- waveIndex = 0;
- #endif
- rateIndex = 0;
- SetState(ATTACK);
- }
-
- keyOn |= mask;
- }
-
- void Operator::KeyOff(Bit8u mask)
- {
- keyOn &= ~mask;
-
- if(!keyOn)
- {
- if(state != OFF)
- SetState(RELEASE);
- }
- }
-
- INLINE Bits Operator::GetWave(Bitu index, Bitu vol)
- {
- #if ( DBOPL_WAVE == WAVE_HANDLER )
- return waveHandler(index, vol << (3 - ENV_EXTRA));
- #elif ( DBOPL_WAVE == WAVE_TABLEMUL )
- return (waveBase[ index & waveMask ] * MulTable[ vol >> ENV_EXTRA ]) >> MUL_SH;
- #elif ( DBOPL_WAVE == WAVE_TABLELOG )
- Bit32s wave = waveBase[ index & waveMask ];
- Bit32u total = (wave & 0x7fff) + vol << (3 - ENV_EXTRA);
- Bit32s sig = ExpTable[ total & 0xff ];
- Bit32u exp = total >> 8;
- Bit32s neg = wave >> 16;
- return ((sig ^ neg) - neg) >> exp;
- #else
+//We're not including the highest attack rate, that gets a special value
+static const Bit8u AttackSamplesTable[13] = {
+ 69, 55, 46, 40,
+ 35, 29, 23, 20,
+ 19, 15, 11, 10,
+ 9
+};
+//On a real opl these values take 8 samples to reach and are based upon larger tables
+static const Bit8u EnvelopeIncreaseTable[13] = {
+ 4, 5, 6, 7,
+ 8, 10, 12, 14,
+ 16, 20, 24, 28,
+ 32,
+};
+
+#if ( DBOPL_WAVE == WAVE_HANDLER ) || ( DBOPL_WAVE == WAVE_TABLELOG )
+static Bit16u ExpTable[ 256 ];
+#endif
+
+#if ( DBOPL_WAVE == WAVE_HANDLER )
+//PI table used by WAVEHANDLER
+static Bit16u SinTable[ 512 ];
+#endif
+
+#if ( DBOPL_WAVE > WAVE_HANDLER )
+//Layout of the waveform table in 512 entry intervals
+//With overlapping waves we reduce the table to half it's size
+
+// | |//\\|____|WAV7|//__|/\ |____|/\/\|
+// |\\//| | |WAV7| | \/| | |
+// |06 |0126|17 |7 |3 |4 |4 5 |5 |
+
+//6 is just 0 shifted and masked
+
+static Bit16s WaveTable[ 8 * 512 ];
+//Distance into WaveTable the wave starts
+static const Bit16u WaveBaseTable[8] = {
+ 0x000, 0x200, 0x200, 0x800,
+ 0xa00, 0xc00, 0x100, 0x400,
+
+};
+//Mask the counter with this
+static const Bit16u WaveMaskTable[8] = {
+ 1023, 1023, 511, 511,
+ 1023, 1023, 512, 1023,
+};
+
+//Where to start the counter on at keyon
+static const Bit16u WaveStartTable[8] = {
+ 512, 0, 0, 0,
+ 0, 512, 512, 256,
+};
+#endif
+
+#if ( DBOPL_WAVE == WAVE_TABLEMUL )
+static Bit16u MulTable[ 384 ];
+#endif
+
+static Bit8u KslTable[ 8 * 16 ];
+static Bit8u TremoloTable[ TREMOLO_TABLE ];
+//Start of a channel behind the chip struct start
+static Bit16u ChanOffsetTable[32];
+//Start of an operator behind the chip struct start
+static Bit16u OpOffsetTable[64];
+
+//The lower bits are the shift of the operator vibrato value
+//The highest bit is right shifted to generate -1 or 0 for negation
+//So taking the highest input value of 7 this gives 3, 7, 3, 0, -3, -7, -3, 0
+static const Bit8s VibratoTable[ 8 ] = {
+ 1 - 0x00, 0 - 0x00, 1 - 0x00, 30 - 0x00,
+ 1 - 0x80, 0 - 0x80, 1 - 0x80, 30 - 0x80
+};
+
+//Shift strength for the ksl value determined by ksl strength
+static const Bit8u KslShiftTable[4] = {
+ 31,1,2,0
+};
+
+//Generate a table index and table shift value using input value from a selected rate
+static void EnvelopeSelect( Bit8u val, Bit8u& index, Bit8u& shift ) {
+ if ( val < 13 * 4 ) { //Rate 0 - 12
+ shift = 12 - ( val >> 2 );
+ index = val & 3;
+ } else if ( val < 15 * 4 ) { //rate 13 - 14
+ shift = 0;
+ index = val - 12 * 4;
+ } else { //rate 15 and up
+ shift = 0;
+ index = 12;
+ }
+}
+
+#if ( DBOPL_WAVE == WAVE_HANDLER )
+/*
+ Generate the different waveforms out of the sine/exponetial table using handlers
+*/
+static inline Bits MakeVolume( Bitu wave, Bitu volume ) {
+ Bitu total = wave + volume;
+ Bitu index = total & 0xff;
+ Bitu sig = ExpTable[ index ];
+ Bitu exp = total >> 8;
+#if 0
+ //Check if we overflow the 31 shift limit
+ if ( exp >= 32 ) {
+ LOG_MSG( "WTF %d %d", total, exp );
+ }
+#endif
+ return (sig >> exp);
+};
+
+static Bits DB_FASTCALL WaveForm0( Bitu i, Bitu volume ) {
+ Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0
+ Bitu wave = SinTable[i & 511];
+ return (MakeVolume( wave, volume ) ^ neg) - neg;
+}
+static Bits DB_FASTCALL WaveForm1( Bitu i, Bitu volume ) {
+ Bit32u wave = SinTable[i & 511];
+ wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 );
+ return MakeVolume( wave, volume );
+}
+static Bits DB_FASTCALL WaveForm2( Bitu i, Bitu volume ) {
+ Bitu wave = SinTable[i & 511];
+ return MakeVolume( wave, volume );
+}
+static Bits DB_FASTCALL WaveForm3( Bitu i, Bitu volume ) {
+ Bitu wave = SinTable[i & 255];
+ wave |= ( ( (i ^ 256 ) & 256) - 1) >> ( 32 - 12 );
+ return MakeVolume( wave, volume );
+}
+static Bits DB_FASTCALL WaveForm4( Bitu i, Bitu volume ) {
+ //Twice as fast
+ i <<= 1;
+ Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0
+ Bitu wave = SinTable[i & 511];
+ wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 );
+ return (MakeVolume( wave, volume ) ^ neg) - neg;
+}
+static Bits DB_FASTCALL WaveForm5( Bitu i, Bitu volume ) {
+ //Twice as fast
+ i <<= 1;
+ Bitu wave = SinTable[i & 511];
+ wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 );
+ return MakeVolume( wave, volume );
+}
+static Bits DB_FASTCALL WaveForm6( Bitu i, Bitu volume ) {
+ Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0
+ return (MakeVolume( 0, volume ) ^ neg) - neg;
+}
+static Bits DB_FASTCALL WaveForm7( Bitu i, Bitu volume ) {
+ //Negative is reversed here
+ Bits neg = (( i >> 9) & 1) - 1;
+ Bitu wave = (i << 3);
+ //When negative the volume also runs backwards
+ wave = ((wave ^ neg) - neg) & 4095;
+ return (MakeVolume( wave, volume ) ^ neg) - neg;
+}
+
+static const WaveHandler WaveHandlerTable[8] = {
+ WaveForm0, WaveForm1, WaveForm2, WaveForm3,
+ WaveForm4, WaveForm5, WaveForm6, WaveForm7
+};
+
+#endif
+
+/*
+ Operator
+*/
+
+//We zero out when rate == 0
+inline void Operator::UpdateAttack( const Chip* chip ) {
+ Bit8u rate = reg60 >> 4;
+ if ( rate ) {
+ Bit8u val = (rate << 2) + ksr;
+ attackAdd = chip->attackRates[ val ];
+ rateZero &= ~(1 << ATTACK);
+ } else {
+ attackAdd = 0;
+ rateZero |= (1 << ATTACK);
+ }
+}
+inline void Operator::UpdateDecay( const Chip* chip ) {
+ Bit8u rate = reg60 & 0xf;
+ if ( rate ) {
+ Bit8u val = (rate << 2) + ksr;
+ decayAdd = chip->linearRates[ val ];
+ rateZero &= ~(1 << DECAY);
+ } else {
+ decayAdd = 0;
+ rateZero |= (1 << DECAY);
+ }
+}
+inline void Operator::UpdateRelease( const Chip* chip ) {
+ Bit8u rate = reg80 & 0xf;
+ if ( rate ) {
+ Bit8u val = (rate << 2) + ksr;
+ releaseAdd = chip->linearRates[ val ];
+ rateZero &= ~(1 << RELEASE);
+ if ( !(reg20 & MASK_SUSTAIN ) ) {
+ rateZero &= ~( 1 << SUSTAIN );
+ }
+ } else {
+ rateZero |= (1 << RELEASE);
+ releaseAdd = 0;
+ if ( !(reg20 & MASK_SUSTAIN ) ) {
+ rateZero |= ( 1 << SUSTAIN );
+ }
+ }
+}
+
+inline void Operator::UpdateAttenuation( ) {
+ Bit8u kslBase = (Bit8u)((chanData >> SHIFT_KSLBASE) & 0xff);
+ Bit32u tl = reg40 & 0x3f;
+ Bit8u kslShift = KslShiftTable[ reg40 >> 6 ];
+ //Make sure the attenuation goes to the right bits
+ totalLevel = tl << ( ENV_BITS - 7 ); //Total level goes 2 bits below max
+ totalLevel += ( kslBase << ENV_EXTRA ) >> kslShift;
+}
+
+void Operator::UpdateFrequency( ) {
+ Bit32u freq = chanData & (( 1 << 10 ) - 1);
+ Bit32u block = (chanData >> 10) & 0xff;
+#ifdef WAVE_PRECISION
+ block = 7 - block;
+ waveAdd = ( freq * freqMul ) >> block;
+#else
+ waveAdd = ( freq << block ) * freqMul;
+#endif
+ if ( reg20 & MASK_VIBRATO ) {
+ vibStrength = (Bit8u)(freq >> 7);
+
+#ifdef WAVE_PRECISION
+ vibrato = ( vibStrength * freqMul ) >> block;
+#else
+ vibrato = ( vibStrength << block ) * freqMul;
+#endif
+ } else {
+ vibStrength = 0;
+ vibrato = 0;
+ }
+}
+
+void Operator::UpdateRates( const Chip* chip ) {
+ //Mame seems to reverse this where enabling ksr actually lowers
+ //the rate, but pdf manuals says otherwise?
+ Bit8u newKsr = (Bit8u)((chanData >> SHIFT_KEYCODE) & 0xff);
+ if ( !( reg20 & MASK_KSR ) ) {
+ newKsr >>= 2;
+ }
+ if ( ksr == newKsr )
+ return;
+ ksr = newKsr;
+ UpdateAttack( chip );
+ UpdateDecay( chip );
+ UpdateRelease( chip );
+}
+
+INLINE Bit32s Operator::RateForward( Bit32u add ) {
+ rateIndex += add;
+ Bit32s ret = rateIndex >> RATE_SH;
+ rateIndex = rateIndex & RATE_MASK;
+ return ret;
+}
+
+template< Operator::State yes>
+Bits Operator::TemplateVolume( ) {
+ Bit32s vol = volume;
+ Bit32s change;
+ switch ( yes ) {
+ case OFF:
+ return ENV_MAX;
+ case ATTACK:
+ change = RateForward( attackAdd );
+ if ( !change )
+ return vol;
+ vol += ( (~vol) * change ) >> 3;
+ if ( vol < ENV_MIN ) {
+ volume = ENV_MIN;
+ rateIndex = 0;
+ SetState( DECAY );
+ return ENV_MIN;
+ }
+ break;
+ case DECAY:
+ vol += RateForward( decayAdd );
+ if ( GCC_UNLIKELY(vol >= sustainLevel) ) {
+ //Check if we didn't overshoot max attenuation, then just go off
+ if ( GCC_UNLIKELY(vol >= ENV_MAX) ) {
+ volume = ENV_MAX;
+ SetState( OFF );
+ return ENV_MAX;
+ }
+ //Continue as sustain
+ rateIndex = 0;
+ SetState( SUSTAIN );
+ }
+ break;
+ case SUSTAIN:
+ if ( reg20 & MASK_SUSTAIN ) {
+ return vol;
+ }
+ //In sustain phase, but not sustaining, do regular release
+ case RELEASE:
+ vol += RateForward( releaseAdd );;
+ if ( GCC_UNLIKELY(vol >= ENV_MAX) ) {
+ volume = ENV_MAX;
+ SetState( OFF );
+ return ENV_MAX;
+ }
+ break;
+ }
+ volume = vol;
+ return vol;
+}
+
+static const VolumeHandler VolumeHandlerTable[5] = {
+ &Operator::TemplateVolume< Operator::OFF >,
+ &Operator::TemplateVolume< Operator::RELEASE >,
+ &Operator::TemplateVolume< Operator::SUSTAIN >,
+ &Operator::TemplateVolume< Operator::DECAY >,
+ &Operator::TemplateVolume< Operator::ATTACK >
+};
+
+INLINE Bitu Operator::ForwardVolume() {
+ return currentLevel + (this->*volHandler)();
+}
+
+
+INLINE Bitu Operator::ForwardWave() {
+ waveIndex += waveCurrent;
+ return waveIndex >> WAVE_SH;
+}
+
+void Operator::Write20( const Chip* chip, Bit8u val ) {
+ Bit8u change = (reg20 ^ val );
+ if ( !change )
+ return;
+ reg20 = val;
+ //Shift the tremolo bit over the entire register, saved a branch, YES!
+ tremoloMask = (Bit8s)(val) >> 7;
+ tremoloMask &= ~(( 1 << ENV_EXTRA ) -1);
+ //Update specific features based on changes
+ if ( change & MASK_KSR ) {
+ UpdateRates( chip );
+ }
+ //With sustain enable the volume doesn't change
+ if ( reg20 & MASK_SUSTAIN || ( !releaseAdd ) ) {
+ rateZero |= ( 1 << SUSTAIN );
+ } else {
+ rateZero &= ~( 1 << SUSTAIN );
+ }
+ //Frequency multiplier or vibrato changed
+ if ( change & (0xf | MASK_VIBRATO) ) {
+ freqMul = chip->freqMul[ val & 0xf ];
+ UpdateFrequency();
+ }
+}
+
+void Operator::Write40( const Chip* /*chip*/, Bit8u val ) {
+ if (!(reg40 ^ val ))
+ return;
+ reg40 = val;
+ UpdateAttenuation( );
+}
+
+void Operator::Write60( const Chip* chip, Bit8u val ) {
+ Bit8u change = reg60 ^ val;
+ reg60 = val;
+ if ( change & 0x0f ) {
+ UpdateDecay( chip );
+ }
+ if ( change & 0xf0 ) {
+ UpdateAttack( chip );
+ }
+}
+
+void Operator::Write80( const Chip* chip, Bit8u val ) {
+ Bit8u change = (reg80 ^ val );
+ if ( !change )
+ return;
+ reg80 = val;
+ Bit8u sustain = val >> 4;
+ //Turn 0xf into 0x1f
+ sustain |= ( sustain + 1) & 0x10;
+ sustainLevel = sustain << ( ENV_BITS - 5 );
+ if ( change & 0x0f ) {
+ UpdateRelease( chip );
+ }
+}
+
+void Operator::WriteE0( const Chip* chip, Bit8u val ) {
+ if ( !(regE0 ^ val) )
+ return;
+ //in opl3 mode you can always selet 7 waveforms regardless of waveformselect
+ Bit8u waveForm = val & ( ( 0x3 & chip->waveFormMask ) | (0x7 & chip->opl3Active ) );
+ regE0 = val;
+#if ( DBOPL_WAVE == WAVE_HANDLER )
+ waveHandler = WaveHandlerTable[ waveForm ];
+#else
+ waveBase = WaveTable + WaveBaseTable[ waveForm ];
+ waveStart = WaveStartTable[ waveForm ] << WAVE_SH;
+ waveMask = WaveMaskTable[ waveForm ];
+#endif
+}
+
+INLINE void Operator::SetState( Bit8u s ) {
+ state = s;
+ volHandler = VolumeHandlerTable[ s ];
+}
+
+INLINE bool Operator::Silent() const {
+ if ( !ENV_SILENT( totalLevel + volume ) )
+ return false;
+ if ( !(rateZero & ( 1 << state ) ) )
+ return false;
+ return true;
+}
+
+INLINE void Operator::Prepare( const Chip* chip ) {
+ currentLevel = totalLevel + (chip->tremoloValue & tremoloMask);
+ waveCurrent = waveAdd;
+ if ( vibStrength >> chip->vibratoShift ) {
+ Bit32s add = vibrato >> chip->vibratoShift;
+ //Sign extend over the shift value
+ Bit32s neg = chip->vibratoSign;
+ //Negate the add with -1 or 0
+ add = ( add ^ neg ) - neg;
+ waveCurrent += add;
+ }
+}
+
+void Operator::KeyOn( Bit8u mask ) {
+ if ( !keyOn ) {
+ //Restart the frequency generator
+#if ( DBOPL_WAVE > WAVE_HANDLER )
+ waveIndex = waveStart;
+#else
+ waveIndex = 0;
+#endif
+ rateIndex = 0;
+ SetState( ATTACK );
+ }
+ keyOn |= mask;
+}
+
+void Operator::KeyOff( Bit8u mask ) {
+ keyOn &= ~mask;
+ if ( !keyOn ) {
+ if ( state != OFF ) {
+ SetState( RELEASE );
+ }
+ }
+}
+
+INLINE Bits Operator::GetWave( Bitu index, Bitu vol ) {
+#if ( DBOPL_WAVE == WAVE_HANDLER )
+ return waveHandler( index, vol << ( 3 - ENV_EXTRA ) );
+#elif ( DBOPL_WAVE == WAVE_TABLEMUL )
+ return (waveBase[ index & waveMask ] * MulTable[ vol >> ENV_EXTRA ]) >> MUL_SH;
+#elif ( DBOPL_WAVE == WAVE_TABLELOG )
+ Bit32s wave = waveBase[ index & waveMask ];
+ Bit32u total = ( wave & 0x7fff ) + vol << ( 3 - ENV_EXTRA );
+ Bit32s sig = ExpTable[ total & 0xff ];
+ Bit32u exp = total >> 8;
+ Bit32s neg = wave >> 16;
+ return ((sig ^ neg) - neg) >> exp;
+#else
#error "No valid wave routine"
- #endif
- }
-
- Bits INLINE Operator::GetSample(Bits modulation)
- {
- Bitu vol = ForwardVolume();
-
- if(ENV_SILENT(vol))
- {
- //Simply forward the wave
- waveIndex += waveCurrent;
- return 0;
- }
- else
- {
- Bitu index = ForwardWave();
- index += modulation;
- return GetWave(index, vol);
- }
- }
-
- Operator::Operator()
- {
- chanData = 0;
- freqMul = 0;
- waveIndex = 0;
- waveAdd = 0;
- waveCurrent = 0;
- keyOn = 0;
- ksr = 0;
- reg20 = 0;
- reg40 = 0;
- reg60 = 0;
- reg80 = 0;
- regE0 = 0;
- SetState(OFF);
- rateZero = (1 << OFF);
- sustainLevel = ENV_MAX;
- currentLevel = ENV_MAX;
- totalLevel = ENV_MAX;
- volume = ENV_MAX;
- releaseAdd = 0;
- }
-
- /*
- Channel
- */
-
- Channel::Channel()
- {
- old[0] = old[1] = 0;
- chanData = 0;
- regB0 = 0;
- regC0 = 0;
- maskLeft = -1;
- maskRight = -1;
- feedback = 31;
- fourMask = 0;
- synthHandler = &Channel::BlockTemplate< sm2FM >;
- }
-
- void Channel::SetChanData(const Chip *chip, Bit32u data)
- {
- Bit32u change = chanData ^ data;
- chanData = data;
- Op(0)->chanData = data;
- Op(1)->chanData = data;
- //Since a frequency update triggered this, always update frequency
- Op(0)->UpdateFrequency();
- Op(1)->UpdateFrequency();
-
- if(change & (0xff << SHIFT_KSLBASE))
- {
- Op(0)->UpdateAttenuation();
- Op(1)->UpdateAttenuation();
- }
-
- if(change & (0xff << SHIFT_KEYCODE))
- {
- Op(0)->UpdateRates(chip);
- Op(1)->UpdateRates(chip);
- }
- }
-
- void Channel::UpdateFrequency(const Chip *chip, Bit8u fourOp)
- {
- //Extrace the frequency bits
- Bit32u data = chanData & 0xffff;
- Bit32u kslBase = KslTable[ data >> 6 ];
- Bit32u keyCode = (data & 0x1c00) >> 9;
-
- if(chip->reg08 & 0x40)
- {
- keyCode |= (data & 0x100) >> 8; /* notesel == 1 */
- }
- else
- {
- keyCode |= (data & 0x200) >> 9; /* notesel == 0 */
- }
-
- //Add the keycode and ksl into the highest bits of chanData
- data |= (keyCode << SHIFT_KEYCODE) | (kslBase << SHIFT_KSLBASE);
- (this + 0)->SetChanData(chip, data);
-
- if(fourOp & 0x3f)
- (this + 1)->SetChanData(chip, data);
- }
-
- void Channel::WriteA0(const Chip *chip, Bit8u val)
- {
- Bit8u fourOp = chip->reg104 & chip->opl3Active & fourMask;
-
- //Don't handle writes to silent fourop channels
- if(fourOp > 0x80)
- return;
-
- Bit32u change = (chanData ^ val) & 0xff;
-
- if(change)
- {
- chanData ^= change;
- UpdateFrequency(chip, fourOp);
- }
- }
-
- void Channel::WriteB0(const Chip *chip, Bit8u val)
- {
- Bit8u fourOp = chip->reg104 & chip->opl3Active & fourMask;
-
- //Don't handle writes to silent fourop channels
- if(fourOp > 0x80)
- return;
-
- Bitu change = (chanData ^ (val << 8)) & 0x1f00;
-
- if(change)
- {
- chanData ^= change;
- UpdateFrequency(chip, fourOp);
- }
-
- //Check for a change in the keyon/off state
- if(!((val ^ regB0) & 0x20))
- return;
-
- regB0 = val;
-
- if(val & 0x20)
- {
- Op(0)->KeyOn(0x1);
- Op(1)->KeyOn(0x1);
-
- if(fourOp & 0x3f)
- {
- (this + 1)->Op(0)->KeyOn(1);
- (this + 1)->Op(1)->KeyOn(1);
- }
- }
- else
- {
- Op(0)->KeyOff(0x1);
- Op(1)->KeyOff(0x1);
-
- if(fourOp & 0x3f)
- {
- (this + 1)->Op(0)->KeyOff(1);
- (this + 1)->Op(1)->KeyOff(1);
- }
- }
- }
-
- void Channel::WriteC0(const Chip *chip, Bit8u val)
- {
- Bit8u change = val ^ regC0;
-
- if(!change)
- return;
-
- regC0 = val;
- feedback = (val >> 1) & 7;
-
- if(feedback)
- {
- //We shift the input to the right 10 bit wave index value
- feedback = 9 - feedback;
- }
- else
- feedback = 31;
-
- //Select the new synth mode
- if(chip->opl3Active)
- {
- //4-op mode enabled for this channel
- if((chip->reg104 & fourMask) & 0x3f)
- {
- Channel *chan0, *chan1;
-
- //Check if it's the 2nd channel in a 4-op
- if(!(fourMask & 0x80))
- {
- chan0 = this;
- chan1 = this + 1;
- }
- else
- {
- chan0 = this - 1;
- chan1 = this;
- }
-
- Bit8u synth = ((chan0->regC0 & 1) << 0) | ((chan1->regC0 & 1) << 1);
-
- switch(synth)
- {
- case 0:
- chan0->synthHandler = &Channel::BlockTemplate< sm3FMFM >;
- break;
-
- case 1:
- chan0->synthHandler = &Channel::BlockTemplate< sm3AMFM >;
- break;
-
- case 2:
- chan0->synthHandler = &Channel::BlockTemplate< sm3FMAM >;
- break;
-
- case 3:
- chan0->synthHandler = &Channel::BlockTemplate< sm3AMAM >;
- break;
- }
-
- //Disable updating percussion channels
- }
- else if((fourMask & 0x40) && (chip->regBD & 0x20))
- {
- //Regular dual op, am or fm
- }
- else if(val & 1)
- synthHandler = &Channel::BlockTemplate< sm3AM >;
- else
- synthHandler = &Channel::BlockTemplate< sm3FM >;
-
- maskLeft = (val & 0x10) ? -1 : 0;
- maskRight = (val & 0x20) ? -1 : 0;
- //opl2 active
- }
- else
- {
- //Disable updating percussion channels
- if((fourMask & 0x40) && (chip->regBD & 0x20))
- {
- //Regular dual op, am or fm
- }
- else if(val & 1)
- synthHandler = &Channel::BlockTemplate< sm2AM >;
- else
- synthHandler = &Channel::BlockTemplate< sm2FM >;
- }
- }
-
- void Channel::ResetC0(const Chip *chip)
- {
- Bit8u val = regC0;
- regC0 ^= 0xff;
- WriteC0(chip, val);
- }
-
- template< bool opl3Mode>
- INLINE void Channel::GeneratePercussion(Chip *chip, Bit32s *output)
- {
- Channel *chan = this;
- //BassDrum
- Bit32s mod = (Bit32u)((old[0] + old[1])) >> feedback;
- old[0] = old[1];
- old[1] = Op(0)->GetSample(mod);
-
- //When bassdrum is in AM mode first operator is ignoed
- if(chan->regC0 & 1)
- mod = 0;
- else
- mod = old[0];
-
- Bit32s sample = Op(1)->GetSample(mod);
- //Precalculate stuff used by other outputs
- Bit32u noiseBit = chip->ForwardNoise() & 0x1;
- Bit32u c2 = Op(2)->ForwardWave();
- Bit32u c5 = Op(5)->ForwardWave();
- Bit32u phaseBit = (((c2 & 0x88) ^ ((c2 << 5) & 0x80)) | ((c5 ^ (c5 << 2)) & 0x20)) ? 0x02 : 0x00;
- //Hi-Hat
- Bit32u hhVol = Op(2)->ForwardVolume();
-
- if(!ENV_SILENT(hhVol))
- {
- Bit32u hhIndex = (phaseBit << 8) | (0x34 << (phaseBit ^ (noiseBit << 1)));
- sample += Op(2)->GetWave(hhIndex, hhVol);
- }
-
- //Snare Drum
- Bit32u sdVol = Op(3)->ForwardVolume();
-
- if(!ENV_SILENT(sdVol))
- {
- Bit32u sdIndex = (0x100 + (c2 & 0x100)) ^ (noiseBit << 8);
- sample += Op(3)->GetWave(sdIndex, sdVol);
- }
-
- //Tom-tom
- sample += Op(4)->GetSample(0);
- //Top-Cymbal
- Bit32u tcVol = Op(5)->ForwardVolume();
-
- if(!ENV_SILENT(tcVol))
- {
- Bit32u tcIndex = (1 + phaseBit) << 8;
- sample += Op(5)->GetWave(tcIndex, tcVol);
- }
-
- sample <<= 1;
-
- if(opl3Mode)
- {
- output[0] += sample;
- output[1] += sample;
- }
- else
- output[0] += sample;
- }
-
- template<SynthMode mode>
- Channel *Channel::BlockTemplate(Chip *chip, Bit32u samples, Bit32s *output)
- {
- switch(mode)
- {
- case sm2AM:
- case sm3AM:
- if(Op(0)->Silent() && Op(1)->Silent())
- {
- old[0] = old[1] = 0;
- return (this + 1);
- }
-
- break;
-
- case sm2FM:
- case sm3FM:
- if(Op(1)->Silent())
- {
- old[0] = old[1] = 0;
- return (this + 1);
- }
-
- break;
-
- case sm3FMFM:
- if(Op(3)->Silent())
- {
- old[0] = old[1] = 0;
- return (this + 2);
- }
-
- break;
-
- case sm3AMFM:
- if(Op(0)->Silent() && Op(3)->Silent())
- {
- old[0] = old[1] = 0;
- return (this + 2);
- }
-
- break;
-
- case sm3FMAM:
- if(Op(1)->Silent() && Op(3)->Silent())
- {
- old[0] = old[1] = 0;
- return (this + 2);
- }
-
- break;
-
- case sm3AMAM:
- if(Op(0)->Silent() && Op(2)->Silent() && Op(3)->Silent())
- {
- old[0] = old[1] = 0;
- return (this + 2);
- }
-
- break;
-
- default:
- break;
- }
-
- //Init the operators with the the current vibrato and tremolo values
- Op(0)->Prepare(chip);
- Op(1)->Prepare(chip);
-
- if(mode > sm4Start)
- {
- Op(2)->Prepare(chip);
- Op(3)->Prepare(chip);
- }
-
- if(mode > sm6Start)
- {
- Op(4)->Prepare(chip);
- Op(5)->Prepare(chip);
- }
-
- for(Bitu i = 0; i < samples; i++)
- {
- //Early out for percussion handlers
- if(mode == sm2Percussion)
- {
- GeneratePercussion<false>(chip, output + i);
- continue; //Prevent some unitialized value bitching
- }
- else if(mode == sm3Percussion)
- {
- GeneratePercussion<true>(chip, output + i * 2);
- continue; //Prevent some unitialized value bitching
- }
-
- //Do unsigned shift so we can shift out all bits but still stay in 10 bit range otherwise
- Bit32s mod = (Bit32u)((old[0] + old[1])) >> feedback;
- old[0] = old[1];
- old[1] = Op(0)->GetSample(mod);
- Bit32s sample;
- Bit32s out0 = old[0];
-
- if(mode == sm2AM || mode == sm3AM)
- sample = out0 + Op(1)->GetSample(0);
- else if(mode == sm2FM || mode == sm3FM)
- sample = Op(1)->GetSample(out0);
- else if(mode == sm3FMFM)
- {
- Bits next = Op(1)->GetSample(out0);
- next = Op(2)->GetSample(next);
- sample = Op(3)->GetSample(next);
- }
- else if(mode == sm3AMFM)
- {
- sample = out0;
- Bits next = Op(1)->GetSample(0);
- next = Op(2)->GetSample(next);
- sample += Op(3)->GetSample(next);
- }
- else if(mode == sm3FMAM)
- {
- sample = Op(1)->GetSample(out0);
- Bits next = Op(2)->GetSample(0);
- sample += Op(3)->GetSample(next);
- }
- else if(mode == sm3AMAM)
- {
- sample = out0;
- Bits next = Op(1)->GetSample(0);
- sample += Op(2)->GetSample(next);
- sample += Op(3)->GetSample(0);
- }
-
- switch(mode)
- {
- case sm2AM:
- case sm2FM:
- output[ i ] += sample;
- break;
-
- case sm3AM:
- case sm3FM:
- case sm3FMFM:
- case sm3AMFM:
- case sm3FMAM:
- case sm3AMAM:
- output[ i * 2 + 0 ] += sample & maskLeft;
- output[ i * 2 + 1 ] += sample & maskRight;
- break;
-
- default:
- break;
- }
- }
-
- switch(mode)
- {
- case sm2AM:
- case sm2FM:
- case sm3AM:
- case sm3FM:
- return (this + 1);
-
- case sm3FMFM:
- case sm3AMFM:
- case sm3FMAM:
- case sm3AMAM:
- return(this + 2);
-
- case sm2Percussion:
- case sm3Percussion:
- return(this + 3);
- }
-
- return 0;
- }
-
- /*
- Chip
- */
-
- Chip::Chip()
- {
- reg08 = 0;
- reg04 = 0;
- regBD = 0;
- reg104 = 0;
- opl3Active = 0;
- //Extra zeros!
- vibratoIndex = 0;
- tremoloIndex = 0;
- vibratoSign = 0;
- vibratoShift = 0;
- tremoloValue = 0;
- vibratoStrength = 0;
- tremoloStrength = 0;
- waveFormMask = 0;
- lfoCounter = 0;
- lfoAdd = 0;
- noiseCounter = 0;
- noiseAdd = 0;
- noiseValue = 0;
- memset(freqMul, 0, sizeof(Bit32u) * 16);
- memset(linearRates, 0, sizeof(Bit32u) * 76);
- memset(attackRates, 0, sizeof(Bit32u) * 76);
- }
-
- INLINE Bit32u Chip::ForwardNoise()
- {
- noiseCounter += noiseAdd;
- Bitu count = noiseCounter >> LFO_SH;
- noiseCounter &= WAVE_MASK;
-
- for(; count > 0; --count)
- {
- //Noise calculation from mame
- noiseValue ^= (0x800302) & (0 - (noiseValue & 1));
- noiseValue >>= 1;
- }
-
- return noiseValue;
- }
-
- INLINE Bit32u Chip::ForwardLFO(Bit32u samples)
- {
- //Current vibrato value, runs 4x slower than tremolo
- vibratoSign = (VibratoTable[ vibratoIndex >> 2]) >> 7;
- vibratoShift = (VibratoTable[ vibratoIndex >> 2] & 7) + vibratoStrength;
- tremoloValue = TremoloTable[ tremoloIndex ] >> tremoloStrength;
- //Check hom many samples there can be done before the value changes
- Bit32u todo = LFO_MAX - lfoCounter;
- Bit32u count = (todo + lfoAdd - 1) / lfoAdd;
-
- if(count > samples)
- {
- count = samples;
- lfoCounter += count * lfoAdd;
- }
- else
- {
- lfoCounter += count * lfoAdd;
- lfoCounter &= (LFO_MAX - 1);
- //Maximum of 7 vibrato value * 4
- vibratoIndex = (vibratoIndex + 1) & 31;
-
- //Clip tremolo to the the table size
- if(tremoloIndex + 1 < TREMOLO_TABLE)
- ++tremoloIndex;
- else
- tremoloIndex = 0;
- }
-
- return count;
- }
-
-
- void Chip::WriteBD(Bit8u val)
- {
- Bit8u change = regBD ^ val;
-
- if(!change)
- return;
-
- regBD = val;
- //TODO could do this with shift and xor?
- vibratoStrength = (val & 0x40) ? 0x00 : 0x01;
- tremoloStrength = (val & 0x80) ? 0x00 : 0x02;
-
- if(val & 0x20)
- {
- //Drum was just enabled, make sure channel 6 has the right synth
- if(change & 0x20)
- {
- if(opl3Active)
- chan[6].synthHandler = &Channel::BlockTemplate< sm3Percussion >;
- else
- chan[6].synthHandler = &Channel::BlockTemplate< sm2Percussion >;
- }
-
- //Bass Drum
- if(val & 0x10)
- {
- chan[6].op[0].KeyOn(0x2);
- chan[6].op[1].KeyOn(0x2);
- }
- else
- {
- chan[6].op[0].KeyOff(0x2);
- chan[6].op[1].KeyOff(0x2);
- }
-
- //Hi-Hat
- if(val & 0x1)
- chan[7].op[0].KeyOn(0x2);
- else
- chan[7].op[0].KeyOff(0x2);
-
- //Snare
- if(val & 0x8)
- chan[7].op[1].KeyOn(0x2);
- else
- chan[7].op[1].KeyOff(0x2);
-
- //Tom-Tom
- if(val & 0x4)
- chan[8].op[0].KeyOn(0x2);
- else
- chan[8].op[0].KeyOff(0x2);
-
- //Top Cymbal
- if(val & 0x2)
- chan[8].op[1].KeyOn(0x2);
- else
- chan[8].op[1].KeyOff(0x2);
-
- //Toggle keyoffs when we turn off the percussion
- }
- else if(change & 0x20)
- {
- //Trigger a reset to setup the original synth handler
- chan[6].ResetC0(this);
- chan[6].op[0].KeyOff(0x2);
- chan[6].op[1].KeyOff(0x2);
- chan[7].op[0].KeyOff(0x2);
- chan[7].op[1].KeyOff(0x2);
- chan[8].op[0].KeyOff(0x2);
- chan[8].op[1].KeyOff(0x2);
- }
- }
-
-
-#define REGOP( _FUNC_ ) \
- index = ( ( reg >> 3) & 0x20 ) | ( reg & 0x1f ); \
- if ( OpOffsetTable[ index ] ) { \
- Operator* regOp = (Operator*)( ((char *)this ) + OpOffsetTable[ index ] ); \
- regOp->_FUNC_( this, val ); \
- }
-
-#define REGCHAN( _FUNC_ ) \
- index = ( ( reg >> 4) & 0x10 ) | ( reg & 0xf ); \
- if ( ChanOffsetTable[ index ] ) { \
- Channel* regChan = (Channel*)( ((char *)this ) + ChanOffsetTable[ index ] ); \
- regChan->_FUNC_( this, val ); \
- }
-
- void Chip::WriteReg(Bit32u reg, Bit8u val)
- {
- Bitu index = 0;
-
- switch((reg & 0xf0) >> 4)
- {
- case 0x00 >> 4:
- if(reg == 0x01)
- waveFormMask = (val & 0x20) ? 0x7 : 0x0;
- else if(reg == 0x104)
- {
- //Only detect changes in lowest 6 bits
- if(!((reg104 ^ val) & 0x3f))
- return;
-
- //Always keep the highest bit enabled, for checking > 0x80
- reg104 = 0x80 | (val & 0x3f);
- }
- else if(reg == 0x105)
- {
- //MAME says the real opl3 doesn't reset anything on opl3 disable/enable till the next write in another register
- if(!((opl3Active ^ val) & 1))
- return;
-
- opl3Active = (val & 1) ? 0xff : 0;
-
- //Update the 0xc0 register for all channels to signal the switch to mono/stereo handlers
- for(int i = 0; i < 18; i++)
- chan[i].ResetC0(this);
- }
- else if(reg == 0x08)
- reg08 = val;
-
- case 0x10 >> 4:
- break;
-
- case 0x20 >> 4:
- case 0x30 >> 4:
- REGOP(Write20);
- break;
-
- case 0x40 >> 4:
- case 0x50 >> 4:
- REGOP(Write40);
- break;
-
- case 0x60 >> 4:
- case 0x70 >> 4:
- REGOP(Write60);
- break;
-
- case 0x80 >> 4:
- case 0x90 >> 4:
- REGOP(Write80);
- break;
-
- case 0xa0 >> 4:
- REGCHAN(WriteA0);
- break;
-
- case 0xb0 >> 4:
- if(reg == 0xbd)
- WriteBD(val);
- else
- REGCHAN(WriteB0);
-
- break;
-
- case 0xc0 >> 4:
- REGCHAN(WriteC0);
-
- case 0xd0 >> 4:
- break;
-
- case 0xe0 >> 4:
- case 0xf0 >> 4:
- REGOP(WriteE0);
- break;
- }
- }
-
-
- Bit32u Chip::WriteAddr(Bit32u port, Bit8u val)
- {
- switch(port & 3)
- {
- case 0:
- return val;
-
- case 2:
- if(opl3Active || (val == 0x05))
- return 0x100 | val;
- else
- return val;
- }
-
- return 0;
- }
-
- void Chip::GenerateBlock2(Bitu total, Bit32s *output)
- {
- while(total > 0)
- {
- Bit32u samples = ForwardLFO(total);
- memset(output, 0, sizeof(Bit32s) * samples);
- int count = 0;
-
- for(Channel *ch = chan; ch < chan + 9;)
- {
- count++;
- ch = (ch->*(ch->synthHandler))(this, samples, output);
- }
-
- total -= samples;
- output += samples;
- }
- }
-
- void Chip::GenerateBlock3(Bitu total, Bit32s *output)
- {
- while(total > 0)
- {
- Bit32u samples = ForwardLFO((Bit32u)total);
- memset(output, 0, sizeof(Bit32s) * samples * 2);
- int count = 0;
-
- for(Channel *ch = chan; ch < chan + 18;)
- {
- count++;
- ch = (ch->*(ch->synthHandler))(this, samples, output);
- }
-
- total -= samples;
- output += samples * 2;
- }
- }
-
- void Chip::GenerateBlock2_Mix(Bitu total, Bit32s *output)
- {
- while(total > 0)
- {
- Bit32u samples = ForwardLFO((Bit32u)total);
- int count = 0;
- for(Channel *ch = chan; ch < chan + 9;)
- {
- count++;
- ch = (ch->*(ch->synthHandler))(this, samples, output);
- }
-
- total -= samples;
- output += samples;
- }
- }
-
- void Chip::GenerateBlock3_Mix(Bitu total, Bit32s *output)
- {
- while(total > 0)
- {
- Bit32u samples = ForwardLFO(total);
- int count = 0;
- for(Channel *ch = chan; ch < chan + 18;)
- {
- count++;
- ch = (ch->*(ch->synthHandler))(this, samples, output);
- }
- total -= samples;
- output += samples * 2;
- }
- }
-
- void Chip::Setup(Bit32u rate)
- {
- double original = OPLRATE;
- // double original = rate;
- double scale = original / (double)rate;
- //Noise counter is run at the same precision as general waves
- noiseAdd = (Bit32u)(0.5 + scale * (1 << LFO_SH));
- noiseCounter = 0;
- noiseValue = 1; //Make sure it triggers the noise xor the first time
- //The low frequency oscillation counter
- //Every time his overflows vibrato and tremoloindex are increased
- lfoAdd = (Bit32u)(0.5 + scale * (1 << LFO_SH));
- lfoCounter = 0;
- vibratoIndex = 0;
- tremoloIndex = 0;
- //With higher octave this gets shifted up
- //-1 since the freqCreateTable = *2
- #ifdef WAVE_PRECISION
- double freqScale = (1 << 7) * scale * (1 << (WAVE_SH - 1 - 10));
-
- for(int i = 0; i < 16; i++)
- freqMul[i] = (Bit32u)(0.5 + freqScale * FreqCreateTable[ i ]);
-
- #else
- Bit32u freqScale = (Bit32u)(0.5 + scale * (1 << (WAVE_SH - 1 - 10)));
-
- for(int i = 0; i < 16; i++)
- freqMul[i] = freqScale * FreqCreateTable[ i ];
-
- #endif
-
- //-3 since the real envelope takes 8 steps to reach the single value we supply
- for(Bit8u i = 0; i < 76; i++)
- {
- Bit8u index, shift;
- EnvelopeSelect(i, index, shift);
- linearRates[i] = (Bit32u)(scale * (EnvelopeIncreaseTable[ index ] << (RATE_SH + ENV_EXTRA - shift - 3)));
- }
-
- if(rate == 48000)
- {
- /* BISQWIT ADD: Use precalculated table for this common sample-rate.
- * Because the actual generation code, below, is MOLASSES SLOW on DOS.
- */
- static const Bit32u precalculated_table[62] =
- {
- 2152, 2700, 3228, 3712, 4304, 5399, 6456, 7424, 8608, 10799, 12912, 14849, 17216, 21598,
- 25824, 29698, 34432, 43196, 51650, 59398, 68864, 86392, 103310, 118795, 137746, 172847,
- 206619, 237693, 275559, 345774, 413238, 475500, 543030, 678787, 814545, 950302, 1086060,
- 1357575, 1629090, 1900605, 2172120, 2715151, 3258181, 3801211, 4344241, 5430302,
- 6516362, 7602423, 8688483, 10860604, 13032725, 15204846, 17376967, 21721209, 26065451,
- 30409693, 34753934, 43442418, 52130902, 60819386, 69507869, 69507869
- };
-
- for(Bit8u i = 0; i < 62; i++)
- attackRates[i] = precalculated_table[i];
- }
- else if(rate == 44100)
- {
- static const Bit32u precalculated_table[62] =
- {
- 2342, 2939, 3513, 4040, 4685, 5877, 7027, 8081, 9369, 11754, 14054, 16162, 18738, 23508,
- 28108, 32325, 37478, 47018, 56219, 64649, 74965, 94044, 112448, 129292, 149929, 188132,
- 224945, 258713, 300002, 376263, 449999, 517550, 591053, 738816, 886579, 1034343, 1182106,
- 1477633, 1773159, 2068686, 2364213, 2955266, 3546319, 4137373, 4728426, 5910533,
- 7092639, 8274746, 9456853, 11821066, 14185279, 16549492, 18913706, 23642132, 28370559,
- 33098985, 37827412, 47284265, 56741118, 66197971, 75654824, 75654824
- };
-
- for(Bit8u i = 0; i < 62; i++)
- attackRates[i] = precalculated_table[i];
- }
- else if(rate == 22050)
- {
- static const Bit32u precalculated_table[62] =
- {
- 4685, 5877, 7027, 8081, 9369, 11754, 14054, 16162, 18738, 23508, 28108, 32325, 37478,
- 47018, 56219, 64649, 74965, 94044, 112448, 129292, 149929, 188132, 224945, 258713, 300002,
- 376263, 449999, 517550, 591053, 738816, 886579, 1034343, 1182106, 1477633, 1773159,
- 2068686, 2364213, 2955266, 3546319, 4137373, 4728426, 5910533, 7092639, 8274746,
- 9456853, 11821066, 14185279, 16549492, 18913706, 23642132, 28370559, 33098985,
- 37827412, 47284265, 56741118, 66197971, 75654824, 94568530, 113482236, 132395942,
- 151309648, 151309648
- };
-
- for(Bit8u i = 0; i < 62; i++)
- attackRates[i] = precalculated_table[i];
- }
- //Generate the best matching attack rate
- else for(Bit8u i = 0; i < 62; i++)
- {
- Bit8u index, shift;
- EnvelopeSelect(i, index, shift);
- //Original amount of samples the attack would take
- Bit32s original = (Bit32u)((AttackSamplesTable[ index ] << shift) / scale);
- Bit32s guessAdd = (Bit32u)(scale * (EnvelopeIncreaseTable[ index ] << (RATE_SH - shift - 3)));
- Bit32s bestAdd = guessAdd;
- Bit32u bestDiff = 1 << 30;
-
- for(Bit32u passes = 0; passes < 16; passes ++)
- {
- Bit32s volume = ENV_MAX;
- Bit32s samples = 0;
- Bit32u count = 0;
-
- while(volume > 0 && samples < original * 2)
- {
- count += guessAdd;
- Bit32s change = count >> RATE_SH;
- count &= RATE_MASK;
-
- if(GCC_UNLIKELY(change)) // less than 1 %
- volume += (~volume * change) >> 3;
-
- samples++;
- }
-
- Bit32s diff = original - samples;
- Bit32u lDiff = labs(diff);
-
- //Init last on first pass
- if(lDiff < bestDiff)
- {
- bestDiff = lDiff;
- bestAdd = guessAdd;
-
- if(!bestDiff)
- break;
- }
-
- //Below our target
- if(diff < 0)
- {
- //Better than the last time
- Bit32s mul = ((original - diff) << 12) / original;
- guessAdd = ((guessAdd * mul) >> 12);
- guessAdd++;
- }
- else if(diff > 0)
- {
- Bit32s mul = ((original - diff) << 12) / original;
- guessAdd = (guessAdd * mul) >> 12;
- guessAdd--;
- }
- }
-
- attackRates[i] = bestAdd;
- }
-
- /*fprintf(stderr, "attack rate table: ");
- for ( Bit8u i = 0; i < 62; i++ )
- fprintf(stderr, ",%u", attackRates[i]);
- fprintf(stderr, "\n");*/
-
- for(Bit8u i = 62; i < 76; i++)
- {
- //This should provide instant volume maximizing
- attackRates[i] = 8 << RATE_SH;
- }
-
- //Setup the channels with the correct four op flags
- //Channels are accessed through a table so they appear linear here
- chan[ 0].fourMask = 0x00 | (1 << 0);
- chan[ 1].fourMask = 0x80 | (1 << 0);
- chan[ 2].fourMask = 0x00 | (1 << 1);
- chan[ 3].fourMask = 0x80 | (1 << 1);
- chan[ 4].fourMask = 0x00 | (1 << 2);
- chan[ 5].fourMask = 0x80 | (1 << 2);
- chan[ 9].fourMask = 0x00 | (1 << 3);
- chan[10].fourMask = 0x80 | (1 << 3);
- chan[11].fourMask = 0x00 | (1 << 4);
- chan[12].fourMask = 0x80 | (1 << 4);
- chan[13].fourMask = 0x00 | (1 << 5);
- chan[14].fourMask = 0x80 | (1 << 5);
- //mark the percussion channels
- chan[ 6].fourMask = 0x40;
- chan[ 7].fourMask = 0x40;
- chan[ 8].fourMask = 0x40;
- //Clear Everything in opl3 mode
- WriteReg(0x105, 0x1);
-
- for(int i = 0; i < 512; i++)
- {
- if(i == 0x105)
- continue;
-
- WriteReg(i, 0xff);
- WriteReg(i, 0x0);
- }
-
- WriteReg(0x105, 0x0);
-
- //Clear everything in opl2 mode
- for(int i = 0; i < 255; i++)
- {
- WriteReg(i, 0xff);
- WriteReg(i, 0x0);
- }
- }
-
- static bool doneTables = false;
- void InitTables(void)
- {
- if(doneTables)
- return;
-
- doneTables = true;
- #if ( DBOPL_WAVE == WAVE_HANDLER ) || ( DBOPL_WAVE == WAVE_TABLELOG )
-
- //Exponential volume table, same as the real adlib
- for(int i = 0; i < 256; i++)
- {
- //Save them in reverse
- ExpTable[i] = (int)(0.5 + (pow(2.0, (255 - i) * (1.0 / 256)) - 1) * 1024);
- ExpTable[i] += 1024; //or remove the -1 oh well :)
- //Preshift to the left once so the final volume can shift to the right
- ExpTable[i] *= 2;
- }
-
- #endif
- #if ( DBOPL_WAVE == WAVE_HANDLER )
-
- //Add 0.5 for the trunc rounding of the integer cast
- //Do a PI sinetable instead of the original 0.5 PI
- for(int i = 0; i < 512; i++)
- SinTable[i] = (Bit16s)(0.5 - log10(sin((i + 0.5) * (PI / 512.0))) / log10(2.0) * 256);
-
- #endif
- #if ( DBOPL_WAVE == WAVE_TABLEMUL )
-
- //Multiplication based tables
- for(int i = 0; i < 384; i++)
- {
- int s = i * 8;
- //TODO maybe keep some of the precision errors of the original table?
- double val = (0.5 + (pow(2.0, -1.0 + (255 - s) * (1.0 / 256))) * (1 << MUL_SH));
- MulTable[i] = (Bit16u)(val);
- }
-
- //Sine Wave Base
- for(int i = 0; i < 512; i++)
- {
- WaveTable[ 0x0200 + i ] = (Bit16s)(sin((i + 0.5) * (PI / 512.0)) * 4084);
- WaveTable[ 0x0000 + i ] = -WaveTable[ 0x200 + i ];
- }
-
- //Exponential wave
- for(int i = 0; i < 256; i++)
- {
- WaveTable[ 0x700 + i ] = (Bit16s)(0.5 + (pow(2.0, -1.0 + (255 - i * 8) * (1.0 / 256))) * 4085);
- WaveTable[ 0x6ff - i ] = -WaveTable[ 0x700 + i ];
- }
-
- #endif
- #if ( DBOPL_WAVE == WAVE_TABLELOG )
-
- //Sine Wave Base
- for(int i = 0; i < 512; i++)
- {
- WaveTable[ 0x0200 + i ] = (Bit16s)(0.5 - log10(sin((i + 0.5) * (PI / 512.0))) / log10(2.0) * 256);
- WaveTable[ 0x0000 + i ] = ((Bit16s)0x8000) | WaveTable[ 0x200 + i];
- }
-
- //Exponential wave
- for(int i = 0; i < 256; i++)
- {
- WaveTable[ 0x700 + i ] = i * 8;
- WaveTable[ 0x6ff - i ] = ((Bit16s)0x8000) | i * 8;
- }
-
- #endif
- // | |//\\|____|WAV7|//__|/\ |____|/\/\|
- // |\\//| | |WAV7| | \/| | |
- // |06 |0126|27 |7 |3 |4 |4 5 |5 |
- #if (( DBOPL_WAVE == WAVE_TABLELOG ) || ( DBOPL_WAVE == WAVE_TABLEMUL ))
-
- for(int i = 0; i < 256; i++)
- {
- //Fill silence gaps
- WaveTable[ 0x400 + i ] = WaveTable[0];
- WaveTable[ 0x500 + i ] = WaveTable[0];
- WaveTable[ 0x900 + i ] = WaveTable[0];
- WaveTable[ 0xc00 + i ] = WaveTable[0];
- WaveTable[ 0xd00 + i ] = WaveTable[0];
- //Replicate sines in other pieces
- WaveTable[ 0x800 + i ] = WaveTable[ 0x200 + i ];
- //double speed sines
- WaveTable[ 0xa00 + i ] = WaveTable[ 0x200 + i * 2 ];
- WaveTable[ 0xb00 + i ] = WaveTable[ 0x000 + i * 2 ];
- WaveTable[ 0xe00 + i ] = WaveTable[ 0x200 + i * 2 ];
- WaveTable[ 0xf00 + i ] = WaveTable[ 0x200 + i * 2 ];
- }
-
- #endif
-
- //Create the ksl table
- for(int oct = 0; oct < 8; oct++)
- {
- int base = oct * 8;
-
- for(int i = 0; i < 16; i++)
- {
- int val = base - KslCreateTable[i];
-
- if(val < 0)
- val = 0;
-
- //*4 for the final range to match attenuation range
- KslTable[ oct * 16 + i ] = val * 4;
- }
- }
-
- //Create the Tremolo table, just increase and decrease a triangle wave
- for(Bit8u i = 0; i < TREMOLO_TABLE / 2; i++)
- {
- Bit8u val = i << ENV_EXTRA;
- TremoloTable[i] = val;
- TremoloTable[TREMOLO_TABLE - 1 - i] = val;
- }
-
- //Create a table with offsets of the channels from the start of the chip
- DBOPL::Chip *chip = 0;
-
- for(Bitu i = 0; i < 32; i++)
- {
- Bitu index = i & 0xf;
-
- if(index >= 9)
- {
- ChanOffsetTable[i] = 0;
- continue;
- }
-
- //Make sure the four op channels follow eachother
- if(index < 6)
- index = (index % 3) * 2 + (index / 3);
-
- //Add back the bits for highest ones
- if(i >= 16)
- index += 9;
-
- intptr_t blah = reinterpret_cast<intptr_t>(&(chip->chan[ index ]));
- ChanOffsetTable[i] = static_cast<Bit16u>(blah);
- }
-
- //Same for operators
- for(Bitu i = 0; i < 64; i++)
- {
- if(i % 8 >= 6 || ((i / 8) % 4 == 3))
- {
- OpOffsetTable[i] = 0;
- continue;
- }
-
- Bitu chNum = (i / 8) * 3 + (i % 8) % 3;
-
- //Make sure we use 16 and up for the 2nd range to match the chanoffset gap
- if(chNum >= 12)
- chNum += 16 - 12;
-
- Bitu opNum = (i % 8) / 3;
- DBOPL::Channel *chan = NULL;
- intptr_t blah = reinterpret_cast<intptr_t>(&(chan->op[opNum]));
- OpOffsetTable[i] = static_cast<Bit16u>((intptr_t)ChanOffsetTable[ chNum ] + blah);
- }
-
- #if 0
-
- //Stupid checks if table's are correct
- for(Bitu i = 0; i < 18; i++)
- {
- Bit32u find = (Bit16u)(&(chip->chan[ i ]));
-
- for(Bitu c = 0; c < 32; c++)
- {
- if(ChanOffsetTable[c] == find)
- {
- find = 0;
- break;
- }
- }
-
- if(find)
- find = find;
- }
-
- for(Bitu i = 0; i < 36; i++)
- {
- Bit32u find = (Bit16u)(&(chip->chan[ i / 2 ].op[i % 2]));
-
- for(Bitu c = 0; c < 64; c++)
- {
- if(OpOffsetTable[c] == find)
- {
- find = 0;
- break;
- }
- }
-
- if(find)
- find = find;
- }
-
- #endif
- }
-
- Bit32u Handler::WriteAddr(Bit32u port, Bit8u val)
- {
- return chip.WriteAddr(port, val);
- }
- void Handler::WriteReg(Bit32u addr, Bit8u val)
- {
- chip.WriteReg(addr, val);
- }
-
- void Handler::Generate(void(*AddSamples_m32)(Bitu, Bit32s *),
- void(*AddSamples_s32)(Bitu, Bit32s *),
- Bitu samples)
- {
- Bit32s buffer[ 512 * 2 ];
-
- if(GCC_UNLIKELY(samples > 512))
- samples = 512;
-
- if(!chip.opl3Active)
- {
- chip.GenerateBlock2(samples, buffer);
- AddSamples_m32(samples, buffer);
- }
- else
- {
- chip.GenerateBlock3(samples, buffer);
- AddSamples_s32(samples, buffer);
- }
- }
-
- void Handler::GenerateArr(Bit32s *out, Bitu *samples)
- {
- if(GCC_UNLIKELY(*samples > 512))
- *samples = 512;
-
- if(!chip.opl3Active)
- chip.GenerateBlock2(*samples, out);
- else
- chip.GenerateBlock3(*samples, out);
- }
-
- void Handler::GenerateArr(Bit32s *out, ssize_t *samples)
- {
- if(GCC_UNLIKELY(*samples > 512))
- *samples = 512;
-
- if(!chip.opl3Active)
- chip.GenerateBlock2(static_cast<Bitu>(*samples), out);
- else
- chip.GenerateBlock3(static_cast<Bitu>(*samples), out);
- }
-
- void Handler::GenerateArr(Bit16s *out, ssize_t *samples)
- {
- Bit32s out32[1024];
- if(GCC_UNLIKELY(*samples > 512))
- *samples = 512;
- memset(out32, 0, sizeof(Bit32s) * 1024);
- if(!chip.opl3Active)
- chip.GenerateBlock2(static_cast<Bitu>(*samples), out32);
- else
- chip.GenerateBlock3(static_cast<Bitu>(*samples), out32);
- ssize_t sz = *samples * 2;
- for(ssize_t i = 0; i < sz; i++)
- out[i] = static_cast<Bit16s>(DBOPL_CLAMP(out32[i], static_cast<ssize_t>(INT16_MIN), static_cast<ssize_t>(INT16_MAX)));
- }
-
- void Handler::GenerateArrMix(Bit32s *out, ssize_t *samples)
- {
- if(GCC_UNLIKELY(*samples > 512))
- *samples = 512;
- if(!chip.opl3Active)
- chip.GenerateBlock2_Mix(static_cast<Bitu>(*samples), out);
- else
- chip.GenerateBlock3_Mix(static_cast<Bitu>(*samples), out);
- }
-
- void Handler::GenerateArrMix(Bit16s *out, ssize_t *samples)
- {
- Bit32s out32[1024];
- if(GCC_UNLIKELY(*samples > 512))
- *samples = 512;
- memset(out32, 0, sizeof(Bit32s) * 1024);
- if(!chip.opl3Active)
- chip.GenerateBlock2(static_cast<Bitu>(*samples), out32);
- else
- chip.GenerateBlock3(static_cast<Bitu>(*samples), out32);
- ssize_t sz = *samples * 2;
- for(ssize_t i = 0; i < sz; i++)
- out[i] += static_cast<Bit16s>(DBOPL_CLAMP(out32[i], static_cast<ssize_t>(INT16_MIN), static_cast<ssize_t>(INT16_MAX)));
- }
-
-
- void Handler::Init(Bitu rate)
- {
- InitTables();
- chip.Setup((Bit32u)rate);
- }
-
-
-} //Namespace DBOPL
-
-//#endif //ADLMIDI_USE_DOSBOX_OPL
+#endif
+}
+
+Bits INLINE Operator::GetSample( Bits modulation ) {
+ Bitu vol = ForwardVolume();
+ if ( ENV_SILENT( vol ) ) {
+ //Simply forward the wave
+ waveIndex += waveCurrent;
+ return 0;
+ } else {
+ Bitu index = ForwardWave();
+ index += modulation;
+ return GetWave( index, vol );
+ }
+}
+
+Operator::Operator() {
+ chanData = 0;
+ freqMul = 0;
+ waveIndex = 0;
+ waveAdd = 0;
+ waveCurrent = 0;
+ keyOn = 0;
+ ksr = 0;
+ reg20 = 0;
+ reg40 = 0;
+ reg60 = 0;
+ reg80 = 0;
+ regE0 = 0;
+ SetState( OFF );
+ rateZero = (1 << OFF);
+ sustainLevel = ENV_MAX;
+ currentLevel = ENV_MAX;
+ totalLevel = ENV_MAX;
+ volume = ENV_MAX;
+ releaseAdd = 0;
+}
+
+/*
+ Channel
+*/
+
+Channel::Channel() {
+ old[0] = old[1] = 0;
+ chanData = 0;
+ regB0 = 0;
+ regC0 = 0;
+ maskLeft = -1;
+ maskRight = -1;
+ feedback = 31;
+ fourMask = 0;
+ synthHandler = &Channel::BlockTemplate< sm2FM >;
+}
+
+void Channel::SetChanData( const Chip* chip, Bit32u data ) {
+ Bit32u change = chanData ^ data;
+ chanData = data;
+ Op( 0 )->chanData = data;
+ Op( 1 )->chanData = data;
+ //Since a frequency update triggered this, always update frequency
+ Op( 0 )->UpdateFrequency();
+ Op( 1 )->UpdateFrequency();
+ if ( change & ( 0xff << SHIFT_KSLBASE ) ) {
+ Op( 0 )->UpdateAttenuation();
+ Op( 1 )->UpdateAttenuation();
+ }
+ if ( change & ( 0xff << SHIFT_KEYCODE ) ) {
+ Op( 0 )->UpdateRates( chip );
+ Op( 1 )->UpdateRates( chip );
+ }
+}
+
+void Channel::UpdateFrequency( const Chip* chip, Bit8u fourOp ) {
+ //Extrace the frequency bits
+ Bit32u data = chanData & 0xffff;
+ Bit32u kslBase = KslTable[ data >> 6 ];
+ Bit32u keyCode = ( data & 0x1c00) >> 9;
+ if ( chip->reg08 & 0x40 ) {
+ keyCode |= ( data & 0x100)>>8; /* notesel == 1 */
+ } else {
+ keyCode |= ( data & 0x200)>>9; /* notesel == 0 */
+ }
+ //Add the keycode and ksl into the highest bits of chanData
+ data |= (keyCode << SHIFT_KEYCODE) | ( kslBase << SHIFT_KSLBASE );
+ ( this + 0 )->SetChanData( chip, data );
+ if ( fourOp & 0x3f ) {
+ ( this + 1 )->SetChanData( chip, data );
+ }
+}
+
+void Channel::WriteA0( const Chip* chip, Bit8u val ) {
+ Bit8u fourOp = chip->reg104 & chip->opl3Active & fourMask;
+ //Don't handle writes to silent fourop channels
+ if ( fourOp > 0x80 )
+ return;
+ Bit32u change = (chanData ^ val ) & 0xff;
+ if ( change ) {
+ chanData ^= change;
+ UpdateFrequency( chip, fourOp );
+ }
+}
+
+void Channel::WriteB0( const Chip* chip, Bit8u val ) {
+ Bit8u fourOp = chip->reg104 & chip->opl3Active & fourMask;
+ //Don't handle writes to silent fourop channels
+ if ( fourOp > 0x80 )
+ return;
+ Bitu change = (chanData ^ ( val << 8 ) ) & 0x1f00;
+ if ( change ) {
+ chanData ^= change;
+ UpdateFrequency( chip, fourOp );
+ }
+ //Check for a change in the keyon/off state
+ if ( !(( val ^ regB0) & 0x20))
+ return;
+ regB0 = val;
+ if ( val & 0x20 ) {
+ Op(0)->KeyOn( 0x1 );
+ Op(1)->KeyOn( 0x1 );
+ if ( fourOp & 0x3f ) {
+ ( this + 1 )->Op(0)->KeyOn( 1 );
+ ( this + 1 )->Op(1)->KeyOn( 1 );
+ }
+ } else {
+ Op(0)->KeyOff( 0x1 );
+ Op(1)->KeyOff( 0x1 );
+ if ( fourOp & 0x3f ) {
+ ( this + 1 )->Op(0)->KeyOff( 1 );
+ ( this + 1 )->Op(1)->KeyOff( 1 );
+ }
+ }
+}
+
+void Channel::WriteC0(const Chip* chip, Bit8u val) {
+ Bit8u change = val ^ regC0;
+ if (!change)
+ return;
+ regC0 = val;
+ feedback = (regC0 >> 1) & 7;
+ if (feedback) {
+ //We shift the input to the right 10 bit wave index value
+ feedback = 9 - feedback;
+ }
+ else {
+ feedback = 31;
+ }
+ UpdateSynth(chip);
+}
+
+void Channel::UpdateSynth( const Chip* chip ) {
+ //Select the new synth mode
+ if ( chip->opl3Active ) {
+ //4-op mode enabled for this channel
+ if ( (chip->reg104 & fourMask) & 0x3f ) {
+ Channel* chan0, *chan1;
+ //Check if it's the 2nd channel in a 4-op
+ if ( !(fourMask & 0x80 ) ) {
+ chan0 = this;
+ chan1 = this + 1;
+ } else {
+ chan0 = this - 1;
+ chan1 = this;
+ }
+
+ Bit8u synth = ( (chan0->regC0 & 1) << 0 )| (( chan1->regC0 & 1) << 1 );
+ switch ( synth ) {
+ case 0:
+ chan0->synthHandler = &Channel::BlockTemplate< sm3FMFM >;
+ break;
+ case 1:
+ chan0->synthHandler = &Channel::BlockTemplate< sm3AMFM >;
+ break;
+ case 2:
+ chan0->synthHandler = &Channel::BlockTemplate< sm3FMAM >;
+ break;
+ case 3:
+ chan0->synthHandler = &Channel::BlockTemplate< sm3AMAM >;
+ break;
+ }
+ //Disable updating percussion channels
+ } else if ((fourMask & 0x40) && ( chip->regBD & 0x20) ) {
+
+ //Regular dual op, am or fm
+ } else if (regC0 & 1 ) {
+ synthHandler = &Channel::BlockTemplate< sm3AM >;
+ } else {
+ synthHandler = &Channel::BlockTemplate< sm3FM >;
+ }
+ maskLeft = (regC0 & 0x10 ) ? -1 : 0;
+ maskRight = (regC0 & 0x20 ) ? -1 : 0;
+ //opl2 active
+ } else {
+ //Disable updating percussion channels
+ if ( (fourMask & 0x40) && ( chip->regBD & 0x20 ) ) {
+
+ //Regular dual op, am or fm
+ } else if (regC0 & 1 ) {
+ synthHandler = &Channel::BlockTemplate< sm2AM >;
+ } else {
+ synthHandler = &Channel::BlockTemplate< sm2FM >;
+ }
+ }
+}
+
+template< bool opl3Mode>
+INLINE void Channel::GeneratePercussion( Chip* chip, Bit32s* output ) {
+ Channel* chan = this;
+
+ //BassDrum
+ Bit32s mod = (Bit32u)((old[0] + old[1])) >> feedback;
+ old[0] = old[1];
+ old[1] = static_cast<Bit32u>(Op(0)->GetSample( mod ));
+
+ //When bassdrum is in AM mode first operator is ignoed
+ if ( chan->regC0 & 1 ) {
+ mod = 0;
+ } else {
+ mod = old[0];
+ }
+ Bit32s sample = static_cast<Bit32u>(Op(1)->GetSample( mod ));
+
+
+ //Precalculate stuff used by other outputs
+ Bit32u noiseBit = chip->ForwardNoise() & 0x1;
+ Bit32u c2 = static_cast<Bit32u>(Op(2)->ForwardWave());
+ Bit32u c5 = static_cast<Bit32u>(Op(5)->ForwardWave());
+ Bit32u phaseBit = (((c2 & 0x88) ^ ((c2<<5) & 0x80)) | ((c5 ^ (c5<<2)) & 0x20)) ? 0x02 : 0x00;
+
+ //Hi-Hat
+ Bit32u hhVol = static_cast<Bit32u>(Op(2)->ForwardVolume());
+ if ( !ENV_SILENT( hhVol ) ) {
+ Bit32u hhIndex = (phaseBit<<8) | (0x34 << ( phaseBit ^ (noiseBit << 1 )));
+ sample += static_cast<Bit32u>(Op(2)->GetWave( hhIndex, hhVol ));
+ }
+ //Snare Drum
+ Bit32u sdVol = static_cast<Bit32u>(Op(3)->ForwardVolume());
+ if ( !ENV_SILENT( sdVol ) ) {
+ Bit32u sdIndex = ( 0x100 + (c2 & 0x100) ) ^ ( noiseBit << 8 );
+ sample += static_cast<Bit32u>(Op(3)->GetWave( sdIndex, sdVol ));
+ }
+ //Tom-tom
+ sample += static_cast<Bit32u>(Op(4)->GetSample( 0 ));
+
+ //Top-Cymbal
+ Bit32u tcVol = static_cast<Bit32u>(Op(5)->ForwardVolume());
+ if ( !ENV_SILENT( tcVol ) ) {
+ Bit32u tcIndex = (1 + phaseBit) << 8;
+ sample += static_cast<Bit32u>(Op(5)->GetWave( tcIndex, tcVol ));
+ }
+ sample <<= 1;
+ if ( opl3Mode ) {
+ output[0] += sample;
+ output[1] += sample;
+ } else {
+ output[0] += sample;
+ }
+}
+
+template<SynthMode mode>
+Channel* Channel::BlockTemplate( Chip* chip, Bit32u samples, Bit32s* output ) {
+ switch( mode ) {
+ case sm2AM:
+ case sm3AM:
+ if ( Op(0)->Silent() && Op(1)->Silent() ) {
+ old[0] = old[1] = 0;
+ return (this + 1);
+ }
+ break;
+ case sm2FM:
+ case sm3FM:
+ if ( Op(1)->Silent() ) {
+ old[0] = old[1] = 0;
+ return (this + 1);
+ }
+ break;
+ case sm3FMFM:
+ if ( Op(3)->Silent() ) {
+ old[0] = old[1] = 0;
+ return (this + 2);
+ }
+ break;
+ case sm3AMFM:
+ if ( Op(0)->Silent() && Op(3)->Silent() ) {
+ old[0] = old[1] = 0;
+ return (this + 2);
+ }
+ break;
+ case sm3FMAM:
+ if ( Op(1)->Silent() && Op(3)->Silent() ) {
+ old[0] = old[1] = 0;
+ return (this + 2);
+ }
+ break;
+ case sm3AMAM:
+ if ( Op(0)->Silent() && Op(2)->Silent() && Op(3)->Silent() ) {
+ old[0] = old[1] = 0;
+ return (this + 2);
+ }
+ break;
+ default:
+ break;
+ }
+ //Init the operators with the the current vibrato and tremolo values
+ Op( 0 )->Prepare( chip );
+ Op( 1 )->Prepare( chip );
+ if ( mode > sm4Start ) {
+ Op( 2 )->Prepare( chip );
+ Op( 3 )->Prepare( chip );
+ }
+ if ( mode > sm6Start ) {
+ Op( 4 )->Prepare( chip );
+ Op( 5 )->Prepare( chip );
+ }
+ for ( Bitu i = 0; i < samples; i++ ) {
+ //Early out for percussion handlers
+ if ( mode == sm2Percussion ) {
+ GeneratePercussion<false>( chip, output + i );
+ continue; //Prevent some unitialized value bitching
+ } else if ( mode == sm3Percussion ) {
+ GeneratePercussion<true>( chip, output + i * 2 );
+ continue; //Prevent some unitialized value bitching
+ }
+
+ //Do unsigned shift so we can shift out all bits but still stay in 10 bit range otherwise
+ Bit32s mod = (Bit32u)((old[0] + old[1])) >> feedback;
+ old[0] = old[1];
+ old[1] = static_cast<Bit32u>(Op(0)->GetSample( mod ));
+ Bit32s sample;
+ Bit32s out0 = old[0];
+ if ( mode == sm2AM || mode == sm3AM ) {
+ sample = static_cast<Bit32u>(out0 + Op(1)->GetSample( 0 ));
+ } else if ( mode == sm2FM || mode == sm3FM ) {
+ sample = static_cast<Bit32u>(Op(1)->GetSample( out0 ));
+ } else if ( mode == sm3FMFM ) {
+ Bits next = Op(1)->GetSample( out0 );
+ next = Op(2)->GetSample( next );
+ sample = static_cast<Bit32u>(Op(3)->GetSample( next ));
+ } else if ( mode == sm3AMFM ) {
+ sample = out0;
+ Bits next = Op(1)->GetSample( 0 );
+ next = Op(2)->GetSample( next );
+ sample += static_cast<Bit32u>(Op(3)->GetSample( next ));
+ } else if ( mode == sm3FMAM ) {
+ sample = static_cast<Bit32u>(Op(1)->GetSample( out0 ));
+ Bits next = Op(2)->GetSample( 0 );
+ sample += static_cast<Bit32u>(Op(3)->GetSample( next ));
+ } else if ( mode == sm3AMAM ) {
+ sample = out0;
+ Bits next = Op(1)->GetSample( 0 );
+ sample += static_cast<Bit32u>(Op(2)->GetSample( next ));
+ sample += static_cast<Bit32u>(Op(3)->GetSample( 0 ));
+ }
+ switch( mode ) {
+ case sm2AM:
+ case sm2FM:
+ output[ i ] += sample;
+ break;
+ case sm3AM:
+ case sm3FM:
+ case sm3FMFM:
+ case sm3AMFM:
+ case sm3FMAM:
+ case sm3AMAM:
+ output[ i * 2 + 0 ] += sample & maskLeft;
+ output[ i * 2 + 1 ] += sample & maskRight;
+ break;
+ default:
+ break;
+ }
+ }
+ switch( mode ) {
+ case sm2AM:
+ case sm2FM:
+ case sm3AM:
+ case sm3FM:
+ return ( this + 1 );
+ case sm3FMFM:
+ case sm3AMFM:
+ case sm3FMAM:
+ case sm3AMAM:
+ return( this + 2 );
+ case sm2Percussion:
+ case sm3Percussion:
+ return( this + 3 );
+ }
+ return 0;
+}
+
+/*
+ Chip
+*/
+
+Chip::Chip() {
+ reg08 = 0;
+ reg04 = 0;
+ regBD = 0;
+ reg104 = 0;
+ opl3Active = 0;
+}
+
+INLINE Bit32u Chip::ForwardNoise() {
+ noiseCounter += noiseAdd;
+ Bitu count = noiseCounter >> LFO_SH;
+ noiseCounter &= WAVE_MASK;
+ for ( ; count > 0; --count ) {
+ //Noise calculation from mame
+ noiseValue ^= ( 0x800302 ) & ( 0 - (noiseValue & 1 ) );
+ noiseValue >>= 1;
+ }
+ return noiseValue;
+}
+
+INLINE Bit32u Chip::ForwardLFO( Bit32u samples ) {
+ //Current vibrato value, runs 4x slower than tremolo
+ vibratoSign = ( VibratoTable[ vibratoIndex >> 2] ) >> 7;
+ vibratoShift = ( VibratoTable[ vibratoIndex >> 2] & 7) + vibratoStrength;
+ tremoloValue = TremoloTable[ tremoloIndex ] >> tremoloStrength;
+
+ //Check hom many samples there can be done before the value changes
+ Bit32u todo = LFO_MAX - lfoCounter;
+ Bit32u count = (todo + lfoAdd - 1) / lfoAdd;
+ if ( count > samples ) {
+ count = samples;
+ lfoCounter += count * lfoAdd;
+ } else {
+ lfoCounter += count * lfoAdd;
+ lfoCounter &= (LFO_MAX - 1);
+ //Maximum of 7 vibrato value * 4
+ vibratoIndex = ( vibratoIndex + 1 ) & 31;
+ //Clip tremolo to the the table size
+ if ( tremoloIndex + 1 < TREMOLO_TABLE )
+ ++tremoloIndex;
+ else
+ tremoloIndex = 0;
+ }
+ return count;
+}
+
+
+void Chip::WriteBD( Bit8u val ) {
+ Bit8u change = regBD ^ val;
+ if ( !change )
+ return;
+ regBD = val;
+ //TODO could do this with shift and xor?
+ vibratoStrength = (val & 0x40) ? 0x00 : 0x01;
+ tremoloStrength = (val & 0x80) ? 0x00 : 0x02;
+ if ( val & 0x20 ) {
+ //Drum was just enabled, make sure channel 6 has the right synth
+ if ( change & 0x20 ) {
+ if ( opl3Active ) {
+ chan[6].synthHandler = &Channel::BlockTemplate< sm3Percussion >;
+ } else {
+ chan[6].synthHandler = &Channel::BlockTemplate< sm2Percussion >;
+ }
+ }
+ //Bass Drum
+ if ( val & 0x10 ) {
+ chan[6].op[0].KeyOn( 0x2 );
+ chan[6].op[1].KeyOn( 0x2 );
+ } else {
+ chan[6].op[0].KeyOff( 0x2 );
+ chan[6].op[1].KeyOff( 0x2 );
+ }
+ //Hi-Hat
+ if ( val & 0x1 ) {
+ chan[7].op[0].KeyOn( 0x2 );
+ } else {
+ chan[7].op[0].KeyOff( 0x2 );
+ }
+ //Snare
+ if ( val & 0x8 ) {
+ chan[7].op[1].KeyOn( 0x2 );
+ } else {
+ chan[7].op[1].KeyOff( 0x2 );
+ }
+ //Tom-Tom
+ if ( val & 0x4 ) {
+ chan[8].op[0].KeyOn( 0x2 );
+ } else {
+ chan[8].op[0].KeyOff( 0x2 );
+ }
+ //Top Cymbal
+ if ( val & 0x2 ) {
+ chan[8].op[1].KeyOn( 0x2 );
+ } else {
+ chan[8].op[1].KeyOff( 0x2 );
+ }
+ //Toggle keyoffs when we turn off the percussion
+ } else if ( change & 0x20 ) {
+ //Trigger a reset to setup the original synth handler
+ //This makes it call
+ chan[6].UpdateSynth( this );
+ chan[6].op[0].KeyOff( 0x2 );
+ chan[6].op[1].KeyOff( 0x2 );
+ chan[7].op[0].KeyOff( 0x2 );
+ chan[7].op[1].KeyOff( 0x2 );
+ chan[8].op[0].KeyOff( 0x2 );
+ chan[8].op[1].KeyOff( 0x2 );
+ }
+}
+
+
+#define REGOP( _FUNC_ ) \
+ index = ( ( reg >> 3) & 0x20 ) | ( reg & 0x1f ); \
+ if ( OpOffsetTable[ index ] ) { \
+ Operator* regOp = (Operator*)( ((char *)this ) + OpOffsetTable[ index ] ); \
+ regOp->_FUNC_( this, val ); \
+ }
+
+#define REGCHAN( _FUNC_ ) \
+ index = ( ( reg >> 4) & 0x10 ) | ( reg & 0xf ); \
+ if ( ChanOffsetTable[ index ] ) { \
+ Channel* regChan = (Channel*)( ((char *)this ) + ChanOffsetTable[ index ] ); \
+ regChan->_FUNC_( this, val ); \
+ }
+
+//Update the 0xc0 register for all channels to signal the switch to mono/stereo handlers
+void Chip::UpdateSynths() {
+ for (int i = 0; i < 18; i++) {
+ chan[i].UpdateSynth(this);
+ }
+}
+
+
+void Chip::WriteReg( Bit32u reg, Bit8u val ) {
+ Bitu index;
+ switch ( (reg & 0xf0) >> 4 ) {
+ case 0x00 >> 4:
+ if ( reg == 0x01 ) {
+ waveFormMask = ( val & 0x20 ) ? 0x7 : 0x0;
+ } else if ( reg == 0x104 ) {
+ //Only detect changes in lowest 6 bits
+ if ( !((reg104 ^ val) & 0x3f) )
+ return;
+ //Always keep the highest bit enabled, for checking > 0x80
+ reg104 = 0x80 | ( val & 0x3f );
+ //Switch synths when changing the 4op combinations
+ UpdateSynths();
+ } else if ( reg == 0x105 ) {
+ //MAME says the real opl3 doesn't reset anything on opl3 disable/enable till the next write in another register
+ if ( !((opl3Active ^ val) & 1 ) )
+ return;
+ opl3Active = ( val & 1 ) ? 0xff : 0;
+ //Just tupdate the synths now that opl3 most have been enabled
+ //This isn't how the real card handles it but need to switch to stereo generating handlers
+ UpdateSynths();
+ } else if ( reg == 0x08 ) {
+ reg08 = val;
+ }
+ case 0x10 >> 4:
+ break;
+ case 0x20 >> 4:
+ case 0x30 >> 4:
+ REGOP( Write20 );
+ break;
+ case 0x40 >> 4:
+ case 0x50 >> 4:
+ REGOP( Write40 );
+ break;
+ case 0x60 >> 4:
+ case 0x70 >> 4:
+ REGOP( Write60 );
+ break;
+ case 0x80 >> 4:
+ case 0x90 >> 4:
+ REGOP( Write80 );
+ break;
+ case 0xa0 >> 4:
+ REGCHAN( WriteA0 );
+ break;
+ case 0xb0 >> 4:
+ if ( reg == 0xbd ) {
+ WriteBD( val );
+ } else {
+ REGCHAN( WriteB0 );
+ }
+ break;
+ case 0xc0 >> 4:
+ REGCHAN( WriteC0 );
+ case 0xd0 >> 4:
+ break;
+ case 0xe0 >> 4:
+ case 0xf0 >> 4:
+ REGOP( WriteE0 );
+ break;
+ }
+}
+
+
+Bit32u Chip::WriteAddr( Bit32u port, Bit8u val ) {
+ switch ( port & 3 ) {
+ case 0:
+ return val;
+ case 2:
+ if ( opl3Active || (val == 0x05) )
+ return 0x100 | val;
+ else
+ return val;
+ }
+ return 0;
+}
+
+void Chip::GenerateBlock2( Bitu total, Bit32s* output ) {
+ while ( total > 0 ) {
+ Bit32u samples = ForwardLFO( static_cast<Bit32u>(total) );
+ memset(output, 0, sizeof(Bit32s) * samples);
+// int count = 0;
+ for( Channel* ch = chan; ch < chan + 9; ) {
+// count++;
+ ch = (ch->*(ch->synthHandler))( this, samples, output );
+ }
+ total -= samples;
+ output += samples;
+ }
+}
+
+void Chip::GenerateBlock2_Mix( Bitu total, Bit32s* output ) {
+ while ( total > 0 ) {
+ Bit32u samples = ForwardLFO( static_cast<Bit32u>(total) );
+// int count = 0;
+ for( Channel* ch = chan; ch < chan + 9; ) {
+// count++;
+ ch = (ch->*(ch->synthHandler))( this, samples, output );
+ }
+ total -= samples;
+ output += samples;
+ }
+}
+
+void Chip::GenerateBlock3( Bitu total, Bit32s* output ) {
+ while ( total > 0 ) {
+ Bit32u samples = ForwardLFO( static_cast<Bit32u>(total) );
+ memset(output, 0, sizeof(Bit32s) * samples *2);
+// int count = 0;
+ for( Channel* ch = chan; ch < chan + 18; ) {
+// count++;
+ ch = (ch->*(ch->synthHandler))( this, samples, output );
+ }
+ total -= samples;
+ output += samples * 2;
+ }
+}
+
+void Chip::GenerateBlock3_Mix( Bitu total, Bit32s* output ) {
+ while ( total > 0 ) {
+ Bit32u samples = ForwardLFO( static_cast<Bit32u>(total) );
+// int count = 0;
+ for( Channel* ch = chan; ch < chan + 18; ) {
+// count++;
+ ch = (ch->*(ch->synthHandler))( this, samples, output );
+ }
+ total -= samples;
+ output += samples * 2;
+ }
+}
+
+void Chip::Setup( Bit32u rate ) {
+ double original = OPLRATE;
+// double original = rate;
+ double scale = original / (double)rate;
+
+ //Noise counter is run at the same precision as general waves
+ noiseAdd = (Bit32u)( 0.5 + scale * ( 1 << LFO_SH ) );
+ noiseCounter = 0;
+ noiseValue = 1; //Make sure it triggers the noise xor the first time
+ //The low frequency oscillation counter
+ //Every time his overflows vibrato and tremoloindex are increased
+ lfoAdd = (Bit32u)( 0.5 + scale * ( 1 << LFO_SH ) );
+ lfoCounter = 0;
+ vibratoIndex = 0;
+ tremoloIndex = 0;
+
+ //With higher octave this gets shifted up
+ //-1 since the freqCreateTable = *2
+#ifdef WAVE_PRECISION
+ double freqScale = ( 1 << 7 ) * scale * ( 1 << ( WAVE_SH - 1 - 10));
+ for ( int i = 0; i < 16; i++ ) {
+ freqMul[i] = (Bit32u)( 0.5 + freqScale * FreqCreateTable[ i ] );
+ }
+#else
+ Bit32u freqScale = (Bit32u)( 0.5 + scale * ( 1 << ( WAVE_SH - 1 - 10)));
+ for ( int i = 0; i < 16; i++ ) {
+ freqMul[i] = freqScale * FreqCreateTable[ i ];
+ }
+#endif
+
+ //-3 since the real envelope takes 8 steps to reach the single value we supply
+ for ( Bit8u i = 0; i < 76; i++ ) {
+ Bit8u index, shift;
+ EnvelopeSelect( i, index, shift );
+ linearRates[i] = (Bit32u)( scale * (EnvelopeIncreaseTable[ index ] << ( RATE_SH + ENV_EXTRA - shift - 3 )));
+ }
+// Bit32s attackDiffs[62];
+ //Generate the best matching attack rate
+ for ( Bit8u i = 0; i < 62; i++ ) {
+ Bit8u index, shift;
+ EnvelopeSelect( i, index, shift );
+ //Original amount of samples the attack would take
+ Bit32s original = (Bit32u)( (AttackSamplesTable[ index ] << shift) / scale);
+
+ Bit32s guessAdd = (Bit32u)( scale * (EnvelopeIncreaseTable[ index ] << ( RATE_SH - shift - 3 )));
+ Bit32s bestAdd = guessAdd;
+ Bit32u bestDiff = 1 << 30;
+ for( Bit32u passes = 0; passes < 16; passes ++ ) {
+ Bit32s volume = ENV_MAX;
+ Bit32s samples = 0;
+ Bit32u count = 0;
+ while ( volume > 0 && samples < original * 2 ) {
+ count += guessAdd;
+ Bit32s change = count >> RATE_SH;
+ count &= RATE_MASK;
+ if ( GCC_UNLIKELY(change) ) { // less than 1 %
+ volume += ( ~volume * change ) >> 3;
+ }
+ samples++;
+
+ }
+ Bit32s diff = original - samples;
+ Bit32u lDiff = labs( diff );
+ //Init last on first pass
+ if ( lDiff < bestDiff ) {
+ bestDiff = lDiff;
+ bestAdd = guessAdd;
+ //We hit an exactly matching sample count
+ if ( !bestDiff )
+ break;
+ }
+ //Linear correction factor, not exactly perfect but seems to work
+ double correct = (original - diff) / (double)original;
+ guessAdd = (Bit32u)(guessAdd * correct);
+ //Below our target
+ if ( diff < 0 ) {
+ //Always add one here for rounding, an overshoot will get corrected by another pass decreasing
+ guessAdd++;
+ }
+ }
+ attackRates[i] = bestAdd;
+ //Keep track of the diffs for some debugging
+// attackDiffs[i] = bestDiff;
+ }
+ for ( Bit8u i = 62; i < 76; i++ ) {
+ //This should provide instant volume maximizing
+ attackRates[i] = 8 << RATE_SH;
+ }
+ //Setup the channels with the correct four op flags
+ //Channels are accessed through a table so they appear linear here
+ chan[ 0].fourMask = 0x00 | ( 1 << 0 );
+ chan[ 1].fourMask = 0x80 | ( 1 << 0 );
+ chan[ 2].fourMask = 0x00 | ( 1 << 1 );
+ chan[ 3].fourMask = 0x80 | ( 1 << 1 );
+ chan[ 4].fourMask = 0x00 | ( 1 << 2 );
+ chan[ 5].fourMask = 0x80 | ( 1 << 2 );
+
+ chan[ 9].fourMask = 0x00 | ( 1 << 3 );
+ chan[10].fourMask = 0x80 | ( 1 << 3 );
+ chan[11].fourMask = 0x00 | ( 1 << 4 );
+ chan[12].fourMask = 0x80 | ( 1 << 4 );
+ chan[13].fourMask = 0x00 | ( 1 << 5 );
+ chan[14].fourMask = 0x80 | ( 1 << 5 );
+
+ //mark the percussion channels
+ chan[ 6].fourMask = 0x40;
+ chan[ 7].fourMask = 0x40;
+ chan[ 8].fourMask = 0x40;
+
+ //Clear Everything in opl3 mode
+ WriteReg( 0x105, 0x1 );
+ for ( int i = 0; i < 512; i++ ) {
+ if ( i == 0x105 )
+ continue;
+ WriteReg( i, 0xff );
+ WriteReg( i, 0x0 );
+ }
+ WriteReg( 0x105, 0x0 );
+ //Clear everything in opl2 mode
+ for ( int i = 0; i < 255; i++ ) {
+ WriteReg( i, 0xff );
+ WriteReg( i, 0x0 );
+ }
+}
+
+static bool doneTables = false;
+void InitTables( void ) {
+ if ( doneTables )
+ return;
+ doneTables = true;
+#if ( DBOPL_WAVE == WAVE_HANDLER ) || ( DBOPL_WAVE == WAVE_TABLELOG )
+ //Exponential volume table, same as the real adlib
+ for ( int i = 0; i < 256; i++ ) {
+ //Save them in reverse
+ ExpTable[i] = (int)( 0.5 + ( pow(2.0, ( 255 - i) * ( 1.0 /256 ) )-1) * 1024 );
+ ExpTable[i] += 1024; //or remove the -1 oh well :)
+ //Preshift to the left once so the final volume can shift to the right
+ ExpTable[i] *= 2;
+ }
+#endif
+#if ( DBOPL_WAVE == WAVE_HANDLER )
+ //Add 0.5 for the trunc rounding of the integer cast
+ //Do a PI sinetable instead of the original 0.5 PI
+ for ( int i = 0; i < 512; i++ ) {
+ SinTable[i] = (Bit16s)( 0.5 - log10( sin( (i + 0.5) * (PI / 512.0) ) ) / log10(2.0)*256 );
+ }
+#endif
+#if ( DBOPL_WAVE == WAVE_TABLEMUL )
+ //Multiplication based tables
+ for ( int i = 0; i < 384; i++ ) {
+ int s = i * 8;
+ //TODO maybe keep some of the precision errors of the original table?
+ double val = ( 0.5 + ( pow(2.0, -1.0 + ( 255 - s) * ( 1.0 /256 ) )) * ( 1 << MUL_SH ));
+ MulTable[i] = (Bit16u)(val);
+ }
+
+ //Sine Wave Base
+ for ( int i = 0; i < 512; i++ ) {
+ WaveTable[ 0x0200 + i ] = (Bit16s)(sin( (i + 0.5) * (PI / 512.0) ) * 4084);
+ WaveTable[ 0x0000 + i ] = -WaveTable[ 0x200 + i ];
+ }
+ //Exponential wave
+ for ( int i = 0; i < 256; i++ ) {
+ WaveTable[ 0x700 + i ] = (Bit16s)( 0.5 + ( pow(2.0, -1.0 + ( 255 - i * 8) * ( 1.0 /256 ) ) ) * 4085 );
+ WaveTable[ 0x6ff - i ] = -WaveTable[ 0x700 + i ];
+ }
+#endif
+#if ( DBOPL_WAVE == WAVE_TABLELOG )
+ //Sine Wave Base
+ for ( int i = 0; i < 512; i++ ) {
+ WaveTable[ 0x0200 + i ] = (Bit16s)( 0.5 - log10( sin( (i + 0.5) * (PI / 512.0) ) ) / log10(2.0)*256 );
+ WaveTable[ 0x0000 + i ] = ((Bit16s)0x8000) | WaveTable[ 0x200 + i];
+ }
+ //Exponential wave
+ for ( int i = 0; i < 256; i++ ) {
+ WaveTable[ 0x700 + i ] = i * 8;
+ WaveTable[ 0x6ff - i ] = ((Bit16s)0x8000) | i * 8;
+ }
+#endif
+
+ // | |//\\|____|WAV7|//__|/\ |____|/\/\|
+ // |\\//| | |WAV7| | \/| | |
+ // |06 |0126|27 |7 |3 |4 |4 5 |5 |
+
+#if (( DBOPL_WAVE == WAVE_TABLELOG ) || ( DBOPL_WAVE == WAVE_TABLEMUL ))
+ for ( int i = 0; i < 256; i++ ) {
+ //Fill silence gaps
+ WaveTable[ 0x400 + i ] = WaveTable[0];
+ WaveTable[ 0x500 + i ] = WaveTable[0];
+ WaveTable[ 0x900 + i ] = WaveTable[0];
+ WaveTable[ 0xc00 + i ] = WaveTable[0];
+ WaveTable[ 0xd00 + i ] = WaveTable[0];
+ //Replicate sines in other pieces
+ WaveTable[ 0x800 + i ] = WaveTable[ 0x200 + i ];
+ //double speed sines
+ WaveTable[ 0xa00 + i ] = WaveTable[ 0x200 + i * 2 ];
+ WaveTable[ 0xb00 + i ] = WaveTable[ 0x000 + i * 2 ];
+ WaveTable[ 0xe00 + i ] = WaveTable[ 0x200 + i * 2 ];
+ WaveTable[ 0xf00 + i ] = WaveTable[ 0x200 + i * 2 ];
+ }
+#endif
+
+ //Create the ksl table
+ for ( int oct = 0; oct < 8; oct++ ) {
+ int base = oct * 8;
+ for ( int i = 0; i < 16; i++ ) {
+ int val = base - KslCreateTable[i];
+ if ( val < 0 )
+ val = 0;
+ //*4 for the final range to match attenuation range
+ KslTable[ oct * 16 + i ] = val * 4;
+ }
+ }
+ //Create the Tremolo table, just increase and decrease a triangle wave
+ for ( Bit8u i = 0; i < TREMOLO_TABLE / 2; i++ ) {
+ Bit8u val = i << ENV_EXTRA;
+ TremoloTable[i] = val;
+ TremoloTable[TREMOLO_TABLE - 1 - i] = val;
+ }
+ //Create a table with offsets of the channels from the start of the chip
+ DBOPL::Chip* chip = 0;
+ for ( Bitu i = 0; i < 32; i++ ) {
+ Bitu index = i & 0xf;
+ if ( index >= 9 ) {
+ ChanOffsetTable[i] = 0;
+ continue;
+ }
+ //Make sure the four op channels follow eachother
+ if ( index < 6 ) {
+ index = (index % 3) * 2 + ( index / 3 );
+ }
+ //Add back the bits for highest ones
+ if ( i >= 16 )
+ index += 9;
+ Bitu blah = reinterpret_cast<Bitu>( &(chip->chan[ index ]) );
+ ChanOffsetTable[i] = static_cast<Bit16u>(blah);
+ }
+ //Same for operators
+ for ( Bitu i = 0; i < 64; i++ ) {
+ if ( i % 8 >= 6 || ( (i / 8) % 4 == 3 ) ) {
+ OpOffsetTable[i] = 0;
+ continue;
+ }
+ Bitu chNum = (i / 8) * 3 + (i % 8) % 3;
+ //Make sure we use 16 and up for the 2nd range to match the chanoffset gap
+ if ( chNum >= 12 )
+ chNum += 16 - 12;
+ Bitu opNum = ( i % 8 ) / 3;
+ DBOPL::Channel* chan = 0;
+ Bitu blah = reinterpret_cast<Bitu>( &(chan->op[opNum]) );
+ OpOffsetTable[i] = static_cast<Bit16u>(ChanOffsetTable[ chNum ] + blah);
+ }
+#if 0
+ //Stupid checks if table's are correct
+ for ( Bitu i = 0; i < 18; i++ ) {
+ Bit32u find = (Bit16u)( &(chip->chan[ i ]) );
+ for ( Bitu c = 0; c < 32; c++ ) {
+ if ( ChanOffsetTable[c] == find ) {
+ find = 0;
+ break;
+ }
+ }
+ if ( find ) {
+ find = find;
+ }
+ }
+ for ( Bitu i = 0; i < 36; i++ ) {
+ Bit32u find = (Bit16u)( &(chip->chan[ i / 2 ].op[i % 2]) );
+ for ( Bitu c = 0; c < 64; c++ ) {
+ if ( OpOffsetTable[c] == find ) {
+ find = 0;
+ break;
+ }
+ }
+ if ( find ) {
+ find = find;
+ }
+ }
+#endif
+}
+
+Bit32u Handler::WriteAddr( Bit32u port, Bit8u val ) {
+ return chip.WriteAddr( port, val );
+
+}
+void Handler::WriteReg( Bit32u addr, Bit8u val ) {
+ chip.WriteReg( addr, val );
+}
+
+#define DB_MAX(x, y) ((x) > (y) ? (x) : (y))
+#define DB_MIN(x, y) ((x) < (y) ? (x) : (y))
+
+#define DBOPL_CLAMP(V, MIN, MAX) DB_MAX(DB_MIN(V, (MAX)), (MIN))
+
+void Handler::GenerateArr(Bit32s *out, Bitu *samples)
+{
+ if(GCC_UNLIKELY(*samples > 512))
+ *samples = 512;
+ if(!chip.opl3Active)
+ chip.GenerateBlock2(*samples, out);
+ else
+ chip.GenerateBlock3(*samples, out);
+}
+
+void Handler::GenerateArr(Bit16s *out, Bitu *samples)
+{
+ Bit32s out32[1024];
+ if(GCC_UNLIKELY(*samples > 512))
+ *samples = 512;
+ memset(out32, 0, sizeof(Bit32s) * 1024);
+ if(!chip.opl3Active)
+ chip.GenerateBlock2(*samples, out32);
+ else
+ chip.GenerateBlock3(*samples, out32);
+ Bitu sz = *samples * 2;
+ for(Bitu i = 0; i < sz; i++)
+ out[i] = static_cast<Bit16s>(DBOPL_CLAMP(out32[i], INT16_MIN, INT16_MAX));
+}
+
+void Handler::GenerateArrMix(Bit32s *out, Bitu *samples)
+{
+ if(GCC_UNLIKELY(*samples > 512))
+ *samples = 512;
+ if(!chip.opl3Active)
+ chip.GenerateBlock2_Mix(*samples, out);
+ else
+ chip.GenerateBlock3_Mix(*samples, out);
+}
+
+void Handler::GenerateArrMix(Bit16s *out, Bitu *samples)
+{
+ Bit32s out32[1024];
+ if(GCC_UNLIKELY(*samples > 512))
+ *samples = 512;
+ memset(out32, 0, sizeof(Bit32s) * 1024);
+ if(!chip.opl3Active)
+ chip.GenerateBlock2(*samples, out32);
+ else
+ chip.GenerateBlock3(*samples, out32);
+ Bitu sz = *samples * 2;
+ for(Bitu i = 0; i < sz; i++)
+ out[i] += static_cast<Bit16s>(DBOPL_CLAMP(out32[i], INT16_MIN, INT16_MAX));
+}
+
+void Handler::Init( Bitu rate ) {
+ InitTables();
+ chip.Setup( static_cast<Bit32u>(rate) );
+}
+
+
+} //Namespace DBOPL
diff --git a/src/chips/dosbox/dbopl.h b/src/chips/dosbox/dbopl.h
index 13c606f..73c0aa9 100644
--- a/src/chips/dosbox/dbopl.h
+++ b/src/chips/dosbox/dbopl.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002-2010 The DOSBox Team
+ * Copyright (C) 2002-2018 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,28 +16,28 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-
-/* BEGIN MIDIPLAY GLUE */
+#include <inttypes.h>
#include <stdint.h>
-#include <stdlib.h>
#include <sys/types.h>
-typedef unsigned long Bitu;
-typedef signed long Bits;
-typedef unsigned Bit32u;
-typedef int Bit32s;
-typedef unsigned short Bit16u;
-typedef signed short Bit16s;
-typedef unsigned char Bit8u;
-typedef signed char Bit8s;
-#define INLINE inline
-#ifdef _MSC_VER
-#define GCC_UNLIKELY(x) (!!(x) == 0)
-#define GCC_LIKELY(x) (!!(x) == 1)
+
+#if defined(__GNUC__) && defined(__i386__)
+#define DB_FASTCALL __attribute__((fastcall))
+#elif defined(_MSC_VER)
+#define DB_FASTCALL __fastcall
#else
-#define GCC_UNLIKELY(x) __builtin_expect((x),0)
-#define GCC_LIKELY(x) __builtin_expect((x),1)
+#define DB_FASTCALL
#endif
-/* END MIDIPLAY GLUE */
+
+typedef uintptr_t Bitu;
+typedef intptr_t Bits;
+typedef uint64_t Bit64u;
+typedef int64_t Bit64s;
+typedef uint32_t Bit32u;
+typedef int32_t Bit32s;
+typedef uint16_t Bit16u;
+typedef int16_t Bit16s;
+typedef uint8_t Bit8u;
+typedef int8_t Bit8s;
//Use 8 handlers based on a small logatirmic wavetabe and an exponential table for volume
#define WAVE_HANDLER 10
@@ -49,267 +49,236 @@ typedef signed char Bit8s;
//Select the type of wave generator routine
#define DBOPL_WAVE WAVE_TABLEMUL
-#ifdef _WIN32
-# ifdef _MSC_VER
-# ifdef _WIN64
-typedef __int64 ssize_t;
-# else
-typedef __int32 ssize_t;
-# endif
-# else
-# ifdef _WIN64
-typedef int64_t ssize_t;
-# else
-typedef int32_t ssize_t;
-# endif
-# endif
-#endif
-
-namespace DBOPL
-{
+namespace DBOPL {
- struct Chip;
- struct Operator;
- struct Channel;
+struct Chip;
+struct Operator;
+struct Channel;
#if (DBOPL_WAVE == WAVE_HANDLER)
- typedef Bits(DB_FASTCALL *WaveHandler)(Bitu i, Bitu volume);
+typedef Bits ( DB_FASTCALL *WaveHandler) ( Bitu i, Bitu volume );
#endif
- typedef Bits(DBOPL::Operator::*VolumeHandler)();
- typedef Channel *(DBOPL::Channel::*SynthHandler)(Chip *chip, Bit32u samples, Bit32s *output);
-
- //Different synth modes that can generate blocks of data
- typedef enum
- {
- sm2AM,
- sm2FM,
- sm3AM,
- sm3FM,
- sm4Start,
- sm3FMFM,
- sm3AMFM,
- sm3FMAM,
- sm3AMAM,
- sm6Start,
- sm2Percussion,
- sm3Percussion
- } SynthMode;
-
- //Shifts for the values contained in chandata variable
- enum
- {
- SHIFT_KSLBASE = 16,
- SHIFT_KEYCODE = 24
- };
-
- struct Operator
- {
- public:
- //Masks for operator 20 values
- enum
- {
- MASK_KSR = 0x10,
- MASK_SUSTAIN = 0x20,
- MASK_VIBRATO = 0x40,
- MASK_TREMOLO = 0x80
- };
-
- typedef enum
- {
- OFF,
- RELEASE,
- SUSTAIN,
- DECAY,
- ATTACK
- } State;
-
- VolumeHandler volHandler;
+typedef Bits ( DBOPL::Operator::*VolumeHandler) ( );
+typedef Channel* ( DBOPL::Channel::*SynthHandler) ( Chip* chip, Bit32u samples, Bit32s* output );
+
+//Different synth modes that can generate blocks of data
+typedef enum {
+ sm2AM,
+ sm2FM,
+ sm3AM,
+ sm3FM,
+ sm4Start,
+ sm3FMFM,
+ sm3AMFM,
+ sm3FMAM,
+ sm3AMAM,
+ sm6Start,
+ sm2Percussion,
+ sm3Percussion,
+} SynthMode;
+
+//Shifts for the values contained in chandata variable
+enum {
+ SHIFT_KSLBASE = 16,
+ SHIFT_KEYCODE = 24,
+};
+
+struct Operator {
+public:
+ //Masks for operator 20 values
+ enum {
+ MASK_KSR = 0x10,
+ MASK_SUSTAIN = 0x20,
+ MASK_VIBRATO = 0x40,
+ MASK_TREMOLO = 0x80,
+ };
+
+ typedef enum {
+ OFF,
+ RELEASE,
+ SUSTAIN,
+ DECAY,
+ ATTACK,
+ } State;
+
+ VolumeHandler volHandler;
#if (DBOPL_WAVE == WAVE_HANDLER)
- WaveHandler waveHandler; //Routine that generate a wave
+ WaveHandler waveHandler; //Routine that generate a wave
#else
- Bit16s *waveBase;
- Bit32u waveMask;
- Bit32u waveStart;
+ Bit16s* waveBase;
+ Bit32u waveMask;
+ Bit32u waveStart;
#endif
- Bit32u waveIndex; //WAVE_BITS shifted counter of the frequency index
- Bit32u waveAdd; //The base frequency without vibrato
- Bit32u waveCurrent; //waveAdd + vibratao
-
- Bit32u chanData; //Frequency/octave and derived data coming from whatever channel controls this
- Bit32u freqMul; //Scale channel frequency with this, TODO maybe remove?
- Bit32u vibrato; //Scaled up vibrato strength
- Bit32s sustainLevel; //When stopping at sustain level stop here
- Bit32s totalLevel; //totalLevel is added to every generated volume
- Bit32u currentLevel; //totalLevel + tremolo
- Bit32s volume; //The currently active volume
-
- Bit32u attackAdd; //Timers for the different states of the envelope
- Bit32u decayAdd;
- Bit32u releaseAdd;
- Bit32u rateIndex; //Current position of the evenlope
-
- Bit8u rateZero; //Bits for the different states of the envelope having no changes
- Bit8u keyOn; //Bitmask of different values that can generate keyon
- //Registers, also used to check for changes
- Bit8u reg20, reg40, reg60, reg80, regE0;
- //Active part of the envelope we're in
- Bit8u state;
- //0xff when tremolo is enabled
- Bit8u tremoloMask;
- //Strength of the vibrato
- Bit8u vibStrength;
- //Keep track of the calculated KSR so we can check for changes
- Bit8u ksr;
- private:
- void SetState(Bit8u s);
- void UpdateAttack(const Chip *chip);
- void UpdateRelease(const Chip *chip);
- void UpdateDecay(const Chip *chip);
- public:
- void UpdateAttenuation();
- void UpdateRates(const Chip *chip);
- void UpdateFrequency();
-
- void Write20(const Chip *chip, Bit8u val);
- void Write40(const Chip *chip, Bit8u val);
- void Write60(const Chip *chip, Bit8u val);
- void Write80(const Chip *chip, Bit8u val);
- void WriteE0(const Chip *chip, Bit8u val);
-
- bool Silent() const;
- void Prepare(const Chip *chip);
-
- void KeyOn(Bit8u mask);
- void KeyOff(Bit8u mask);
-
- template< State state>
- Bits TemplateVolume();
-
- Bit32s RateForward(Bit32u add);
- Bitu ForwardWave();
- Bitu ForwardVolume();
-
- Bits GetSample(Bits modulation);
- Bits GetWave(Bitu index, Bitu vol);
- public:
- Operator();
- char ____padding[5];
- };
-
- struct Channel
- {
- Operator op[2];
- inline Operator *Op(Bitu index)
- {
- return &((this + (index >> 1))->op[ index & 1 ]);
- }
- SynthHandler synthHandler;
- Bit32u chanData; //Frequency/octave and derived values
- Bit32s old[2]; //Old data for feedback
-
- Bit8u feedback; //Feedback shift
- Bit8u regB0; //Register values to check for changes
- Bit8u regC0;
- //This should correspond with reg104, bit 6 indicates a Percussion channel, bit 7 indicates a silent channel
- Bit8u fourMask;
- Bit8s maskLeft; //Sign extended values for both channel's panning
- Bit8s maskRight;
-
- //Forward the channel data to the operators of the channel
- void SetChanData(const Chip *chip, Bit32u data);
- //Change in the chandata, check for new values and if we have to forward to operators
- void UpdateFrequency(const Chip *chip, Bit8u fourOp);
- void WriteA0(const Chip *chip, Bit8u val);
- void WriteB0(const Chip *chip, Bit8u val);
- void WriteC0(const Chip *chip, Bit8u val);
- void ResetC0(const Chip *chip);
-
- //call this for the first channel
- template< bool opl3Mode >
- void GeneratePercussion(Chip *chip, Bit32s *output);
-
- //Generate blocks of data in specific modes
- template<SynthMode mode>
- Channel *BlockTemplate(Chip *chip, Bit32u samples, Bit32s *output);
- Channel();
- char ____padding[6];
- };
-
- struct Chip
- {
- //This is used as the base counter for vibrato and tremolo
- Bit32u lfoCounter;
- Bit32u lfoAdd;
-
-
- Bit32u noiseCounter;
- Bit32u noiseAdd;
- Bit32u noiseValue;
-
- //Frequency scales for the different multiplications
- Bit32u freqMul[16];
- //Rates for decay and release for rate of this chip
- Bit32u linearRates[76];
- //Best match attack rates for the rate of this chip
- Bit32u attackRates[76];
-
- //18 channels with 2 operators each
- Channel chan[18];
-
- Bit8u reg104;
- Bit8u reg08;
- Bit8u reg04;
- Bit8u regBD;
- Bit8u vibratoIndex;
- Bit8u tremoloIndex;
- Bit8s vibratoSign;
- Bit8u vibratoShift;
- Bit8u tremoloValue;
- Bit8u vibratoStrength;
- Bit8u tremoloStrength;
- //Mask for allowed wave forms
- Bit8u waveFormMask;
- //0 or -1 when enabled
- Bit8s opl3Active;
-
- //Return the maximum amount of samples before and LFO change
- Bit32u ForwardLFO(Bit32u samples);
- Bit32u ForwardNoise();
-
- void WriteBD(Bit8u val);
- void WriteReg(Bit32u reg, Bit8u val);
-
- Bit32u WriteAddr(Bit32u port, Bit8u val);
-
- void GenerateBlock2(Bitu samples, Bit32s *output);
- void GenerateBlock3(Bitu samples, Bit32s *output);
-
- void GenerateBlock2_Mix(Bitu samples, Bit32s *output);
- void GenerateBlock3_Mix(Bitu samples, Bit32s *output);
-
- void Generate(Bit32u samples);
- void Setup(Bit32u r);
-
- Chip();
- };
-
- struct Handler
- {
- DBOPL::Chip chip;
- Bit32u WriteAddr(Bit32u port, Bit8u val);
- void WriteReg(Bit32u addr, Bit8u val);
- void Generate(void(*AddSamples_m32)(Bitu, Bit32s *),
- void(*AddSamples_s32)(Bitu, Bit32s *),
- Bitu samples);
- void GenerateArr(Bit32s *out, Bitu *samples);
- void GenerateArr(Bit32s *out, ssize_t *samples);
- void GenerateArr(Bit16s *out, ssize_t *samples);
- void GenerateArrMix(Bit32s *out, ssize_t *samples);
- void GenerateArrMix(Bit16s *out, ssize_t *samples);
- void Init(Bitu rate);
- };
-
-
-} //Namespace
+ Bit32u waveIndex; //WAVE_BITS shifted counter of the frequency index
+ Bit32u waveAdd; //The base frequency without vibrato
+ Bit32u waveCurrent; //waveAdd + vibratao
+
+ Bit32u chanData; //Frequency/octave and derived data coming from whatever channel controls this
+ Bit32u freqMul; //Scale channel frequency with this, TODO maybe remove?
+ Bit32u vibrato; //Scaled up vibrato strength
+ Bit32s sustainLevel; //When stopping at sustain level stop here
+ Bit32s totalLevel; //totalLevel is added to every generated volume
+ Bit32u currentLevel; //totalLevel + tremolo
+ Bit32s volume; //The currently active volume
+
+ Bit32u attackAdd; //Timers for the different states of the envelope
+ Bit32u decayAdd;
+ Bit32u releaseAdd;
+ Bit32u rateIndex; //Current position of the evenlope
+
+ Bit8u rateZero; //Bits for the different states of the envelope having no changes
+ Bit8u keyOn; //Bitmask of different values that can generate keyon
+ //Registers, also used to check for changes
+ Bit8u reg20, reg40, reg60, reg80, regE0;
+ //Active part of the envelope we're in
+ Bit8u state;
+ //0xff when tremolo is enabled
+ Bit8u tremoloMask;
+ //Strength of the vibrato
+ Bit8u vibStrength;
+ //Keep track of the calculated KSR so we can check for changes
+ Bit8u ksr;
+private:
+ void SetState( Bit8u s );
+ void UpdateAttack( const Chip* chip );
+ void UpdateRelease( const Chip* chip );
+ void UpdateDecay( const Chip* chip );
+public:
+ void UpdateAttenuation();
+ void UpdateRates( const Chip* chip );
+ void UpdateFrequency( );
+
+ void Write20( const Chip* chip, Bit8u val );
+ void Write40( const Chip* chip, Bit8u val );
+ void Write60( const Chip* chip, Bit8u val );
+ void Write80( const Chip* chip, Bit8u val );
+ void WriteE0( const Chip* chip, Bit8u val );
+
+ bool Silent() const;
+ void Prepare( const Chip* chip );
+
+ void KeyOn( Bit8u mask);
+ void KeyOff( Bit8u mask);
+
+ template< State state>
+ Bits TemplateVolume( );
+
+ Bit32s RateForward( Bit32u add );
+ Bitu ForwardWave();
+ Bitu ForwardVolume();
+
+ Bits GetSample( Bits modulation );
+ Bits GetWave( Bitu index, Bitu vol );
+public:
+ Operator();
+};
+
+struct Channel {
+ Operator op[2];
+ inline Operator* Op( Bitu index ) {
+ return &( ( this + (index >> 1) )->op[ index & 1 ]);
+ }
+ SynthHandler synthHandler;
+ Bit32u chanData; //Frequency/octave and derived values
+ Bit32s old[2]; //Old data for feedback
+
+ Bit8u feedback; //Feedback shift
+ Bit8u regB0; //Register values to check for changes
+ Bit8u regC0;
+ //This should correspond with reg104, bit 6 indicates a Percussion channel, bit 7 indicates a silent channel
+ Bit8u fourMask;
+ Bit8s maskLeft; //Sign extended values for both channel's panning
+ Bit8s maskRight;
+
+ //Forward the channel data to the operators of the channel
+ void SetChanData( const Chip* chip, Bit32u data );
+ //Change in the chandata, check for new values and if we have to forward to operators
+ void UpdateFrequency( const Chip* chip, Bit8u fourOp );
+ void UpdateSynth(const Chip* chip);
+ void WriteA0( const Chip* chip, Bit8u val );
+ void WriteB0( const Chip* chip, Bit8u val );
+ void WriteC0( const Chip* chip, Bit8u val );
+
+ //call this for the first channel
+ template< bool opl3Mode >
+ void GeneratePercussion( Chip* chip, Bit32s* output );
+
+ //Generate blocks of data in specific modes
+ template<SynthMode mode>
+ Channel* BlockTemplate( Chip* chip, Bit32u samples, Bit32s* output );
+ Channel();
+};
+
+struct Chip {
+ //This is used as the base counter for vibrato and tremolo
+ Bit32u lfoCounter;
+ Bit32u lfoAdd;
+
+
+ Bit32u noiseCounter;
+ Bit32u noiseAdd;
+ Bit32u noiseValue;
+
+ //Frequency scales for the different multiplications
+ Bit32u freqMul[16];
+ //Rates for decay and release for rate of this chip
+ Bit32u linearRates[76];
+ //Best match attack rates for the rate of this chip
+ Bit32u attackRates[76];
+
+ //18 channels with 2 operators each
+ Channel chan[18];
+
+ Bit8u reg104;
+ Bit8u reg08;
+ Bit8u reg04;
+ Bit8u regBD;
+ Bit8u vibratoIndex;
+ Bit8u tremoloIndex;
+ Bit8s vibratoSign;
+ Bit8u vibratoShift;
+ Bit8u tremoloValue;
+ Bit8u vibratoStrength;
+ Bit8u tremoloStrength;
+ //Mask for allowed wave forms
+ Bit8u waveFormMask;
+ //0 or -1 when enabled
+ Bit8s opl3Active;
+
+ //Return the maximum amount of samples before and LFO change
+ Bit32u ForwardLFO( Bit32u samples );
+ Bit32u ForwardNoise();
+
+ void WriteBD( Bit8u val );
+ void WriteReg(Bit32u reg, Bit8u val );
+
+ Bit32u WriteAddr( Bit32u port, Bit8u val );
+
+ void GenerateBlock2( Bitu samples, Bit32s* output );
+ void GenerateBlock2_Mix( Bitu samples, Bit32s* output );
+ void GenerateBlock3( Bitu samples, Bit32s* output );
+ void GenerateBlock3_Mix( Bitu samples, Bit32s* output );
+
+ //Update the synth handlers in all channels
+ void UpdateSynths();
+ void Generate( Bit32u samples );
+ void Setup( Bit32u r );
+
+ Chip();
+};
+
+struct Handler {
+ DBOPL::Chip chip;
+ Bit32u WriteAddr( Bit32u port, Bit8u val );
+ void WriteReg( Bit32u addr, Bit8u val );
+ void GenerateArr(Bit32s *out, Bitu *samples);
+ void GenerateArr(Bit16s *out, Bitu *samples);
+ void GenerateArrMix(Bit32s *out, Bitu *samples);
+ void GenerateArrMix(Bit16s *out, Bitu *samples);
+ void Init( Bitu rate );
+};
+
+
+} //Namespace
diff --git a/src/chips/dosbox_opl3.cpp b/src/chips/dosbox_opl3.cpp
index e748b85..af4cb08 100644
--- a/src/chips/dosbox_opl3.cpp
+++ b/src/chips/dosbox_opl3.cpp
@@ -1,22 +1,16 @@
#include "dosbox_opl3.h"
#include "dosbox/dbopl.h"
+#include <new>
#include <cstdlib>
#include <assert.h>
DosBoxOPL3::DosBoxOPL3() :
- OPLChipBase(),
- m_chip(NULL)
+ OPLChipBaseBufferedT(),
+ m_chip(new DBOPL::Handler)
{
reset();
}
-DosBoxOPL3::DosBoxOPL3(const DosBoxOPL3 &c) :
- OPLChipBase(c),
- m_chip(NULL)
-{
- setRate(c.m_rate);
-}
-
DosBoxOPL3::~DosBoxOPL3()
{
DBOPL::Handler *chip_r = reinterpret_cast<DBOPL::Handler*>(m_chip);
@@ -25,23 +19,20 @@ DosBoxOPL3::~DosBoxOPL3()
void DosBoxOPL3::setRate(uint32_t rate)
{
- OPLChipBase::setRate(rate);
- reset();
+ OPLChipBaseBufferedT::setRate(rate);
+ DBOPL::Handler *chip_r = reinterpret_cast<DBOPL::Handler*>(m_chip);
+ chip_r->~Handler();
+ new(chip_r) DBOPL::Handler;
+ chip_r->Init(49716);
}
void DosBoxOPL3::reset()
{
+ OPLChipBaseBufferedT::reset();
DBOPL::Handler *chip_r = reinterpret_cast<DBOPL::Handler*>(m_chip);
- if(m_chip && chip_r)
- delete chip_r;
- m_chip = new DBOPL::Handler;
- chip_r = reinterpret_cast<DBOPL::Handler*>(m_chip);
- chip_r->Init(m_rate);
-}
-
-void DosBoxOPL3::reset(uint32_t rate)
-{
- setRate(rate);
+ chip_r->~Handler();
+ new(chip_r) DBOPL::Handler;
+ chip_r->Init(49716);
}
void DosBoxOPL3::writeReg(uint16_t addr, uint8_t data)
@@ -50,63 +41,14 @@ void DosBoxOPL3::writeReg(uint16_t addr, uint8_t data)
chip_r->WriteReg(static_cast<Bit32u>(addr), data);
}
-int DosBoxOPL3::generate(int16_t *output, size_t frames)
-{
- DBOPL::Handler *chip_r = reinterpret_cast<DBOPL::Handler*>(m_chip);
- ssize_t left = (ssize_t)frames;
- while(left > 0)
- {
- ssize_t frames_i = left;
- chip_r->GenerateArr(output, &frames_i);
- output += (frames_i * 2);
- left -= frames_i;
- }
- return (int)frames;
-}
-
-int DosBoxOPL3::generateAndMix(int16_t *output, size_t frames)
-{
- DBOPL::Handler *chip_r = reinterpret_cast<DBOPL::Handler*>(m_chip);
- ssize_t left = (ssize_t)frames;
- while(left > 0)
- {
- ssize_t frames_i = left;
- chip_r->GenerateArrMix(output, &frames_i);
- output += (frames_i * 2);
- left -= frames_i;
- }
- return (int)frames;
-}
-
-int DosBoxOPL3::generate32(int32_t *output, size_t frames)
-{
- DBOPL::Handler *chip_r = reinterpret_cast<DBOPL::Handler*>(m_chip);
- ssize_t left = (ssize_t)frames;
- while(left > 0)
- {
- ssize_t frames_i = left;
- chip_r->GenerateArr(output, &frames_i);
- output += (frames_i * 2);
- left -= frames_i;
- }
- return (int)frames;
-}
-
-int DosBoxOPL3::generateAndMix32(int32_t *output, size_t frames)
+void DosBoxOPL3::nativeGenerateN(int16_t *output, size_t frames)
{
DBOPL::Handler *chip_r = reinterpret_cast<DBOPL::Handler*>(m_chip);
- ssize_t left = (ssize_t)frames;
- while(left > 0)
- {
- ssize_t frames_i = left;
- chip_r->GenerateArrMix(output, &frames_i);
- output += (frames_i * 2);
- left -= frames_i;
- }
- return (int)frames;
+ Bitu frames_i = frames;
+ chip_r->GenerateArr(output, &frames_i);
}
const char *DosBoxOPL3::emulatorName()
{
- return "DosBox 0.74 OPL3";
+ return "DosBox 0.74-r4111 OPL3";
}
diff --git a/src/chips/dosbox_opl3.h b/src/chips/dosbox_opl3.h
index 422e2d1..f4c68da 100644
--- a/src/chips/dosbox_opl3.h
+++ b/src/chips/dosbox_opl3.h
@@ -3,23 +3,20 @@
#include "opl_chip_base.h"
-class DosBoxOPL3 final : public OPLChipBase
+class DosBoxOPL3 final : public OPLChipBaseBufferedT<DosBoxOPL3>
{
void *m_chip;
public:
DosBoxOPL3();
- DosBoxOPL3(const DosBoxOPL3 &c);
- virtual ~DosBoxOPL3() override;
+ ~DosBoxOPL3() override;
- virtual void setRate(uint32_t rate) override;
- virtual void reset() override;
- virtual void reset(uint32_t rate) override;
- virtual void writeReg(uint16_t addr, uint8_t data) override;
- virtual int generate(int16_t *output, size_t frames) override;
- virtual int generateAndMix(int16_t *output, size_t frames) override;
- virtual int generate32(int32_t *output, size_t frames) override;
- virtual int generateAndMix32(int32_t *output, size_t frames) override;
- virtual const char *emulatorName() override;
+ void setRate(uint32_t rate) override;
+ void reset() override;
+ void writeReg(uint16_t addr, uint8_t data) override;
+ void nativePreGenerate() override {}
+ void nativePostGenerate() override {}
+ void nativeGenerateN(int16_t *output, size_t frames) override;
+ const char *emulatorName() override;
};
#endif // DOSBOX_OPL3_H
diff --git a/src/chips/nuked/nukedopl3.c b/src/chips/nuked/nukedopl3.c
index eadb6b9..87d3212 100644
--- a/src/chips/nuked/nukedopl3.c
+++ b/src/chips/nuked/nukedopl3.c
@@ -697,18 +697,18 @@ static void OPL3_ChannelUpdateRhythm(opl3_chip *chip, Bit8u data)
channel6 = &chip->channel[6];
channel7 = &chip->channel[7];
channel8 = &chip->channel[8];
- channel6->out[0] = &channel6->slots[1]->out;
- channel6->out[1] = &channel6->slots[1]->out;
+ channel6->out[0] = &channel6->slotz[1]->out;
+ channel6->out[1] = &channel6->slotz[1]->out;
channel6->out[2] = &chip->zeromod;
channel6->out[3] = &chip->zeromod;
- channel7->out[0] = &channel7->slots[0]->out;
- channel7->out[1] = &channel7->slots[0]->out;
- channel7->out[2] = &channel7->slots[1]->out;
- channel7->out[3] = &channel7->slots[1]->out;
- channel8->out[0] = &channel8->slots[0]->out;
- channel8->out[1] = &channel8->slots[0]->out;
- channel8->out[2] = &channel8->slots[1]->out;
- channel8->out[3] = &channel8->slots[1]->out;
+ channel7->out[0] = &channel7->slotz[0]->out;
+ channel7->out[1] = &channel7->slotz[0]->out;
+ channel7->out[2] = &channel7->slotz[1]->out;
+ channel7->out[3] = &channel7->slotz[1]->out;
+ channel8->out[0] = &channel8->slotz[0]->out;
+ channel8->out[1] = &channel8->slotz[0]->out;
+ channel8->out[2] = &channel8->slotz[1]->out;
+ channel8->out[3] = &channel8->slotz[1]->out;
for (chnum = 6; chnum < 9; chnum++)
{
chip->channel[chnum].chtype = ch_drum;
@@ -719,49 +719,49 @@ static void OPL3_ChannelUpdateRhythm(opl3_chip *chip, Bit8u data)
/* hh */
if (chip->rhy & 0x01)
{
- OPL3_EnvelopeKeyOn(channel7->slots[0], egk_drum);
+ OPL3_EnvelopeKeyOn(channel7->slotz[0], egk_drum);
}
else
{
- OPL3_EnvelopeKeyOff(channel7->slots[0], egk_drum);
+ OPL3_EnvelopeKeyOff(channel7->slotz[0], egk_drum);
}
/* tc */
if (chip->rhy & 0x02)
{
- OPL3_EnvelopeKeyOn(channel8->slots[1], egk_drum);
+ OPL3_EnvelopeKeyOn(channel8->slotz[1], egk_drum);
}
else
{
- OPL3_EnvelopeKeyOff(channel8->slots[1], egk_drum);
+ OPL3_EnvelopeKeyOff(channel8->slotz[1], egk_drum);
}
/* tom */
if (chip->rhy & 0x04)
{
- OPL3_EnvelopeKeyOn(channel8->slots[0], egk_drum);
+ OPL3_EnvelopeKeyOn(channel8->slotz[0], egk_drum);
}
else
{
- OPL3_EnvelopeKeyOff(channel8->slots[0], egk_drum);
+ OPL3_EnvelopeKeyOff(channel8->slotz[0], egk_drum);
}
/* sd */
if (chip->rhy & 0x08)
{
- OPL3_EnvelopeKeyOn(channel7->slots[1], egk_drum);
+ OPL3_EnvelopeKeyOn(channel7->slotz[1], egk_drum);
}
else
{
- OPL3_EnvelopeKeyOff(channel7->slots[1], egk_drum);
+ OPL3_EnvelopeKeyOff(channel7->slotz[1], egk_drum);
}
/* bd */
if (chip->rhy & 0x10)
{
- OPL3_EnvelopeKeyOn(channel6->slots[0], egk_drum);
- OPL3_EnvelopeKeyOn(channel6->slots[1], egk_drum);
+ OPL3_EnvelopeKeyOn(channel6->slotz[0], egk_drum);
+ OPL3_EnvelopeKeyOn(channel6->slotz[1], egk_drum);
}
else
{
- OPL3_EnvelopeKeyOff(channel6->slots[0], egk_drum);
- OPL3_EnvelopeKeyOff(channel6->slots[1], egk_drum);
+ OPL3_EnvelopeKeyOff(channel6->slotz[0], egk_drum);
+ OPL3_EnvelopeKeyOff(channel6->slotz[1], egk_drum);
}
}
else
@@ -770,8 +770,8 @@ static void OPL3_ChannelUpdateRhythm(opl3_chip *chip, Bit8u data)
{
chip->channel[chnum].chtype = ch_2op;
OPL3_ChannelSetupAlg(&chip->channel[chnum]);
- OPL3_EnvelopeKeyOff(chip->channel[chnum].slots[0], egk_drum);
- OPL3_EnvelopeKeyOff(chip->channel[chnum].slots[1], egk_drum);
+ OPL3_EnvelopeKeyOff(chip->channel[chnum].slotz[0], egk_drum);
+ OPL3_EnvelopeKeyOff(chip->channel[chnum].slotz[1], egk_drum);
}
}
}
@@ -785,14 +785,14 @@ static void OPL3_ChannelWriteA0(opl3_channel *channel, Bit8u data)
channel->f_num = (channel->f_num & 0x300) | data;
channel->ksv = (channel->block << 1)
| ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01);
- OPL3_EnvelopeUpdateKSL(channel->slots[0]);
- OPL3_EnvelopeUpdateKSL(channel->slots[1]);
+ OPL3_EnvelopeUpdateKSL(channel->slotz[0]);
+ OPL3_EnvelopeUpdateKSL(channel->slotz[1]);
if (channel->chip->newm && channel->chtype == ch_4op)
{
channel->pair->f_num = channel->f_num;
channel->pair->ksv = channel->ksv;
- OPL3_EnvelopeUpdateKSL(channel->pair->slots[0]);
- OPL3_EnvelopeUpdateKSL(channel->pair->slots[1]);
+ OPL3_EnvelopeUpdateKSL(channel->pair->slotz[0]);
+ OPL3_EnvelopeUpdateKSL(channel->pair->slotz[1]);
}
}
@@ -806,15 +806,15 @@ static void OPL3_ChannelWriteB0(opl3_channel *channel, Bit8u data)
channel->block = (data >> 2) & 0x07;
channel->ksv = (channel->block << 1)
| ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01);
- OPL3_EnvelopeUpdateKSL(channel->slots[0]);
- OPL3_EnvelopeUpdateKSL(channel->slots[1]);
+ OPL3_EnvelopeUpdateKSL(channel->slotz[0]);
+ OPL3_EnvelopeUpdateKSL(channel->slotz[1]);
if (channel->chip->newm && channel->chtype == ch_4op)
{
channel->pair->f_num = channel->f_num;
channel->pair->block = channel->block;
channel->pair->ksv = channel->ksv;
- OPL3_EnvelopeUpdateKSL(channel->pair->slots[0]);
- OPL3_EnvelopeUpdateKSL(channel->pair->slots[1]);
+ OPL3_EnvelopeUpdateKSL(channel->pair->slotz[0]);
+ OPL3_EnvelopeUpdateKSL(channel->pair->slotz[1]);
}
}
@@ -824,19 +824,19 @@ static void OPL3_ChannelSetupAlg(opl3_channel *channel)
{
if (channel->ch_num == 7 || channel->ch_num == 8)
{
- channel->slots[0]->mod = &channel->chip->zeromod;
- channel->slots[1]->mod = &channel->chip->zeromod;
+ channel->slotz[0]->mod = &channel->chip->zeromod;
+ channel->slotz[1]->mod = &channel->chip->zeromod;
return;
}
switch (channel->alg & 0x01)
{
case 0x00:
- channel->slots[0]->mod = &channel->slots[0]->fbmod;
- channel->slots[1]->mod = &channel->slots[0]->out;
+ channel->slotz[0]->mod = &channel->slotz[0]->fbmod;
+ channel->slotz[1]->mod = &channel->slotz[0]->out;
break;
case 0x01:
- channel->slots[0]->mod = &channel->slots[0]->fbmod;
- channel->slots[1]->mod = &channel->chip->zeromod;
+ channel->slotz[0]->mod = &channel->slotz[0]->fbmod;
+ channel->slotz[1]->mod = &channel->chip->zeromod;
break;
}
return;
@@ -854,43 +854,43 @@ static void OPL3_ChannelSetupAlg(opl3_channel *channel)
switch (channel->alg & 0x03)
{
case 0x00:
- channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod;
- channel->pair->slots[1]->mod = &channel->pair->slots[0]->out;
- channel->slots[0]->mod = &channel->pair->slots[1]->out;
- channel->slots[1]->mod = &channel->slots[0]->out;
- channel->out[0] = &channel->slots[1]->out;
+ channel->pair->slotz[0]->mod = &channel->pair->slotz[0]->fbmod;
+ channel->pair->slotz[1]->mod = &channel->pair->slotz[0]->out;
+ channel->slotz[0]->mod = &channel->pair->slotz[1]->out;
+ channel->slotz[1]->mod = &channel->slotz[0]->out;
+ channel->out[0] = &channel->slotz[1]->out;
channel->out[1] = &channel->chip->zeromod;
channel->out[2] = &channel->chip->zeromod;
channel->out[3] = &channel->chip->zeromod;
break;
case 0x01:
- channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod;
- channel->pair->slots[1]->mod = &channel->pair->slots[0]->out;
- channel->slots[0]->mod = &channel->chip->zeromod;
- channel->slots[1]->mod = &channel->slots[0]->out;
- channel->out[0] = &channel->pair->slots[1]->out;
- channel->out[1] = &channel->slots[1]->out;
+ channel->pair->slotz[0]->mod = &channel->pair->slotz[0]->fbmod;
+ channel->pair->slotz[1]->mod = &channel->pair->slotz[0]->out;
+ channel->slotz[0]->mod = &channel->chip->zeromod;
+ channel->slotz[1]->mod = &channel->slotz[0]->out;
+ channel->out[0] = &channel->pair->slotz[1]->out;
+ channel->out[1] = &channel->slotz[1]->out;
channel->out[2] = &channel->chip->zeromod;
channel->out[3] = &channel->chip->zeromod;
break;
case 0x02:
- channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod;
- channel->pair->slots[1]->mod = &channel->chip->zeromod;
- channel->slots[0]->mod = &channel->pair->slots[1]->out;
- channel->slots[1]->mod = &channel->slots[0]->out;
- channel->out[0] = &channel->pair->slots[0]->out;
- channel->out[1] = &channel->slots[1]->out;
+ channel->pair->slotz[0]->mod = &channel->pair->slotz[0]->fbmod;
+ channel->pair->slotz[1]->mod = &channel->chip->zeromod;
+ channel->slotz[0]->mod = &channel->pair->slotz[1]->out;
+ channel->slotz[1]->mod = &channel->slotz[0]->out;
+ channel->out[0] = &channel->pair->slotz[0]->out;
+ channel->out[1] = &channel->slotz[1]->out;
channel->out[2] = &channel->chip->zeromod;
channel->out[3] = &channel->chip->zeromod;
break;
case 0x03:
- channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod;
- channel->pair->slots[1]->mod = &channel->chip->zeromod;
- channel->slots[0]->mod = &channel->pair->slots[1]->out;
- channel->slots[1]->mod = &channel->chip->zeromod;
- channel->out[0] = &channel->pair->slots[0]->out;
- channel->out[1] = &channel->slots[0]->out;
- channel->out[2] = &channel->slots[1]->out;
+ channel->pair->slotz[0]->mod = &channel->pair->slotz[0]->fbmod;
+ channel->pair->slotz[1]->mod = &channel->chip->zeromod;
+ channel->slotz[0]->mod = &channel->pair->slotz[1]->out;
+ channel->slotz[1]->mod = &channel->chip->zeromod;
+ channel->out[0] = &channel->pair->slotz[0]->out;
+ channel->out[1] = &channel->slotz[0]->out;
+ channel->out[2] = &channel->slotz[1]->out;
channel->out[3] = &channel->chip->zeromod;
break;
}
@@ -900,18 +900,18 @@ static void OPL3_ChannelSetupAlg(opl3_channel *channel)
switch (channel->alg & 0x01)
{
case 0x00:
- channel->slots[0]->mod = &channel->slots[0]->fbmod;
- channel->slots[1]->mod = &channel->slots[0]->out;
- channel->out[0] = &channel->slots[1]->out;
+ channel->slotz[0]->mod = &channel->slotz[0]->fbmod;
+ channel->slotz[1]->mod = &channel->slotz[0]->out;
+ channel->out[0] = &channel->slotz[1]->out;
channel->out[1] = &channel->chip->zeromod;
channel->out[2] = &channel->chip->zeromod;
channel->out[3] = &channel->chip->zeromod;
break;
case 0x01:
- channel->slots[0]->mod = &channel->slots[0]->fbmod;
- channel->slots[1]->mod = &channel->chip->zeromod;
- channel->out[0] = &channel->slots[0]->out;
- channel->out[1] = &channel->slots[1]->out;
+ channel->slotz[0]->mod = &channel->slotz[0]->fbmod;
+ channel->slotz[1]->mod = &channel->chip->zeromod;
+ channel->out[0] = &channel->slotz[0]->out;
+ channel->out[1] = &channel->slotz[1]->out;
channel->out[2] = &channel->chip->zeromod;
channel->out[3] = &channel->chip->zeromod;
break;
@@ -964,21 +964,21 @@ static void OPL3_ChannelKeyOn(opl3_channel *channel)
{
if (channel->chtype == ch_4op)
{
- OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm);
- OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm);
- OPL3_EnvelopeKeyOn(channel->pair->slots[0], egk_norm);
- OPL3_EnvelopeKeyOn(channel->pair->slots[1], egk_norm);
+ OPL3_EnvelopeKeyOn(channel->slotz[0], egk_norm);
+ OPL3_EnvelopeKeyOn(channel->slotz[1], egk_norm);
+ OPL3_EnvelopeKeyOn(channel->pair->slotz[0], egk_norm);
+ OPL3_EnvelopeKeyOn(channel->pair->slotz[1], egk_norm);
}
else if (channel->chtype == ch_2op || channel->chtype == ch_drum)
{
- OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm);
- OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm);
+ OPL3_EnvelopeKeyOn(channel->slotz[0], egk_norm);
+ OPL3_EnvelopeKeyOn(channel->slotz[1], egk_norm);
}
}
else
{
- OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm);
- OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm);
+ OPL3_EnvelopeKeyOn(channel->slotz[0], egk_norm);
+ OPL3_EnvelopeKeyOn(channel->slotz[1], egk_norm);
}
}
@@ -988,21 +988,21 @@ static void OPL3_ChannelKeyOff(opl3_channel *channel)
{
if (channel->chtype == ch_4op)
{
- OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm);
- OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm);
- OPL3_EnvelopeKeyOff(channel->pair->slots[0], egk_norm);
- OPL3_EnvelopeKeyOff(channel->pair->slots[1], egk_norm);
+ OPL3_EnvelopeKeyOff(channel->slotz[0], egk_norm);
+ OPL3_EnvelopeKeyOff(channel->slotz[1], egk_norm);
+ OPL3_EnvelopeKeyOff(channel->pair->slotz[0], egk_norm);
+ OPL3_EnvelopeKeyOff(channel->pair->slotz[1], egk_norm);
}
else if (channel->chtype == ch_2op || channel->chtype == ch_drum)
{
- OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm);
- OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm);
+ OPL3_EnvelopeKeyOff(channel->slotz[0], egk_norm);
+ OPL3_EnvelopeKeyOff(channel->slotz[1], egk_norm);
}
}
else
{
- OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm);
- OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm);
+ OPL3_EnvelopeKeyOff(channel->slotz[0], egk_norm);
+ OPL3_EnvelopeKeyOff(channel->slotz[1], egk_norm);
}
}
@@ -1147,7 +1147,7 @@ void OPL3_Generate(opl3_chip *chip, Bit16s *buf)
if (chip->eg_timerrem || chip->eg_state)
{
- if (chip->eg_timer == 0xfffffffff)
+ if (chip->eg_timer == (uint64_t)0xfffffffffU)
{
chip->eg_timer = 0;
chip->eg_timerrem = 1;
@@ -1209,8 +1209,8 @@ void OPL3_Reset(opl3_chip *chip, Bit32u samplerate)
}
for (channum = 0; channum < 18; channum++)
{
- chip->channel[channum].slots[0] = &chip->slot[ch_slot[channum]];
- chip->channel[channum].slots[1] = &chip->slot[ch_slot[channum] + 3];
+ chip->channel[channum].slotz[0] = &chip->slot[ch_slot[channum]];
+ chip->channel[channum].slotz[1] = &chip->slot[ch_slot[channum] + 3];
chip->slot[ch_slot[channum]].channel = &chip->channel[channum];
chip->slot[ch_slot[channum] + 3].channel = &chip->channel[channum];
if ((channum % 9) < 3)
diff --git a/src/chips/nuked/nukedopl3.h b/src/chips/nuked/nukedopl3.h
index ce748b1..d57cf5f 100644
--- a/src/chips/nuked/nukedopl3.h
+++ b/src/chips/nuked/nukedopl3.h
@@ -86,7 +86,7 @@ struct _opl3_slot {
};
struct _opl3_channel {
- opl3_slot *slots[2];
+ opl3_slot *slotz[2];/*Don't use "slots" keyword to avoid conflict with Qt applications*/
opl3_channel *pair;
opl3_chip *chip;
Bit16s *out[4];
diff --git a/src/chips/nuked/nukedopl3_174.c b/src/chips/nuked/nukedopl3_174.c
index 401089c..99eab16 100644
--- a/src/chips/nuked/nukedopl3_174.c
+++ b/src/chips/nuked/nukedopl3_174.c
@@ -638,18 +638,18 @@ static void OPL3_ChannelUpdateRhythm(opl3_chip *chip, Bit8u data)
channel6 = &chip->channel[6];
channel7 = &chip->channel[7];
channel8 = &chip->channel[8];
- channel6->out[0] = &channel6->slots[1]->out;
- channel6->out[1] = &channel6->slots[1]->out;
+ channel6->out[0] = &channel6->slotz[1]->out;
+ channel6->out[1] = &channel6->slotz[1]->out;
channel6->out[2] = &chip->zeromod;
channel6->out[3] = &chip->zeromod;
- channel7->out[0] = &channel7->slots[0]->out;
- channel7->out[1] = &channel7->slots[0]->out;
- channel7->out[2] = &channel7->slots[1]->out;
- channel7->out[3] = &channel7->slots[1]->out;
- channel8->out[0] = &channel8->slots[0]->out;
- channel8->out[1] = &channel8->slots[0]->out;
- channel8->out[2] = &channel8->slots[1]->out;
- channel8->out[3] = &channel8->slots[1]->out;
+ channel7->out[0] = &channel7->slotz[0]->out;
+ channel7->out[1] = &channel7->slotz[0]->out;
+ channel7->out[2] = &channel7->slotz[1]->out;
+ channel7->out[3] = &channel7->slotz[1]->out;
+ channel8->out[0] = &channel8->slotz[0]->out;
+ channel8->out[1] = &channel8->slotz[0]->out;
+ channel8->out[2] = &channel8->slotz[1]->out;
+ channel8->out[3] = &channel8->slotz[1]->out;
for (chnum = 6; chnum < 9; chnum++)
{
chip->channel[chnum].chtype = ch_drum;
@@ -658,49 +658,49 @@ static void OPL3_ChannelUpdateRhythm(opl3_chip *chip, Bit8u data)
/*hh*/
if (chip->rhy & 0x01)
{
- OPL3_EnvelopeKeyOn(channel7->slots[0], egk_drum);
+ OPL3_EnvelopeKeyOn(channel7->slotz[0], egk_drum);
}
else
{
- OPL3_EnvelopeKeyOff(channel7->slots[0], egk_drum);
+ OPL3_EnvelopeKeyOff(channel7->slotz[0], egk_drum);
}
/*tc*/
if (chip->rhy & 0x02)
{
- OPL3_EnvelopeKeyOn(channel8->slots[1], egk_drum);
+ OPL3_EnvelopeKeyOn(channel8->slotz[1], egk_drum);
}
else
{
- OPL3_EnvelopeKeyOff(channel8->slots[1], egk_drum);
+ OPL3_EnvelopeKeyOff(channel8->slotz[1], egk_drum);
}
/*tom*/
if (chip->rhy & 0x04)
{
- OPL3_EnvelopeKeyOn(channel8->slots[0], egk_drum);
+ OPL3_EnvelopeKeyOn(channel8->slotz[0], egk_drum);
}
else
{
- OPL3_EnvelopeKeyOff(channel8->slots[0], egk_drum);
+ OPL3_EnvelopeKeyOff(channel8->slotz[0], egk_drum);
}
/*sd*/
if (chip->rhy & 0x08)
{
- OPL3_EnvelopeKeyOn(channel7->slots[1], egk_drum);
+ OPL3_EnvelopeKeyOn(channel7->slotz[1], egk_drum);
}
else
{
- OPL3_EnvelopeKeyOff(channel7->slots[1], egk_drum);
+ OPL3_EnvelopeKeyOff(channel7->slotz[1], egk_drum);
}
/*bd*/
if (chip->rhy & 0x10)
{
- OPL3_EnvelopeKeyOn(channel6->slots[0], egk_drum);
- OPL3_EnvelopeKeyOn(channel6->slots[1], egk_drum);
+ OPL3_EnvelopeKeyOn(channel6->slotz[0], egk_drum);
+ OPL3_EnvelopeKeyOn(channel6->slotz[1], egk_drum);
}
else
{
- OPL3_EnvelopeKeyOff(channel6->slots[0], egk_drum);
- OPL3_EnvelopeKeyOff(channel6->slots[1], egk_drum);
+ OPL3_EnvelopeKeyOff(channel6->slotz[0], egk_drum);
+ OPL3_EnvelopeKeyOff(channel6->slotz[1], egk_drum);
}
}
else
@@ -709,8 +709,8 @@ static void OPL3_ChannelUpdateRhythm(opl3_chip *chip, Bit8u data)
{
chip->channel[chnum].chtype = ch_2op;
OPL3_ChannelSetupAlg(&chip->channel[chnum]);
- OPL3_EnvelopeKeyOff(chip->channel[chnum].slots[0], egk_drum);
- OPL3_EnvelopeKeyOff(chip->channel[chnum].slots[1], egk_drum);
+ OPL3_EnvelopeKeyOff(chip->channel[chnum].slotz[0], egk_drum);
+ OPL3_EnvelopeKeyOff(chip->channel[chnum].slotz[1], egk_drum);
}
}
}
@@ -724,18 +724,18 @@ static void OPL3_ChannelWriteA0(opl3_channel *channel, Bit8u data)
channel->f_num = (channel->f_num & 0x300) | data;
channel->ksv = (channel->block << 1)
| ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01);
- OPL3_EnvelopeUpdateKSL(channel->slots[0]);
- OPL3_EnvelopeUpdateKSL(channel->slots[1]);
- OPL3_EnvelopeUpdateRate(channel->slots[0]);
- OPL3_EnvelopeUpdateRate(channel->slots[1]);
+ OPL3_EnvelopeUpdateKSL(channel->slotz[0]);
+ OPL3_EnvelopeUpdateKSL(channel->slotz[1]);
+ OPL3_EnvelopeUpdateRate(channel->slotz[0]);
+ OPL3_EnvelopeUpdateRate(channel->slotz[1]);
if (channel->chip->newm && channel->chtype == ch_4op)
{
channel->pair->f_num = channel->f_num;
channel->pair->ksv = channel->ksv;
- OPL3_EnvelopeUpdateKSL(channel->pair->slots[0]);
- OPL3_EnvelopeUpdateKSL(channel->pair->slots[1]);
- OPL3_EnvelopeUpdateRate(channel->pair->slots[0]);
- OPL3_EnvelopeUpdateRate(channel->pair->slots[1]);
+ OPL3_EnvelopeUpdateKSL(channel->pair->slotz[0]);
+ OPL3_EnvelopeUpdateKSL(channel->pair->slotz[1]);
+ OPL3_EnvelopeUpdateRate(channel->pair->slotz[0]);
+ OPL3_EnvelopeUpdateRate(channel->pair->slotz[1]);
}
}
@@ -749,19 +749,19 @@ static void OPL3_ChannelWriteB0(opl3_channel *channel, Bit8u data)
channel->block = (data >> 2) & 0x07;
channel->ksv = (channel->block << 1)
| ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01);
- OPL3_EnvelopeUpdateKSL(channel->slots[0]);
- OPL3_EnvelopeUpdateKSL(channel->slots[1]);
- OPL3_EnvelopeUpdateRate(channel->slots[0]);
- OPL3_EnvelopeUpdateRate(channel->slots[1]);
+ OPL3_EnvelopeUpdateKSL(channel->slotz[0]);
+ OPL3_EnvelopeUpdateKSL(channel->slotz[1]);
+ OPL3_EnvelopeUpdateRate(channel->slotz[0]);
+ OPL3_EnvelopeUpdateRate(channel->slotz[1]);
if (channel->chip->newm && channel->chtype == ch_4op)
{
channel->pair->f_num = channel->f_num;
channel->pair->block = channel->block;
channel->pair->ksv = channel->ksv;
- OPL3_EnvelopeUpdateKSL(channel->pair->slots[0]);
- OPL3_EnvelopeUpdateKSL(channel->pair->slots[1]);
- OPL3_EnvelopeUpdateRate(channel->pair->slots[0]);
- OPL3_EnvelopeUpdateRate(channel->pair->slots[1]);
+ OPL3_EnvelopeUpdateKSL(channel->pair->slotz[0]);
+ OPL3_EnvelopeUpdateKSL(channel->pair->slotz[1]);
+ OPL3_EnvelopeUpdateRate(channel->pair->slotz[0]);
+ OPL3_EnvelopeUpdateRate(channel->pair->slotz[1]);
}
}
@@ -772,12 +772,12 @@ static void OPL3_ChannelSetupAlg(opl3_channel *channel)
switch (channel->alg & 0x01)
{
case 0x00:
- channel->slots[0]->mod = &channel->slots[0]->fbmod;
- channel->slots[1]->mod = &channel->slots[0]->out;
+ channel->slotz[0]->mod = &channel->slotz[0]->fbmod;
+ channel->slotz[1]->mod = &channel->slotz[0]->out;
break;
case 0x01:
- channel->slots[0]->mod = &channel->slots[0]->fbmod;
- channel->slots[1]->mod = &channel->chip->zeromod;
+ channel->slotz[0]->mod = &channel->slotz[0]->fbmod;
+ channel->slotz[1]->mod = &channel->chip->zeromod;
break;
}
return;
@@ -795,43 +795,43 @@ static void OPL3_ChannelSetupAlg(opl3_channel *channel)
switch (channel->alg & 0x03)
{
case 0x00:
- channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod;
- channel->pair->slots[1]->mod = &channel->pair->slots[0]->out;
- channel->slots[0]->mod = &channel->pair->slots[1]->out;
- channel->slots[1]->mod = &channel->slots[0]->out;
- channel->out[0] = &channel->slots[1]->out;
+ channel->pair->slotz[0]->mod = &channel->pair->slotz[0]->fbmod;
+ channel->pair->slotz[1]->mod = &channel->pair->slotz[0]->out;
+ channel->slotz[0]->mod = &channel->pair->slotz[1]->out;
+ channel->slotz[1]->mod = &channel->slotz[0]->out;
+ channel->out[0] = &channel->slotz[1]->out;
channel->out[1] = &channel->chip->zeromod;
channel->out[2] = &channel->chip->zeromod;
channel->out[3] = &channel->chip->zeromod;
break;
case 0x01:
- channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod;
- channel->pair->slots[1]->mod = &channel->pair->slots[0]->out;
- channel->slots[0]->mod = &channel->chip->zeromod;
- channel->slots[1]->mod = &channel->slots[0]->out;
- channel->out[0] = &channel->pair->slots[1]->out;
- channel->out[1] = &channel->slots[1]->out;
+ channel->pair->slotz[0]->mod = &channel->pair->slotz[0]->fbmod;
+ channel->pair->slotz[1]->mod = &channel->pair->slotz[0]->out;
+ channel->slotz[0]->mod = &channel->chip->zeromod;
+ channel->slotz[1]->mod = &channel->slotz[0]->out;
+ channel->out[0] = &channel->pair->slotz[1]->out;
+ channel->out[1] = &channel->slotz[1]->out;
channel->out[2] = &channel->chip->zeromod;
channel->out[3] = &channel->chip->zeromod;
break;
case 0x02:
- channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod;
- channel->pair->slots[1]->mod = &channel->chip->zeromod;
- channel->slots[0]->mod = &channel->pair->slots[1]->out;
- channel->slots[1]->mod = &channel->slots[0]->out;
- channel->out[0] = &channel->pair->slots[0]->out;
- channel->out[1] = &channel->slots[1]->out;
+ channel->pair->slotz[0]->mod = &channel->pair->slotz[0]->fbmod;
+ channel->pair->slotz[1]->mod = &channel->chip->zeromod;
+ channel->slotz[0]->mod = &channel->pair->slotz[1]->out;
+ channel->slotz[1]->mod = &channel->slotz[0]->out;
+ channel->out[0] = &channel->pair->slotz[0]->out;
+ channel->out[1] = &channel->slotz[1]->out;
channel->out[2] = &channel->chip->zeromod;
channel->out[3] = &channel->chip->zeromod;
break;
case 0x03:
- channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod;
- channel->pair->slots[1]->mod = &channel->chip->zeromod;
- channel->slots[0]->mod = &channel->pair->slots[1]->out;
- channel->slots[1]->mod = &channel->chip->zeromod;
- channel->out[0] = &channel->pair->slots[0]->out;
- channel->out[1] = &channel->slots[0]->out;
- channel->out[2] = &channel->slots[1]->out;
+ channel->pair->slotz[0]->mod = &channel->pair->slotz[0]->fbmod;
+ channel->pair->slotz[1]->mod = &channel->chip->zeromod;
+ channel->slotz[0]->mod = &channel->pair->slotz[1]->out;
+ channel->slotz[1]->mod = &channel->chip->zeromod;
+ channel->out[0] = &channel->pair->slotz[0]->out;
+ channel->out[1] = &channel->slotz[0]->out;
+ channel->out[2] = &channel->slotz[1]->out;
channel->out[3] = &channel->chip->zeromod;
break;
}
@@ -841,18 +841,18 @@ static void OPL3_ChannelSetupAlg(opl3_channel *channel)
switch (channel->alg & 0x01)
{
case 0x00:
- channel->slots[0]->mod = &channel->slots[0]->fbmod;
- channel->slots[1]->mod = &channel->slots[0]->out;
- channel->out[0] = &channel->slots[1]->out;
+ channel->slotz[0]->mod = &channel->slotz[0]->fbmod;
+ channel->slotz[1]->mod = &channel->slotz[0]->out;
+ channel->out[0] = &channel->slotz[1]->out;
channel->out[1] = &channel->chip->zeromod;
channel->out[2] = &channel->chip->zeromod;
channel->out[3] = &channel->chip->zeromod;
break;
case 0x01:
- channel->slots[0]->mod = &channel->slots[0]->fbmod;
- channel->slots[1]->mod = &channel->chip->zeromod;
- channel->out[0] = &channel->slots[0]->out;
- channel->out[1] = &channel->slots[1]->out;
+ channel->slotz[0]->mod = &channel->slotz[0]->fbmod;
+ channel->slotz[1]->mod = &channel->chip->zeromod;
+ channel->out[0] = &channel->slotz[0]->out;
+ channel->out[1] = &channel->slotz[1]->out;
channel->out[2] = &channel->chip->zeromod;
channel->out[3] = &channel->chip->zeromod;
break;
@@ -905,21 +905,21 @@ static void OPL3_ChannelKeyOn(opl3_channel *channel)
{
if (channel->chtype == ch_4op)
{
- OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm);
- OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm);
- OPL3_EnvelopeKeyOn(channel->pair->slots[0], egk_norm);
- OPL3_EnvelopeKeyOn(channel->pair->slots[1], egk_norm);
+ OPL3_EnvelopeKeyOn(channel->slotz[0], egk_norm);
+ OPL3_EnvelopeKeyOn(channel->slotz[1], egk_norm);
+ OPL3_EnvelopeKeyOn(channel->pair->slotz[0], egk_norm);
+ OPL3_EnvelopeKeyOn(channel->pair->slotz[1], egk_norm);
}
else if (channel->chtype == ch_2op || channel->chtype == ch_drum)
{
- OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm);
- OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm);
+ OPL3_EnvelopeKeyOn(channel->slotz[0], egk_norm);
+ OPL3_EnvelopeKeyOn(channel->slotz[1], egk_norm);
}
}
else
{
- OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm);
- OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm);
+ OPL3_EnvelopeKeyOn(channel->slotz[0], egk_norm);
+ OPL3_EnvelopeKeyOn(channel->slotz[1], egk_norm);
}
}
@@ -929,21 +929,21 @@ static void OPL3_ChannelKeyOff(opl3_channel *channel)
{
if (channel->chtype == ch_4op)
{
- OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm);
- OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm);
- OPL3_EnvelopeKeyOff(channel->pair->slots[0], egk_norm);
- OPL3_EnvelopeKeyOff(channel->pair->slots[1], egk_norm);
+ OPL3_EnvelopeKeyOff(channel->slotz[0], egk_norm);
+ OPL3_EnvelopeKeyOff(channel->slotz[1], egk_norm);
+ OPL3_EnvelopeKeyOff(channel->pair->slotz[0], egk_norm);
+ OPL3_EnvelopeKeyOff(channel->pair->slotz[1], egk_norm);
}
else if (channel->chtype == ch_2op || channel->chtype == ch_drum)
{
- OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm);
- OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm);
+ OPL3_EnvelopeKeyOff(channel->slotz[0], egk_norm);
+ OPL3_EnvelopeKeyOff(channel->slotz[1], egk_norm);
}
}
else
{
- OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm);
- OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm);
+ OPL3_EnvelopeKeyOff(channel->slotz[0], egk_norm);
+ OPL3_EnvelopeKeyOff(channel->slotz[1], egk_norm);
}
}
@@ -997,9 +997,9 @@ static void OPL3_GenerateRhythm1(opl3_chip *chip)
channel6 = &chip->channel[6];
channel7 = &chip->channel[7];
channel8 = &chip->channel[8];
- OPL3_SlotGenerate(channel6->slots[0]);
- phase14 = (channel7->slots[0]->pg_phase >> 9) & 0x3ff;
- phase17 = (channel8->slots[1]->pg_phase >> 9) & 0x3ff;
+ OPL3_SlotGenerate(channel6->slotz[0]);
+ phase14 = (channel7->slotz[0]->pg_phase >> 9) & 0x3ff;
+ phase17 = (channel8->slotz[1]->pg_phase >> 9) & 0x3ff;
phase = 0x00;
/*hh tc phase bit*/
phasebit = ((phase14 & 0x08) | (((phase14 >> 5) ^ phase14) & 0x04)
@@ -1007,9 +1007,9 @@ static void OPL3_GenerateRhythm1(opl3_chip *chip)
/*hh*/
phase = (phasebit << 9)
| (0x34 << ((phasebit ^ (chip->noise & 0x01)) << 1));
- OPL3_SlotGeneratePhase(channel7->slots[0], phase);
+ OPL3_SlotGeneratePhase(channel7->slotz[0], phase);
/*tt*/
- OPL3_SlotGenerateZM(channel8->slots[0]);
+ OPL3_SlotGenerateZM(channel8->slotz[0]);
}
static void OPL3_GenerateRhythm2(opl3_chip *chip)
@@ -1025,19 +1025,19 @@ static void OPL3_GenerateRhythm2(opl3_chip *chip)
channel6 = &chip->channel[6];
channel7 = &chip->channel[7];
channel8 = &chip->channel[8];
- OPL3_SlotGenerate(channel6->slots[1]);
- phase14 = (channel7->slots[0]->pg_phase >> 9) & 0x3ff;
- phase17 = (channel8->slots[1]->pg_phase >> 9) & 0x3ff;
+ OPL3_SlotGenerate(channel6->slotz[1]);
+ phase14 = (channel7->slotz[0]->pg_phase >> 9) & 0x3ff;
+ phase17 = (channel8->slotz[1]->pg_phase >> 9) & 0x3ff;
phase = 0x00;
/*hh tc phase bit*/
phasebit = ((phase14 & 0x08) | (((phase14 >> 5) ^ phase14) & 0x04)
| (((phase17 >> 2) ^ phase17) & 0x08)) ? 0x01 : 0x00;
/*sd*/
phase = (0x100 << ((phase14 >> 8) & 0x01)) ^ ((chip->noise & 0x01) << 8);
- OPL3_SlotGeneratePhase(channel7->slots[1], phase);
+ OPL3_SlotGeneratePhase(channel7->slotz[1], phase);
/*tc*/
phase = 0x100 | (phasebit << 9);
- OPL3_SlotGeneratePhase(channel8->slots[1], phase);
+ OPL3_SlotGeneratePhase(channel8->slotz[1], phase);
}
void OPL3v17_Generate(opl3_chip *chip, Bit16s *buf)
@@ -1202,8 +1202,8 @@ void OPL3v17_Reset(opl3_chip *chip, Bit32u samplerate)
}
for (channum = 0; channum < 18; channum++)
{
- chip->channel[channum].slots[0] = &chip->chipslot[ch_slot[channum]];
- chip->channel[channum].slots[1] = &chip->chipslot[ch_slot[channum] + 3];
+ chip->channel[channum].slotz[0] = &chip->chipslot[ch_slot[channum]];
+ chip->channel[channum].slotz[1] = &chip->chipslot[ch_slot[channum] + 3];
chip->chipslot[ch_slot[channum]].channel = &chip->channel[channum];
chip->chipslot[ch_slot[channum] + 3].channel = &chip->channel[channum];
if ((channum % 9) < 3)
diff --git a/src/chips/nuked/nukedopl3_174.h b/src/chips/nuked/nukedopl3_174.h
index 43e4a6e..240802f 100644
--- a/src/chips/nuked/nukedopl3_174.h
+++ b/src/chips/nuked/nukedopl3_174.h
@@ -91,7 +91,7 @@ struct _opl3_slot {
};
struct _opl3_channel {
- opl3_slot *slots[2];
+ opl3_slot *slotz[2];/*Don't use "slots" keyword to avoid conflict with Qt applications*/
opl3_channel *pair;
opl3_chip *chip;
Bit16s *out[4];
diff --git a/src/chips/nuked_opl3.cpp b/src/chips/nuked_opl3.cpp
index 70fc525..48e5c17 100644
--- a/src/chips/nuked_opl3.cpp
+++ b/src/chips/nuked_opl3.cpp
@@ -3,18 +3,10 @@
#include <cstring>
NukedOPL3::NukedOPL3() :
- OPLChipBase()
+ OPLChipBaseT()
{
m_chip = new opl3_chip;
- reset(m_rate);
-}
-
-NukedOPL3::NukedOPL3(const NukedOPL3 &c):
- OPLChipBase(c)
-{
- m_chip = new opl3_chip;
- std::memset(m_chip, 0, sizeof(opl3_chip));
- reset(c.m_rate);
+ setRate(m_rate);
}
NukedOPL3::~NukedOPL3()
@@ -25,7 +17,7 @@ NukedOPL3::~NukedOPL3()
void NukedOPL3::setRate(uint32_t rate)
{
- OPLChipBase::setRate(rate);
+ OPLChipBaseT::setRate(rate);
opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip);
std::memset(chip_r, 0, sizeof(opl3_chip));
OPL3_Reset(chip_r, rate);
@@ -33,12 +25,10 @@ void NukedOPL3::setRate(uint32_t rate)
void NukedOPL3::reset()
{
- setRate(m_rate);
-}
-
-void NukedOPL3::reset(uint32_t rate)
-{
- setRate(rate);
+ OPLChipBaseT::reset();
+ opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip);
+ std::memset(chip_r, 0, sizeof(opl3_chip));
+ OPL3_Reset(chip_r, m_rate);
}
void NukedOPL3::writeReg(uint16_t addr, uint8_t data)
@@ -47,44 +37,10 @@ void NukedOPL3::writeReg(uint16_t addr, uint8_t data)
OPL3_WriteRegBuffered(chip_r, addr, data);
}
-int NukedOPL3::generate(int16_t *output, size_t frames)
-{
- opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip);
- OPL3_GenerateStream(chip_r, output, (Bit32u)frames);
- return (int)frames;
-}
-
-int NukedOPL3::generateAndMix(int16_t *output, size_t frames)
-{
- opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip);
- OPL3_GenerateStreamMix(chip_r, output, (Bit32u)frames);
- return (int)frames;
-}
-
-int NukedOPL3::generate32(int32_t *output, size_t frames)
-{
- opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip);
- for(size_t i = 0; i < frames; ++i) {
- int16_t frame[2];
- OPL3_GenerateResampled(chip_r, frame);
- output[0] = (int32_t)frame[0];
- output[1] = (int32_t)frame[1];
- output += 2;
- }
- return (int)frames;
-}
-
-int NukedOPL3::generateAndMix32(int32_t *output, size_t frames)
+void NukedOPL3::nativeGenerate(int16_t *frame)
{
opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip);
- for(size_t i = 0; i < frames; ++i) {
- int16_t frame[2];
- OPL3_GenerateResampled(chip_r, frame);
- output[0] += (int32_t)frame[0];
- output[1] += (int32_t)frame[1];
- output += 2;
- }
- return (int)frames;
+ OPL3_Generate(chip_r, frame);
}
const char *NukedOPL3::emulatorName()
diff --git a/src/chips/nuked_opl3.h b/src/chips/nuked_opl3.h
index ceb1dfd..25d9ed5 100644
--- a/src/chips/nuked_opl3.h
+++ b/src/chips/nuked_opl3.h
@@ -3,23 +3,20 @@
#include "opl_chip_base.h"
-class NukedOPL3 final : public OPLChipBase
+class NukedOPL3 final : public OPLChipBaseT<NukedOPL3>
{
void *m_chip;
public:
NukedOPL3();
- NukedOPL3(const NukedOPL3 &c);
- virtual ~NukedOPL3() override;
+ ~NukedOPL3() override;
- virtual void setRate(uint32_t rate) override;
- virtual void reset() override;
- virtual void reset(uint32_t rate) override;
- virtual void writeReg(uint16_t addr, uint8_t data) override;
- virtual int generate(int16_t *output, size_t frames) override;
- virtual int generateAndMix(int16_t *output, size_t frames) override;
- virtual int generate32(int32_t *output, size_t frames) override;
- virtual int generateAndMix32(int32_t *output, size_t frames) override;
- virtual const char *emulatorName() override;
+ void setRate(uint32_t rate) override;
+ void reset() override;
+ void writeReg(uint16_t addr, uint8_t data) override;
+ void nativePreGenerate() override {}
+ void nativePostGenerate() override {}
+ void nativeGenerate(int16_t *frame) override;
+ const char *emulatorName() override;
};
#endif // NUKED_OPL3_H
diff --git a/src/chips/nuked_opl3_v174.cpp b/src/chips/nuked_opl3_v174.cpp
index 0dcf925..e24b2e7 100644
--- a/src/chips/nuked_opl3_v174.cpp
+++ b/src/chips/nuked_opl3_v174.cpp
@@ -3,18 +3,10 @@
#include <cstring>
NukedOPL3v174::NukedOPL3v174() :
- OPLChipBase()
+ OPLChipBaseT()
{
m_chip = new opl3_chip;
- reset(m_rate);
-}
-
-NukedOPL3v174::NukedOPL3v174(const NukedOPL3v174 &c):
- OPLChipBase(c)
-{
- m_chip = new opl3_chip;
- std::memset(m_chip, 0, sizeof(opl3_chip));
- reset(c.m_rate);
+ setRate(m_rate);
}
NukedOPL3v174::~NukedOPL3v174()
@@ -25,7 +17,7 @@ NukedOPL3v174::~NukedOPL3v174()
void NukedOPL3v174::setRate(uint32_t rate)
{
- OPLChipBase::setRate(rate);
+ OPLChipBaseT::setRate(rate);
opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip);
std::memset(chip_r, 0, sizeof(opl3_chip));
OPL3v17_Reset(chip_r, rate);
@@ -33,12 +25,10 @@ void NukedOPL3v174::setRate(uint32_t rate)
void NukedOPL3v174::reset()
{
- setRate(m_rate);
-}
-
-void NukedOPL3v174::reset(uint32_t rate)
-{
- setRate(rate);
+ OPLChipBaseT::reset();
+ opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip);
+ std::memset(chip_r, 0, sizeof(opl3_chip));
+ OPL3v17_Reset(chip_r, m_rate);
}
void NukedOPL3v174::writeReg(uint16_t addr, uint8_t data)
@@ -47,44 +37,10 @@ void NukedOPL3v174::writeReg(uint16_t addr, uint8_t data)
OPL3v17_WriteReg(chip_r, addr, data);
}
-int NukedOPL3v174::generate(int16_t *output, size_t frames)
-{
- opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip);
- OPL3v17_GenerateStream(chip_r, output, (Bit32u)frames);
- return (int)frames;
-}
-
-int NukedOPL3v174::generateAndMix(int16_t *output, size_t frames)
-{
- opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip);
- OPL3v17_GenerateStreamMix(chip_r, output, (Bit32u)frames);
- return (int)frames;
-}
-
-int NukedOPL3v174::generate32(int32_t *output, size_t frames)
-{
- opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip);
- for(size_t i = 0; i < frames; ++i) {
- int16_t frame[2];
- OPL3v17_GenerateResampled(chip_r, frame);
- output[0] = (int32_t)frame[0];
- output[1] = (int32_t)frame[1];
- output += 2;
- }
- return (int)frames;
-}
-
-int NukedOPL3v174::generateAndMix32(int32_t *output, size_t frames)
+void NukedOPL3v174::nativeGenerate(int16_t *frame)
{
opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip);
- for(size_t i = 0; i < frames; ++i) {
- int16_t frame[2];
- OPL3v17_GenerateResampled(chip_r, frame);
- output[0] += (int32_t)frame[0];
- output[1] += (int32_t)frame[1];
- output += 2;
- }
- return (int)frames;
+ OPL3v17_Generate(chip_r, frame);
}
const char *NukedOPL3v174::emulatorName()
diff --git a/src/chips/nuked_opl3_v174.h b/src/chips/nuked_opl3_v174.h
index acbdcca..b9c5ba6 100644
--- a/src/chips/nuked_opl3_v174.h
+++ b/src/chips/nuked_opl3_v174.h
@@ -3,23 +3,20 @@
#include "opl_chip_base.h"
-class NukedOPL3v174 final : public OPLChipBase
+class NukedOPL3v174 final : public OPLChipBaseT<NukedOPL3v174>
{
void *m_chip;
public:
NukedOPL3v174();
- NukedOPL3v174(const NukedOPL3v174 &c);
- virtual ~NukedOPL3v174() override;
+ ~NukedOPL3v174() override;
- virtual void setRate(uint32_t rate) override;
- virtual void reset() override;
- virtual void reset(uint32_t rate) override;
- virtual void writeReg(uint16_t addr, uint8_t data) override;
- virtual int generate(int16_t *output, size_t frames) override;
- virtual int generateAndMix(int16_t *output, size_t frames) override;
- virtual int generate32(int32_t *output, size_t frames) override;
- virtual int generateAndMix32(int32_t *output, size_t frames) override;
- virtual const char *emulatorName() override;
+ void setRate(uint32_t rate) override;
+ void reset() override;
+ void writeReg(uint16_t addr, uint8_t data) override;
+ void nativePreGenerate() override {}
+ void nativePostGenerate() override {}
+ void nativeGenerate(int16_t *frame) override;
+ const char *emulatorName() override;
};
#endif // NUKED_OPL3174_H
diff --git a/src/chips/opl_chip_base.cpp b/src/chips/opl_chip_base.cpp
deleted file mode 100644
index 670a998..0000000
--- a/src/chips/opl_chip_base.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-#include "opl_chip_base.h"
-
-OPLChipBase::OPLChipBase() :
- m_rate(44100)
-{}
-
-OPLChipBase::OPLChipBase(const OPLChipBase &c):
- m_rate(c.m_rate)
-{}
-
-OPLChipBase::~OPLChipBase()
-{}
-
-void OPLChipBase::setRate(uint32_t rate)
-{
- m_rate = rate;
-}
-
-void OPLChipBase::reset(uint32_t rate)
-{
- setRate(rate);
-}
-
-int OPLChipBase::generate32(int32_t *output, size_t frames)
-{
- enum { maxFramesAtOnce = 256 };
- int16_t temp[2 * maxFramesAtOnce];
- for(size_t left = frames; left > 0;) {
- size_t count = (left < static_cast<size_t>(maxFramesAtOnce)) ? left : static_cast<size_t>(maxFramesAtOnce);
- generate(temp, count);
- for(size_t i = 0; i < 2 * count; ++i)
- output[i] = temp[i];
- left -= count;
- output += 2 * count;
- }
- return (int)frames;
-}
-
-int OPLChipBase::generateAndMix32(int32_t *output, size_t frames)
-{
- enum { maxFramesAtOnce = 256 };
- int16_t temp[2 * maxFramesAtOnce];
- for(size_t left = frames; left > 0;) {
- size_t count = (left < static_cast<size_t>(maxFramesAtOnce)) ? left : static_cast<size_t>(maxFramesAtOnce);
- generate(temp, count);
- for(size_t i = 0; i < 2 * count; ++i)
- output[i] += temp[i];
- left -= count;
- output += 2 * count;
- }
- return (int)frames;
-}
diff --git a/src/chips/opl_chip_base.h b/src/chips/opl_chip_base.h
index fb9b9e9..5721a81 100644
--- a/src/chips/opl_chip_base.h
+++ b/src/chips/opl_chip_base.h
@@ -9,24 +9,91 @@
#define override
#endif
+#if defined(ADLMIDI_ENABLE_HQ_RESAMPLER)
+class VResampler;
+#endif
+
class OPLChipBase
{
protected:
uint32_t m_rate;
public:
OPLChipBase();
- OPLChipBase(const OPLChipBase &c);
virtual ~OPLChipBase();
- virtual void setRate(uint32_t rate);
+ virtual void setRate(uint32_t rate) = 0;
virtual void reset() = 0;
- virtual void reset(uint32_t rate);
virtual void writeReg(uint16_t addr, uint8_t data) = 0;
- virtual int generate(int16_t *output, size_t frames) = 0;
- virtual int generateAndMix(int16_t *output, size_t frames) = 0;
- virtual int generate32(int32_t *output, size_t frames);
- virtual int generateAndMix32(int32_t *output, size_t frames);
+
+ virtual void nativePreGenerate() = 0;
+ virtual void nativePostGenerate() = 0;
+ virtual void nativeGenerate(int16_t *frame) = 0;
+
+ virtual void generate(int16_t *output, size_t frames) = 0;
+ virtual void generateAndMix(int16_t *output, size_t frames) = 0;
+ virtual void generate32(int32_t *output, size_t frames) = 0;
+ virtual void generateAndMix32(int32_t *output, size_t frames) = 0;
+
virtual const char* emulatorName() = 0;
+private:
+ OPLChipBase(const OPLChipBase &c);
+ OPLChipBase &operator=(const OPLChipBase &c);
+};
+
+// A base class providing F-bounded generic and efficient implementations,
+// supporting resampling of chip outputs
+template <class T>
+class OPLChipBaseT : public OPLChipBase
+{
+public:
+ OPLChipBaseT();
+ virtual ~OPLChipBaseT();
+
+ virtual void setRate(uint32_t rate) override;
+ virtual void reset() override;
+ void generate(int16_t *output, size_t frames) override;
+ void generateAndMix(int16_t *output, size_t frames) override;
+ void generate32(int32_t *output, size_t frames) override;
+ void generateAndMix32(int32_t *output, size_t frames) override;
+private:
+ void setupResampler(uint32_t rate);
+ void resetResampler();
+ void resampledGenerate(int32_t *output);
+#if defined(ADLMIDI_ENABLE_HQ_RESAMPLER)
+ VResampler *m_resampler;
+#else
+ int32_t m_oldsamples[2];
+ int32_t m_samples[2];
+ int32_t m_samplecnt;
+ int32_t m_rateratio;
+ enum { rsm_frac = 10 };
+#endif
+ // amplitude scale factors in and out of resampler, varying for chips;
+ // values are OK to "redefine", the static polymorphism will accept it.
+ enum { resamplerPreAmplify = 1, resamplerPostAttenuate = 1 };
+};
+
+// A base class which provides frame-by-frame interfaces on emulations which
+// don't have a routine for it. It produces outputs in fixed size buffers.
+// Fast register updates will suffer some latency because of buffering.
+template <class T, unsigned Buffer = 256>
+class OPLChipBaseBufferedT : public OPLChipBaseT<T>
+{
+public:
+ OPLChipBaseBufferedT()
+ : OPLChipBaseT<T>(), m_bufferIndex(0) {}
+ virtual ~OPLChipBaseBufferedT()
+ {}
+public:
+ void reset() override;
+ void nativeGenerate(int16_t *frame) override;
+protected:
+ virtual void nativeGenerateN(int16_t *output, size_t frames) = 0;
+private:
+ unsigned m_bufferIndex;
+ int16_t m_buffer[2 * Buffer];
};
+#include "opl_chip_base.tcc"
+
#endif // ONP_CHIP_BASE_H
diff --git a/src/chips/opl_chip_base.tcc b/src/chips/opl_chip_base.tcc
new file mode 100644
index 0000000..58145bc
--- /dev/null
+++ b/src/chips/opl_chip_base.tcc
@@ -0,0 +1,216 @@
+#include "opl_chip_base.h"
+#include <cmath>
+
+#if defined(ADLMIDI_ENABLE_HQ_RESAMPLER)
+#include <zita-resampler/vresampler.h>
+#endif
+
+/* OPLChipBase */
+
+inline OPLChipBase::OPLChipBase() :
+ m_rate(44100)
+{
+}
+
+inline OPLChipBase::~OPLChipBase()
+{
+}
+
+/* OPLChipBaseT */
+
+template <class T>
+OPLChipBaseT<T>::OPLChipBaseT()
+ : OPLChipBase()
+{
+#if defined(ADLMIDI_ENABLE_HQ_RESAMPLER)
+ m_resampler = new VResampler;
+#endif
+ setupResampler(m_rate);
+}
+
+template <class T>
+OPLChipBaseT<T>::~OPLChipBaseT()
+{
+#if defined(ADLMIDI_ENABLE_HQ_RESAMPLER)
+ delete m_resampler;
+#endif
+}
+
+template <class T>
+void OPLChipBaseT<T>::setRate(uint32_t rate)
+{
+ uint32_t oldRate = m_rate;
+ m_rate = rate;
+ if(rate != oldRate)
+ setupResampler(rate);
+ else
+ resetResampler();
+}
+
+template <class T>
+void OPLChipBaseT<T>::reset()
+{
+ resetResampler();
+}
+
+template <class T>
+void OPLChipBaseT<T>::generate(int16_t *output, size_t frames)
+{
+ static_cast<T *>(this)->nativePreGenerate();
+ for(size_t i = 0; i < frames; ++i)
+ {
+ int32_t frame[2];
+ static_cast<T *>(this)->resampledGenerate(frame);
+ for (unsigned c = 0; c < 2; ++c) {
+ int32_t temp = frame[c];
+ temp = (temp > -32768) ? temp : -32768;
+ temp = (temp < 32767) ? temp : 32767;
+ output[c] = (int16_t)temp;
+ }
+ output += 2;
+ }
+ static_cast<T *>(this)->nativePostGenerate();
+}
+
+template <class T>
+void OPLChipBaseT<T>::generateAndMix(int16_t *output, size_t frames)
+{
+ static_cast<T *>(this)->nativePreGenerate();
+ for(size_t i = 0; i < frames; ++i)
+ {
+ int32_t frame[2];
+ static_cast<T *>(this)->resampledGenerate(frame);
+ for (unsigned c = 0; c < 2; ++c) {
+ int32_t temp = (int32_t)output[c] + frame[c];
+ temp = (temp > -32768) ? temp : -32768;
+ temp = (temp < 32767) ? temp : 32767;
+ output[c] = (int16_t)temp;
+ }
+ output += 2;
+ }
+ static_cast<T *>(this)->nativePostGenerate();
+}
+
+template <class T>
+void OPLChipBaseT<T>::generate32(int32_t *output, size_t frames)
+{
+ static_cast<T *>(this)->nativePreGenerate();
+ for(size_t i = 0; i < frames; ++i)
+ {
+ static_cast<T *>(this)->resampledGenerate(output);
+ output += 2;
+ }
+ static_cast<T *>(this)->nativePostGenerate();
+}
+
+template <class T>
+void OPLChipBaseT<T>::generateAndMix32(int32_t *output, size_t frames)
+{
+ static_cast<T *>(this)->nativePreGenerate();
+ for(size_t i = 0; i < frames; ++i)
+ {
+ int32_t frame[2];
+ static_cast<T *>(this)->resampledGenerate(frame);
+ output[0] += frame[0];
+ output[1] += frame[1];
+ output += 2;
+ }
+ static_cast<T *>(this)->nativePostGenerate();
+}
+
+template <class T>
+void OPLChipBaseT<T>::setupResampler(uint32_t rate)
+{
+#if defined(ADLMIDI_ENABLE_HQ_RESAMPLER)
+ m_resampler->setup(rate * (1.0 / 49716), 2, 48);
+#else
+ m_oldsamples[0] = m_oldsamples[1] = 0;
+ m_samples[0] = m_samples[1] = 0;
+ m_samplecnt = 0;
+ m_rateratio = (int32_t)((rate << rsm_frac) / 49716);
+#endif
+}
+
+template <class T>
+void OPLChipBaseT<T>::resetResampler()
+{
+#if defined(ADLMIDI_ENABLE_HQ_RESAMPLER)
+ m_resampler->reset();
+#else
+ m_oldsamples[0] = m_oldsamples[1] = 0;
+ m_samples[0] = m_samples[1] = 0;
+ m_samplecnt = 0;
+#endif
+}
+
+#if defined(ADLMIDI_ENABLE_HQ_RESAMPLER)
+template <class T>
+void OPLChipBaseT<T>::resampledGenerate(int32_t *output)
+{
+ VResampler *rsm = m_resampler;
+ float scale = (float)T::resamplerPreAmplify /
+ (float)T::resamplerPostAttenuate;
+ float f_in[2];
+ float f_out[2];
+ rsm->inp_count = 0;
+ rsm->inp_data = f_in;
+ rsm->out_count = 1;
+ rsm->out_data = f_out;
+ while(rsm->process(), rsm->out_count != 0)
+ {
+ int16_t in[2];
+ static_cast<T *>(this)->nativeGenerate(in);
+ f_in[0] = scale * (float)in[0];
+ f_in[1] = scale * (float)in[1];
+ rsm->inp_count = 1;
+ rsm->inp_data = f_in;
+ rsm->out_count = 1;
+ rsm->out_data = f_out;
+ }
+ output[0] = std::lround(f_out[0]);
+ output[1] = std::lround(f_out[1]);
+}
+#else
+template <class T>
+void OPLChipBaseT<T>::resampledGenerate(int32_t *output)
+{
+ int32_t samplecnt = m_samplecnt;
+ const int32_t rateratio = m_rateratio;
+ while(samplecnt >= rateratio)
+ {
+ m_oldsamples[0] = m_samples[0];
+ m_oldsamples[1] = m_samples[1];
+ int16_t buffer[2];
+ static_cast<T *>(this)->nativeGenerate(buffer);
+ m_samples[0] = buffer[0] * T::resamplerPreAmplify;
+ m_samples[1] = buffer[1] * T::resamplerPreAmplify;
+ samplecnt -= rateratio;
+ }
+ output[0] = (int32_t)(((m_oldsamples[0] * (rateratio - samplecnt)
+ + m_samples[0] * samplecnt) / rateratio)/T::resamplerPostAttenuate);
+ output[1] = (int32_t)(((m_oldsamples[1] * (rateratio - samplecnt)
+ + m_samples[1] * samplecnt) / rateratio)/T::resamplerPostAttenuate);
+ m_samplecnt = samplecnt + (1 << rsm_frac);
+}
+#endif
+
+/* OPLChipBaseBufferedT */
+
+template <class T, unsigned Buffer>
+void OPLChipBaseBufferedT<T, Buffer>::reset()
+{
+ OPLChipBaseT<T>::reset();
+ m_bufferIndex = 0;
+}
+
+template <class T, unsigned Buffer>
+void OPLChipBaseBufferedT<T, Buffer>::nativeGenerate(int16_t *frame)
+{
+ unsigned bufferIndex = m_bufferIndex;
+ if(bufferIndex == 0)
+ static_cast<T *>(this)->nativeGenerateN(m_buffer, Buffer);
+ frame[0] = m_buffer[2 * bufferIndex];
+ frame[1] = m_buffer[2 * bufferIndex + 1];
+ bufferIndex = (bufferIndex + 1 < Buffer) ? (bufferIndex + 1) : 0;
+ m_bufferIndex = bufferIndex;
+}
diff --git a/src/fraction.hpp b/src/fraction.hpp
index 1ec10ab..1c0a38d 100644
--- a/src/fraction.hpp
+++ b/src/fraction.hpp
@@ -4,6 +4,7 @@
#include <cmath>
#include <limits>
+
/* Fraction number handling.
* Copyright (C) 1992,2001 Bisqwit (http://iki.fi/bisqwit/)
*/
@@ -82,6 +83,10 @@ public:
self &operator= (long double orig);
};
+#ifdef _MSC_VER
+#pragma warning(disable:4146)
+#endif
+
template<typename inttype>
void fraction<inttype>::Optim()
{
@@ -110,6 +115,10 @@ void fraction<inttype>::Optim()
//fprintf(stderr, "result: %d/%d\n\n", nom(), denom());
}
+#ifdef _MSC_VER
+#pragma warning(default:4146)
+#endif
+
template<typename inttype>
inline const fraction<inttype> abs(const fraction<inttype> &f)
{
diff --git a/src/wopl/wopl_file.h b/src/wopl/wopl_file.h
index f5d816b..0e38842 100644
--- a/src/wopl/wopl_file.h
+++ b/src/wopl/wopl_file.h
@@ -32,6 +32,14 @@
extern "C" {
#endif
+#if !defined(__STDC_VERSION__) || (defined(__STDC_VERSION__) && (__STDC_VERSION__ < 199901L)) \
+ || defined(__STRICT_ANSI__) || !defined(__cplusplus)
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef signed short int int16_t;
+typedef unsigned short int uint16_t;
+#endif
+
/* Global OPL flags */
typedef enum WOPLFileFlags
{
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100644
index 0000000..bb5615e
--- /dev/null
+++ b/test/CMakeLists.txt
@@ -0,0 +1,7 @@
+
+set(CMAKE_CXX_STANDARD 11)
+
+add_subdirectory(bankmap)
+
+add_library(Catch-objects OBJECT "common/catch_main.cpp")
+target_include_directories(Catch-objects PRIVATE "common")
diff --git a/test/bankmap/CMakeLists.txt b/test/bankmap/CMakeLists.txt
new file mode 100644
index 0000000..2741637
--- /dev/null
+++ b/test/bankmap/CMakeLists.txt
@@ -0,0 +1,12 @@
+
+set(CMAKE_CXX_STANDARD 11)
+
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}/../common
+ ${CMAKE_SOURCE_DIR}/include
+ ${CMAKE_SOURCE_DIR}/src)
+
+add_executable(BankMapTest bank_map.cpp $<TARGET_OBJECTS:Catch-objects>)
+
+set_target_properties(BankMapTest PROPERTIES COMPILE_DEFINITIONS "GSL_THROW_ON_CONTRACT_VIOLATION")
+add_test(NAME BankMapTest COMMAND BankMapTest)
diff --git a/test/bankmap/bank_map.cpp b/test/bankmap/bank_map.cpp
new file mode 100644
index 0000000..613fc59
--- /dev/null
+++ b/test/bankmap/bank_map.cpp
@@ -0,0 +1,100 @@
+#include <catch.hpp>
+#include <random>
+#include "adlmidi_bankmap.h"
+
+typedef BasicBankMap<int> BankMap;
+typedef BankMap::value_type ValuePair;
+typedef BankMap::iterator Iterator;
+typedef std::pair<Iterator, bool> InsertResult;
+
+static std::mt19937 rng;
+
+static size_t iterated_size(const BankMap &map)
+{
+ size_t size = 0;
+ auto it = map.begin(), end = map.end();
+ while(it != end) {
+ ++it;
+ ++size;
+ }
+ return size;
+}
+
+static bool consistent_size(const BankMap &map)
+{
+ return map.size() == iterated_size(map);
+}
+
+TEST_CASE("[BankMap] Construction")
+{
+ BankMap map;
+
+ REQUIRE(map.capacity() == 0);
+ REQUIRE(map.size() == 0);
+ REQUIRE(iterated_size(map) == 0);
+}
+
+TEST_CASE("[BankMap] Insert, erase and find")
+{
+ BankMap map;
+
+ for(unsigned i = 0; i < 10; ++i) {
+ const uint16_t key = rng();
+ const int value = rng();
+
+ uint16_t another_key = rng();
+ while (another_key == key)
+ another_key = rng();
+
+ InsertResult ir = map.insert(ValuePair{key, value});
+ REQUIRE(ir.second);
+ REQUIRE(map.size() == 1);
+ REQUIRE(iterated_size(map) == 1);
+
+ Iterator it = map.find(key);
+ REQUIRE(it != map.end());
+ REQUIRE(it->first == key);
+ REQUIRE(it->second == value);
+ REQUIRE(map.find(another_key) == map.end());
+
+ map.erase(it);
+ REQUIRE(map.find(key) == map.end());
+ REQUIRE(map.size() == 0);
+ REQUIRE(iterated_size(map) == 0);
+ }
+}
+
+TEST_CASE("[BankMap] Insert without expanding")
+{
+ BankMap map;
+
+ InsertResult ir;
+ ir = map.insert(ValuePair{0, 0}, BankMap::do_not_expand_t());
+ REQUIRE(ir.first == map.end());
+ REQUIRE(!ir.second);
+
+ map.reserve(1);
+ REQUIRE(map.capacity() > 1);
+
+ while(map.size() < map.capacity()) {
+ const uint16_t key = rng();
+ const int value = rng();
+ if(map.find(key) != map.end())
+ continue;
+ ir = map.insert(ValuePair{key, value}, BankMap::do_not_expand_t());
+ REQUIRE(ir.first != map.end());
+ REQUIRE(ir.first->first == key);
+ REQUIRE(ir.first->second == value);
+ REQUIRE(ir.second);
+ REQUIRE(consistent_size(map));
+ }
+
+ ir = map.insert(ValuePair{0, 0}, BankMap::do_not_expand_t());
+ REQUIRE(ir.first == map.end());
+ REQUIRE(!ir.second);
+ REQUIRE(consistent_size(map));
+
+ map.clear();
+ REQUIRE(map.size() == 0);
+ REQUIRE(consistent_size(map));
+}
diff --git a/test/common/catch.hpp b/test/common/catch.hpp
new file mode 100644
index 0000000..ecd8907
--- /dev/null
+++ b/test/common/catch.hpp
@@ -0,0 +1,13050 @@
+/*
+ * Catch v2.2.2
+ * Generated: 2018-04-06 12:05:03.186665
+ * ----------------------------------------------------------
+ * This file has been merged from multiple headers. Please don't edit it directly
+ * Copyright (c) 2018 Two Blue Cubes Ltd. All rights reserved.
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
+#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
+// start catch.hpp
+
+
+#define CATCH_VERSION_MAJOR 2
+#define CATCH_VERSION_MINOR 2
+#define CATCH_VERSION_PATCH 2
+
+#ifdef __clang__
+# pragma clang system_header
+#elif defined __GNUC__
+# pragma GCC system_header
+#endif
+
+// start catch_suppress_warnings.h
+
+#ifdef __clang__
+# ifdef __ICC // icpc defines the __clang__ macro
+# pragma warning(push)
+# pragma warning(disable: 161 1682)
+# else // __ICC
+# pragma clang diagnostic ignored "-Wunused-variable"
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wpadded"
+# pragma clang diagnostic ignored "-Wswitch-enum"
+# pragma clang diagnostic ignored "-Wcovered-switch-default"
+# endif
+#elif defined __GNUC__
+# pragma GCC diagnostic ignored "-Wparentheses"
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wunused-variable"
+# pragma GCC diagnostic ignored "-Wpadded"
+#endif
+// end catch_suppress_warnings.h
+#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
+# define CATCH_IMPL
+# define CATCH_CONFIG_ALL_PARTS
+#endif
+
+// In the impl file, we want to have access to all parts of the headers
+// Can also be used to sanely support PCHs
+#if defined(CATCH_CONFIG_ALL_PARTS)
+# define CATCH_CONFIG_EXTERNAL_INTERFACES
+# if defined(CATCH_CONFIG_DISABLE_MATCHERS)
+# undef CATCH_CONFIG_DISABLE_MATCHERS
+# endif
+# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
+#endif
+
+#if !defined(CATCH_CONFIG_IMPL_ONLY)
+// start catch_platform.h
+
+#ifdef __APPLE__
+# include <TargetConditionals.h>
+# if TARGET_OS_OSX == 1
+# define CATCH_PLATFORM_MAC
+# elif TARGET_OS_IPHONE == 1
+# define CATCH_PLATFORM_IPHONE
+# endif
+
+#elif defined(linux) || defined(__linux) || defined(__linux__)
+# define CATCH_PLATFORM_LINUX
+
+#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
+# define CATCH_PLATFORM_WINDOWS
+#endif
+
+// end catch_platform.h
+
+#ifdef CATCH_IMPL
+# ifndef CLARA_CONFIG_MAIN
+# define CLARA_CONFIG_MAIN_NOT_DEFINED
+# define CLARA_CONFIG_MAIN
+# endif
+#endif
+
+// start catch_user_interfaces.h
+
+namespace Catch {
+ unsigned int rngSeed();
+}
+
+// end catch_user_interfaces.h
+// start catch_tag_alias_autoregistrar.h
+
+// start catch_common.h
+
+// start catch_compiler_capabilities.h
+
+// Detect a number of compiler features - by compiler
+// The following features are defined:
+//
+// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
+// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
+// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
+// ****************
+// Note to maintainers: if new toggles are added please document them
+// in configuration.md, too
+// ****************
+
+// In general each macro has a _NO_<feature name> form
+// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.
+// Many features, at point of detection, define an _INTERNAL_ macro, so they
+// can be combined, en-mass, with the _NO_ forms later.
+
+#ifdef __cplusplus
+
+# if __cplusplus >= 201402L
+# define CATCH_CPP14_OR_GREATER
+# endif
+
+# if __cplusplus >= 201703L
+# define CATCH_CPP17_OR_GREATER
+# endif
+
+#endif
+
+#if defined(CATCH_CPP17_OR_GREATER)
+# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
+#endif
+
+#ifdef __clang__
+
+# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+ _Pragma( "clang diagnostic push" ) \
+ _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
+ _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
+# define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
+ _Pragma( "clang diagnostic pop" )
+
+# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
+ _Pragma( "clang diagnostic push" ) \
+ _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
+# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
+ _Pragma( "clang diagnostic pop" )
+
+#endif // __clang__
+
+////////////////////////////////////////////////////////////////////////////////
+// Assume that non-Windows platforms support posix signals by default
+#if !defined(CATCH_PLATFORM_WINDOWS)
+ #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// We know some environments not to support full POSIX signals
+#if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)
+ #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
+#endif
+
+#ifdef __OS400__
+# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
+# define CATCH_CONFIG_COLOUR_NONE
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// Cygwin
+#ifdef __CYGWIN__
+
+// Required for some versions of Cygwin to declare gettimeofday
+// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
+# define _BSD_SOURCE
+
+#endif // __CYGWIN__
+
+////////////////////////////////////////////////////////////////////////////////
+// Visual C++
+#ifdef _MSC_VER
+
+# if _MSC_VER >= 1900 // Visual Studio 2015 or newer
+# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
+# endif
+
+// Universal Windows platform does not support SEH
+// Or console colours (or console at all...)
+# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
+# define CATCH_CONFIG_COLOUR_NONE
+# else
+# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
+# endif
+
+#endif // _MSC_VER
+
+////////////////////////////////////////////////////////////////////////////////
+
+// DJGPP
+#ifdef __DJGPP__
+# define CATCH_INTERNAL_CONFIG_NO_WCHAR
+#endif // __DJGPP__
+
+////////////////////////////////////////////////////////////////////////////////
+
+// Use of __COUNTER__ is suppressed during code analysis in
+// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
+// handled by it.
+// Otherwise all supported compilers support COUNTER macro,
+// but user still might want to turn it off
+#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )
+ #define CATCH_INTERNAL_CONFIG_COUNTER
+#endif
+
+#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
+# define CATCH_CONFIG_COUNTER
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH)
+# define CATCH_CONFIG_WINDOWS_SEH
+#endif
+// This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
+#if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
+# define CATCH_CONFIG_POSIX_SIGNALS
+#endif
+// This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions.
+#if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR)
+# define CATCH_CONFIG_WCHAR
+#endif
+
+#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
+# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
+#endif
+
+#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
+# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
+# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
+#endif
+#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
+# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
+# define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
+#endif
+
+// end catch_compiler_capabilities.h
+#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
+#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
+#ifdef CATCH_CONFIG_COUNTER
+# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
+#else
+# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
+#endif
+
+#include <iosfwd>
+#include <string>
+#include <cstdint>
+
+namespace Catch {
+
+ struct CaseSensitive { enum Choice {
+ Yes,
+ No
+ }; };
+
+ class NonCopyable {
+ NonCopyable( NonCopyable const& ) = delete;
+ NonCopyable( NonCopyable && ) = delete;
+ NonCopyable& operator = ( NonCopyable const& ) = delete;
+ NonCopyable& operator = ( NonCopyable && ) = delete;
+
+ protected:
+ NonCopyable();
+ virtual ~NonCopyable();
+ };
+
+ struct SourceLineInfo {
+
+ SourceLineInfo() = delete;
+ SourceLineInfo( char const* _file, std::size_t _line ) noexcept
+ : file( _file ),
+ line( _line )
+ {}
+
+ SourceLineInfo( SourceLineInfo const& other ) = default;
+ SourceLineInfo( SourceLineInfo && ) = default;
+ SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
+ SourceLineInfo& operator = ( SourceLineInfo && ) = default;
+
+ bool empty() const noexcept;
+ bool operator == ( SourceLineInfo const& other ) const noexcept;
+ bool operator < ( SourceLineInfo const& other ) const noexcept;
+
+ char const* file;
+ std::size_t line;
+ };
+
+ std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
+
+ // Use this in variadic streaming macros to allow
+ // >> +StreamEndStop
+ // as well as
+ // >> stuff +StreamEndStop
+ struct StreamEndStop {
+ std::string operator+() const;
+ };
+ template<typename T>
+ T const& operator + ( T const& value, StreamEndStop ) {
+ return value;
+ }
+}
+
+#define CATCH_INTERNAL_LINEINFO \
+ ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
+
+// end catch_common.h
+namespace Catch {
+
+ struct RegistrarForTagAliases {
+ RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
+ };
+
+} // end namespace Catch
+
+#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \
+ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+ namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \
+ CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
+
+// end catch_tag_alias_autoregistrar.h
+// start catch_test_registry.h
+
+// start catch_interfaces_testcase.h
+
+#include <vector>
+#include <memory>
+
+namespace Catch {
+
+ class TestSpec;
+
+ struct ITestInvoker {
+ virtual void invoke () const = 0;
+ virtual ~ITestInvoker();
+ };
+
+ using ITestCasePtr = std::shared_ptr<ITestInvoker>;
+
+ class TestCase;
+ struct IConfig;
+
+ struct ITestCaseRegistry {
+ virtual ~ITestCaseRegistry();
+ virtual std::vector<TestCase> const& getAllTests() const = 0;
+ virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
+ };
+
+ bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
+ std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
+ std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
+
+}
+
+// end catch_interfaces_testcase.h
+// start catch_stringref.h
+
+#include <cstddef>
+#include <string>
+#include <iosfwd>
+
+namespace Catch {
+
+ class StringData;
+
+ /// A non-owning string class (similar to the forthcoming std::string_view)
+ /// Note that, because a StringRef may be a substring of another string,
+ /// it may not be null terminated. c_str() must return a null terminated
+ /// string, however, and so the StringRef will internally take ownership
+ /// (taking a copy), if necessary. In theory this ownership is not externally
+ /// visible - but it does mean (substring) StringRefs should not be shared between
+ /// threads.
+ class StringRef {
+ public:
+ using size_type = std::size_t;
+
+ private:
+ friend struct StringRefTestAccess;
+
+ char const* m_start;
+ size_type m_size;
+
+ char* m_data = nullptr;
+
+ void takeOwnership();
+
+ static constexpr char const* const s_empty = "";
+
+ public: // construction/ assignment
+ StringRef() noexcept
+ : StringRef( s_empty, 0 )
+ {}
+
+ StringRef( StringRef const& other ) noexcept
+ : m_start( other.m_start ),
+ m_size( other.m_size )
+ {}
+
+ StringRef( StringRef&& other ) noexcept
+ : m_start( other.m_start ),
+ m_size( other.m_size ),
+ m_data( other.m_data )
+ {
+ other.m_data = nullptr;
+ }
+
+ StringRef( char const* rawChars ) noexcept;
+
+ StringRef( char const* rawChars, size_type size ) noexcept
+ : m_start( rawChars ),
+ m_size( size )
+ {}
+
+ StringRef( std::string const& stdString ) noexcept
+ : m_start( stdString.c_str() ),
+ m_size( stdString.size() )
+ {}
+
+ ~StringRef() noexcept {
+ delete[] m_data;
+ }
+
+ auto operator = ( StringRef const &other ) noexcept -> StringRef& {
+ delete[] m_data;
+ m_data = nullptr;
+ m_start = other.m_start;
+ m_size = other.m_size;
+ return *this;
+ }
+
+ operator std::string() const;
+
+ void swap( StringRef& other ) noexcept;
+
+ public: // operators
+ auto operator == ( StringRef const& other ) const noexcept -> bool;
+ auto operator != ( StringRef const& other ) const noexcept -> bool;
+
+ auto operator[] ( size_type index ) const noexcept -> char;
+
+ public: // named queries
+ auto empty() const noexcept -> bool {
+ return m_size == 0;
+ }
+ auto size() const noexcept -> size_type {
+ return m_size;
+ }
+
+ auto numberOfCharacters() const noexcept -> size_type;
+ auto c_str() const -> char const*;
+
+ public: // substrings and searches
+ auto substr( size_type start, size_type size ) const noexcept -> StringRef;
+
+ // Returns the current start pointer.
+ // Note that the pointer can change when if the StringRef is a substring
+ auto currentData() const noexcept -> char const*;
+
+ private: // ownership queries - may not be consistent between calls
+ auto isOwned() const noexcept -> bool;
+ auto isSubstring() const noexcept -> bool;
+ };
+
+ auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string;
+ auto operator + ( StringRef const& lhs, char const* rhs ) -> std::string;
+ auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string;
+
+ auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&;
+ auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;
+
+ inline auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {
+ return StringRef( rawChars, size );
+ }
+
+} // namespace Catch
+
+// end catch_stringref.h
+namespace Catch {
+
+template<typename C>
+class TestInvokerAsMethod : public ITestInvoker {
+ void (C::*m_testAsMethod)();
+public:
+ TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {}
+
+ void invoke() const override {
+ C obj;
+ (obj.*m_testAsMethod)();
+ }
+};
+
+auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*;
+
+template<typename C>
+auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* {
+ return new(std::nothrow) TestInvokerAsMethod<C>( testAsMethod );
+}
+
+struct NameAndTags {
+ NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept;
+ StringRef name;
+ StringRef tags;
+};
+
+struct AutoReg : NonCopyable {
+ AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept;
+ ~AutoReg();
+};
+
+} // end namespace Catch
+
+#if defined(CATCH_CONFIG_DISABLE)
+ #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
+ static void TestName()
+ #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
+ namespace{ \
+ struct TestName : ClassName { \
+ void test(); \
+ }; \
+ } \
+ void TestName::test()
+
+#endif
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
+ static void TestName(); \
+ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
+ CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
+ static void TestName()
+ #define INTERNAL_CATCH_TESTCASE( ... ) \
+ INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
+ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
+ CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
+ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+ namespace{ \
+ struct TestName : ClassName{ \
+ void test(); \
+ }; \
+ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
+ } \
+ CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
+ void TestName::test()
+ #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
+ INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
+ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
+ CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
+
+// end catch_test_registry.h
+// start catch_capture.hpp
+
+// start catch_assertionhandler.h
+
+// start catch_assertioninfo.h
+
+// start catch_result_type.h
+
+namespace Catch {
+
+ // ResultWas::OfType enum
+ struct ResultWas { enum OfType {
+ Unknown = -1,
+ Ok = 0,
+ Info = 1,
+ Warning = 2,
+
+ FailureBit = 0x10,
+
+ ExpressionFailed = FailureBit | 1,
+ ExplicitFailure = FailureBit | 2,
+
+ Exception = 0x100 | FailureBit,
+
+ ThrewException = Exception | 1,
+ DidntThrowException = Exception | 2,
+
+ FatalErrorCondition = 0x200 | FailureBit
+
+ }; };
+
+ bool isOk( ResultWas::OfType resultType );
+ bool isJustInfo( int flags );
+
+ // ResultDisposition::Flags enum
+ struct ResultDisposition { enum Flags {
+ Normal = 0x01,
+
+ ContinueOnFailure = 0x02, // Failures fail test, but execution continues
+ FalseTest = 0x04, // Prefix expression with !
+ SuppressFail = 0x08 // Failures are reported but do not fail the test
+ }; };
+
+ ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs );
+
+ bool shouldContinueOnFailure( int flags );
+ inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
+ bool shouldSuppressFailure( int flags );
+
+} // end namespace Catch
+
+// end catch_result_type.h
+namespace Catch {
+
+ struct AssertionInfo
+ {
+ StringRef macroName;
+ SourceLineInfo lineInfo;
+ StringRef capturedExpression;
+ ResultDisposition::Flags resultDisposition;
+
+ // We want to delete this constructor but a compiler bug in 4.8 means
+ // the struct is then treated as non-aggregate
+ //AssertionInfo() = delete;
+ };
+
+} // end namespace Catch
+
+// end catch_assertioninfo.h
+// start catch_decomposer.h
+
+// start catch_tostring.h
+
+#include <vector>
+#include <cstddef>
+#include <type_traits>
+#include <string>
+// start catch_stream.h
+
+#include <iosfwd>
+#include <cstddef>
+#include <ostream>
+
+namespace Catch {
+
+ std::ostream& cout();
+ std::ostream& cerr();
+ std::ostream& clog();
+
+ class StringRef;
+
+ struct IStream {
+ virtual ~IStream();
+ virtual std::ostream& stream() const = 0;
+ };
+
+ auto makeStream( StringRef const &filename ) -> IStream const*;
+
+ class ReusableStringStream {
+ std::size_t m_index;
+ std::ostream* m_oss;
+ public:
+ ReusableStringStream();
+ ~ReusableStringStream();
+
+ auto str() const -> std::string;
+
+ template<typename T>
+ auto operator << ( T const& value ) -> ReusableStringStream& {
+ *m_oss << value;
+ return *this;
+ }
+ auto get() -> std::ostream& { return *m_oss; }
+
+ static void cleanup();
+ };
+}
+
+// end catch_stream.h
+
+#ifdef __OBJC__
+// start catch_objc_arc.hpp
+
+#import <Foundation/Foundation.h>
+
+#ifdef __has_feature
+#define CATCH_ARC_ENABLED __has_feature(objc_arc)
+#else
+#define CATCH_ARC_ENABLED 0
+#endif
+
+void arcSafeRelease( NSObject* obj );
+id performOptionalSelector( id obj, SEL sel );
+
+#if !CATCH_ARC_ENABLED
+inline void arcSafeRelease( NSObject* obj ) {
+ [obj release];
+}
+inline id performOptionalSelector( id obj, SEL sel ) {
+ if( [obj respondsToSelector: sel] )
+ return [obj performSelector: sel];
+ return nil;
+}
+#define CATCH_UNSAFE_UNRETAINED
+#define CATCH_ARC_STRONG
+#else
+inline void arcSafeRelease( NSObject* ){}
+inline id performOptionalSelector( id obj, SEL sel ) {
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
+#endif
+ if( [obj respondsToSelector: sel] )
+ return [obj performSelector: sel];
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+ return nil;
+}
+#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
+#define CATCH_ARC_STRONG __strong
+#endif
+
+// end catch_objc_arc.hpp
+#endif
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
+#endif
+
+// We need a dummy global operator<< so we can bring it into Catch namespace later
+struct Catch_global_namespace_dummy {};
+std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
+
+namespace Catch {
+ // Bring in operator<< from global namespace into Catch namespace
+ using ::operator<<;
+
+ namespace Detail {
+
+ extern const std::string unprintableString;
+
+ std::string rawMemoryToString( const void *object, std::size_t size );
+
+ template<typename T>
+ std::string rawMemoryToString( const T& object ) {
+ return rawMemoryToString( &object, sizeof(object) );
+ }
+
+ template<typename T>
+ class IsStreamInsertable {
+ template<typename SS, typename TT>
+ static auto test(int)
+ -> decltype(std::declval<SS&>() << std::declval<TT>(), std::true_type());
+
+ template<typename, typename>
+ static auto test(...)->std::false_type;
+
+ public:
+ static const bool value = decltype(test<std::ostream, const T&>(0))::value;
+ };
+
+ template<typename E>
+ std::string convertUnknownEnumToString( E e );
+
+ template<typename T>
+ typename std::enable_if<!std::is_enum<T>::value, std::string>::type convertUnstreamable( T const& value ) {
+#if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
+ (void)value;
+ return Detail::unprintableString;
+#else
+ return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
+#endif
+ }
+ template<typename T>
+ typename std::enable_if<std::is_enum<T>::value, std::string>::type convertUnstreamable( T const& value ) {
+ return convertUnknownEnumToString( value );
+ }
+
+#if defined(_MANAGED)
+ //! Convert a CLR string to a utf8 std::string
+ template<typename T>
+ std::string clrReferenceToString( T^ ref ) {
+ if (ref == nullptr)
+ return std::string("null");
+ auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
+ cli::pin_ptr<System::Byte> p = &bytes[0];
+ return std::string(reinterpret_cast<char const *>(p), bytes->Length);
+ }
+#endif
+
+ } // namespace Detail
+
+ // If we decide for C++14, change these to enable_if_ts
+ template <typename T, typename = void>
+ struct StringMaker {
+ template <typename Fake = T>
+ static
+ typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
+ convert(const Fake& value) {
+ ReusableStringStream rss;
+ rss << value;
+ return rss.str();
+ }
+
+ template <typename Fake = T>
+ static
+ typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
+ convert( const Fake& value ) {
+ return Detail::convertUnstreamable( value );
+ }
+ };
+
+ namespace Detail {
+
+ // This function dispatches all stringification requests inside of Catch.
+ // Should be preferably called fully qualified, like ::Catch::Detail::stringify
+ template <typename T>
+ std::string stringify(const T& e) {
+ return ::Catch::StringMaker<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(e);
+ }
+
+ template<typename E>
+ std::string convertUnknownEnumToString( E e ) {
+ return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e));
+ }
+
+#if defined(_MANAGED)
+ template <typename T>
+ std::string stringify( T^ e ) {
+ return ::Catch::StringMaker<T^>::convert(e);
+ }
+#endif
+
+ } // namespace Detail
+
+ // Some predefined specializations
+
+ template<>
+ struct StringMaker<std::string> {
+ static std::string convert(const std::string& str);
+ };
+#ifdef CATCH_CONFIG_WCHAR
+ template<>
+ struct StringMaker<std::wstring> {
+ static std::string convert(const std::wstring& wstr);
+ };
+#endif
+
+ template<>
+ struct StringMaker<char const *> {
+ static std::string convert(char const * str);
+ };
+ template<>
+ struct StringMaker<char *> {
+ static std::string convert(char * str);
+ };
+
+#ifdef CATCH_CONFIG_WCHAR
+ template<>
+ struct StringMaker<wchar_t const *> {
+ static std::string convert(wchar_t const * str);
+ };
+ template<>
+ struct StringMaker<wchar_t *> {
+ static std::string convert(wchar_t * str);
+ };
+#endif
+
+ // TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,
+ // while keeping string semantics?
+ template<int SZ>
+ struct StringMaker<char[SZ]> {
+ static std::string convert(char const* str) {
+ return ::Catch::Detail::stringify(std::string{ str });
+ }
+ };
+ template<int SZ>
+ struct StringMaker<signed char[SZ]> {
+ static std::string convert(signed char const* str) {
+ return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
+ }
+ };
+ template<int SZ>
+ struct StringMaker<unsigned char[SZ]> {
+ static std::string convert(unsigned char const* str) {
+ return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
+ }
+ };
+
+ template<>
+ struct StringMaker<int> {
+ static std::string convert(int value);
+ };
+ template<>
+ struct StringMaker<long> {
+ static std::string convert(long value);
+ };
+ template<>
+ struct StringMaker<long long> {
+ static std::string convert(long long value);
+ };
+ template<>
+ struct StringMaker<unsigned int> {
+ static std::string convert(unsigned int value);
+ };
+ template<>
+ struct StringMaker<unsigned long> {
+ static std::string convert(unsigned long value);
+ };
+ template<>
+ struct StringMaker<unsigned long long> {
+ static std::string convert(unsigned long long value);
+ };
+
+ template<>
+ struct StringMaker<bool> {
+ static std::string convert(bool b);
+ };
+
+ template<>
+ struct StringMaker<char> {
+ static std::string convert(char c);
+ };
+ template<>
+ struct StringMaker<signed char> {
+ static std::string convert(signed char c);
+ };
+ template<>
+ struct StringMaker<unsigned char> {
+ static std::string convert(unsigned char c);
+ };
+
+ template<>
+ struct StringMaker<std::nullptr_t> {
+ static std::string convert(std::nullptr_t);
+ };
+
+ template<>
+ struct StringMaker<float> {
+ static std::string convert(float value);
+ };
+ template<>
+ struct StringMaker<double> {
+ static std::string convert(double value);
+ };
+
+ template <typename T>
+ struct StringMaker<T*> {
+ template <typename U>
+ static std::string convert(U* p) {
+ if (p) {
+ return ::Catch::Detail::rawMemoryToString(p);
+ } else {
+ return "nullptr";
+ }
+ }
+ };
+
+ template <typename R, typename C>
+ struct StringMaker<R C::*> {
+ static std::string convert(R C::* p) {
+ if (p) {
+ return ::Catch::Detail::rawMemoryToString(p);
+ } else {
+ return "nullptr";
+ }
+ }
+ };
+
+#if defined(_MANAGED)
+ template <typename T>
+ struct StringMaker<T^> {
+ static std::string convert( T^ ref ) {
+ return ::Catch::Detail::clrReferenceToString(ref);
+ }
+ };
+#endif
+
+ namespace Detail {
+ template<typename InputIterator>
+ std::string rangeToString(InputIterator first, InputIterator last) {
+ ReusableStringStream rss;
+ rss << "{ ";
+ if (first != last) {
+ rss << ::Catch::Detail::stringify(*first);
+ for (++first; first != last; ++first)
+ rss << ", " << ::Catch::Detail::stringify(*first);
+ }
+ rss << " }";
+ return rss.str();
+ }
+ }
+
+#ifdef __OBJC__
+ template<>
+ struct StringMaker<NSString*> {
+ static std::string convert(NSString * nsstring) {
+ if (!nsstring)
+ return "nil";
+ return std::string("@") + [nsstring UTF8String];
+ }
+ };
+ template<>
+ struct StringMaker<NSObject*> {
+ static std::string convert(NSObject* nsObject) {
+ return ::Catch::Detail::stringify([nsObject description]);
+ }
+
+ };
+ namespace Detail {
+ inline std::string stringify( NSString* nsstring ) {
+ return StringMaker<NSString*>::convert( nsstring );
+ }
+
+ } // namespace Detail
+#endif // __OBJC__
+
+} // namespace Catch
+
+//////////////////////////////////////////////////////
+// Separate std-lib types stringification, so it can be selectively enabled
+// This means that we do not bring in
+
+#if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
+# define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
+# define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
+# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
+#endif
+
+// Separate std::pair specialization
+#if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
+#include <utility>
+namespace Catch {
+ template<typename T1, typename T2>
+ struct StringMaker<std::pair<T1, T2> > {
+ static std::string convert(const std::pair<T1, T2>& pair) {
+ ReusableStringStream rss;
+ rss << "{ "
+ << ::Catch::Detail::stringify(pair.first)
+ << ", "
+ << ::Catch::Detail::stringify(pair.second)
+ << " }";
+ return rss.str();
+ }
+ };
+}
+#endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
+
+// Separate std::tuple specialization
+#if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
+#include <tuple>
+namespace Catch {
+ namespace Detail {
+ template<
+ typename Tuple,
+ std::size_t N = 0,
+ bool = (N < std::tuple_size<Tuple>::value)
+ >
+ struct TupleElementPrinter {
+ static void print(const Tuple& tuple, std::ostream& os) {
+ os << (N ? ", " : " ")
+ << ::Catch::Detail::stringify(std::get<N>(tuple));
+ TupleElementPrinter<Tuple, N + 1>::print(tuple, os);
+ }
+ };
+
+ template<
+ typename Tuple,
+ std::size_t N
+ >
+ struct TupleElementPrinter<Tuple, N, false> {
+ static void print(const Tuple&, std::ostream&) {}
+ };
+
+ }
+
+ template<typename ...Types>
+ struct StringMaker<std::tuple<Types...>> {
+ static std::string convert(const std::tuple<Types...>& tuple) {
+ ReusableStringStream rss;
+ rss << '{';
+ Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());
+ rss << " }";
+ return rss.str();
+ }
+ };
+}
+#endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
+
+namespace Catch {
+ struct not_this_one {}; // Tag type for detecting which begin/ end are being selected
+
+ // Import begin/ end from std here so they are considered alongside the fallback (...) overloads in this namespace
+ using std::begin;
+ using std::end;
+
+ not_this_one begin( ... );
+ not_this_one end( ... );
+
+ template <typename T>
+ struct is_range {
+ static const bool value =
+ !std::is_same<decltype(begin(std::declval<T>())), not_this_one>::value &&
+ !std::is_same<decltype(end(std::declval<T>())), not_this_one>::value;
+ };
+
+#if defined(_MANAGED) // Managed types are never ranges
+ template <typename T>
+ struct is_range<T^> {
+ static const bool value = false;
+ };
+#endif
+
+ template<typename Range>
+ std::string rangeToString( Range const& range ) {
+ return ::Catch::Detail::rangeToString( begin( range ), end( range ) );
+ }
+
+ // Handle vector<bool> specially
+ template<typename Allocator>
+ std::string rangeToString( std::vector<bool, Allocator> const& v ) {
+ ReusableStringStream rss;
+ rss << "{ ";
+ bool first = true;
+ for( bool b : v ) {
+ if( first )
+ first = false;
+ else
+ rss << ", ";
+ rss << ::Catch::Detail::stringify( b );
+ }
+ rss << " }";
+ return rss.str();
+ }
+
+ template<typename R>
+ struct StringMaker<R, typename std::enable_if<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>::type> {
+ static std::string convert( R const& range ) {
+ return rangeToString( range );
+ }
+ };
+
+ template <typename T, int SZ>
+ struct StringMaker<T[SZ]> {
+ static std::string convert(T const(&arr)[SZ]) {
+ return rangeToString(arr);
+ }
+ };
+
+} // namespace Catch
+
+// Separate std::chrono::duration specialization
+#if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
+#include <ctime>
+#include <ratio>
+#include <chrono>
+
+namespace Catch {
+
+template <class Ratio>
+struct ratio_string {
+ static std::string symbol();
+};
+
+template <class Ratio>
+std::string ratio_string<Ratio>::symbol() {
+ Catch::ReusableStringStream rss;
+ rss << '[' << Ratio::num << '/'
+ << Ratio::den << ']';
+ return rss.str();
+}
+template <>
+struct ratio_string<std::atto> {
+ static std::string symbol();
+};
+template <>
+struct ratio_string<std::femto> {
+ static std::string symbol();
+};
+template <>
+struct ratio_string<std::pico> {
+ static std::string symbol();
+};
+template <>
+struct ratio_string<std::nano> {
+ static std::string symbol();
+};
+template <>
+struct ratio_string<std::micro> {
+ static std::string symbol();
+};
+template <>
+struct ratio_string<std::milli> {
+ static std::string symbol();
+};
+
+ ////////////
+ // std::chrono::duration specializations
+ template<typename Value, typename Ratio>
+ struct StringMaker<std::chrono::duration<Value, Ratio>> {
+ static std::string convert(std::chrono::duration<Value, Ratio> const& duration) {
+ ReusableStringStream rss;
+ rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
+ return rss.str();
+ }
+ };
+ template<typename Value>
+ struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
+ static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) {
+ ReusableStringStream rss;
+ rss << duration.count() << " s";
+ return rss.str();
+ }
+ };
+ template<typename Value>
+ struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
+ static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) {
+ ReusableStringStream rss;
+ rss << duration.count() << " m";
+ return rss.str();
+ }
+ };
+ template<typename Value>
+ struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
+ static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) {
+ ReusableStringStream rss;
+ rss << duration.count() << " h";
+ return rss.str();
+ }
+ };
+
+ ////////////
+ // std::chrono::time_point specialization
+ // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>
+ template<typename Clock, typename Duration>
+ struct StringMaker<std::chrono::time_point<Clock, Duration>> {
+ static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) {
+ return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
+ }
+ };
+ // std::chrono::time_point<system_clock> specialization
+ template<typename Duration>
+ struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
+ static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) {
+ auto converted = std::chrono::system_clock::to_time_t(time_point);
+
+#ifdef _MSC_VER
+ std::tm timeInfo = {};
+ gmtime_s(&timeInfo, &converted);
+#else
+ std::tm* timeInfo = std::gmtime(&converted);
+#endif
+
+ auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
+ char timeStamp[timeStampSize];
+ const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
+
+#ifdef _MSC_VER
+ std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
+#else
+ std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
+#endif
+ return std::string(timeStamp);
+ }
+ };
+}
+#endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+// end catch_tostring.h
+#include <iosfwd>
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4389) // '==' : signed/unsigned mismatch
+#pragma warning(disable:4018) // more "signed/unsigned mismatch"
+#pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
+#pragma warning(disable:4180) // qualifier applied to function type has no meaning
+#endif
+
+namespace Catch {
+
+ struct ITransientExpression {
+ auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
+ auto getResult() const -> bool { return m_result; }
+ virtual void streamReconstructedExpression( std::ostream &os ) const = 0;
+
+ ITransientExpression( bool isBinaryExpression, bool result )
+ : m_isBinaryExpression( isBinaryExpression ),
+ m_result( result )
+ {}
+
+ // We don't actually need a virtual destructor, but many static analysers
+ // complain if it's not here :-(
+ virtual ~ITransientExpression();
+
+ bool m_isBinaryExpression;
+ bool m_result;
+
+ };
+
+ void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );
+
+ template<typename LhsT, typename RhsT>
+ class BinaryExpr : public ITransientExpression {
+ LhsT m_lhs;
+ StringRef m_op;
+ RhsT m_rhs;
+
+ void streamReconstructedExpression( std::ostream &os ) const override {
+ formatReconstructedExpression
+ ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) );
+ }
+
+ public:
+ BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
+ : ITransientExpression{ true, comparisonResult },
+ m_lhs( lhs ),
+ m_op( op ),
+ m_rhs( rhs )
+ {}
+ };
+
+ template<typename LhsT>
+ class UnaryExpr : public ITransientExpression {
+ LhsT m_lhs;
+
+ void streamReconstructedExpression( std::ostream &os ) const override {
+ os << Catch::Detail::stringify( m_lhs );
+ }
+
+ public:
+ explicit UnaryExpr( LhsT lhs )
+ : ITransientExpression{ false, lhs ? true : false },
+ m_lhs( lhs )
+ {}
+ };
+
+ // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
+ template<typename LhsT, typename RhsT>
+ auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast<bool>(lhs == rhs); }
+ template<typename T>
+ auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
+ template<typename T>
+ auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
+ template<typename T>
+ auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
+ template<typename T>
+ auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
+
+ template<typename LhsT, typename RhsT>
+ auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); }
+ template<typename T>
+ auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
+ template<typename T>
+ auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
+ template<typename T>
+ auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
+ template<typename T>
+ auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
+
+ template<typename LhsT>
+ class ExprLhs {
+ LhsT m_lhs;
+ public:
+ explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
+
+ template<typename RhsT>
+ auto operator == ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
+ return { compareEqual( m_lhs, rhs ), m_lhs, "==", rhs };
+ }
+ auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
+ return { m_lhs == rhs, m_lhs, "==", rhs };
+ }
+
+ template<typename RhsT>
+ auto operator != ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
+ return { compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs };
+ }
+ auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
+ return { m_lhs != rhs, m_lhs, "!=", rhs };
+ }
+
+ template<typename RhsT>
+ auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
+ return { static_cast<bool>(m_lhs > rhs), m_lhs, ">", rhs };
+ }
+ template<typename RhsT>
+ auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
+ return { static_cast<bool>(m_lhs < rhs), m_lhs, "<", rhs };
+ }
+ template<typename RhsT>
+ auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
+ return { static_cast<bool>(m_lhs >= rhs), m_lhs, ">=", rhs };
+ }
+ template<typename RhsT>
+ auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
+ return { static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs };
+ }
+
+ auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
+ return UnaryExpr<LhsT>{ m_lhs };
+ }
+ };
+
+ void handleExpression( ITransientExpression const& expr );
+
+ template<typename T>
+ void handleExpression( ExprLhs<T> const& expr ) {
+ handleExpression( expr.makeUnaryExpr() );
+ }
+
+ struct Decomposer {
+ template<typename T>
+ auto operator <= ( T const& lhs ) -> ExprLhs<T const&> {
+ return ExprLhs<T const&>{ lhs };
+ }
+
+ auto operator <=( bool value ) -> ExprLhs<bool> {
+ return ExprLhs<bool>{ value };
+ }
+ };
+
+} // end namespace Catch
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+// end catch_decomposer.h
+// start catch_interfaces_capture.h
+
+#include <string>
+
+namespace Catch {
+
+ class AssertionResult;
+ struct AssertionInfo;
+ struct SectionInfo;
+ struct SectionEndInfo;
+ struct MessageInfo;
+ struct Counts;
+ struct BenchmarkInfo;
+ struct BenchmarkStats;
+ struct AssertionReaction;
+
+ struct ITransientExpression;
+
+ struct IResultCapture {
+
+ virtual ~IResultCapture();
+
+ virtual bool sectionStarted( SectionInfo const& sectionInfo,
+ Counts& assertions ) = 0;
+ virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
+ virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
+
+ virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
+ virtual void benchmarkEnded( BenchmarkStats const& stats ) = 0;
+
+ virtual void pushScopedMessage( MessageInfo const& message ) = 0;
+ virtual void popScopedMessage( MessageInfo const& message ) = 0;
+
+ virtual void handleFatalErrorCondition( StringRef message ) = 0;
+
+ virtual void handleExpr
+ ( AssertionInfo const& info,
+ ITransientExpression const& expr,
+ AssertionReaction& reaction ) = 0;
+ virtual void handleMessage
+ ( AssertionInfo const& info,
+ ResultWas::OfType resultType,
+ StringRef const& message,
+ AssertionReaction& reaction ) = 0;
+ virtual void handleUnexpectedExceptionNotThrown
+ ( AssertionInfo const& info,
+ AssertionReaction& reaction ) = 0;
+ virtual void handleUnexpectedInflightException
+ ( AssertionInfo const& info,
+ std::string const& message,
+ AssertionReaction& reaction ) = 0;
+ virtual void handleIncomplete
+ ( AssertionInfo const& info ) = 0;
+ virtual void handleNonExpr
+ ( AssertionInfo const &info,
+ ResultWas::OfType resultType,
+ AssertionReaction &reaction ) = 0;
+
+ virtual bool lastAssertionPassed() = 0;
+ virtual void assertionPassed() = 0;
+
+ // Deprecated, do not use:
+ virtual std::string getCurrentTestName() const = 0;
+ virtual const AssertionResult* getLastResult() const = 0;
+ virtual void exceptionEarlyReported() = 0;
+ };
+
+ IResultCapture& getResultCapture();
+}
+
+// end catch_interfaces_capture.h
+namespace Catch {
+
+ struct TestFailureException{};
+ struct AssertionResultData;
+ struct IResultCapture;
+ class RunContext;
+
+ class LazyExpression {
+ friend class AssertionHandler;
+ friend struct AssertionStats;
+ friend class RunContext;
+
+ ITransientExpression const* m_transientExpression = nullptr;
+ bool m_isNegated;
+ public:
+ LazyExpression( bool isNegated );
+ LazyExpression( LazyExpression const& other );
+ LazyExpression& operator = ( LazyExpression const& ) = delete;
+
+ explicit operator bool() const;
+
+ friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&;
+ };
+
+ struct AssertionReaction {
+ bool shouldDebugBreak = false;
+ bool shouldThrow = false;
+ };
+
+ class AssertionHandler {
+ AssertionInfo m_assertionInfo;
+ AssertionReaction m_reaction;
+ bool m_completed = false;
+ IResultCapture& m_resultCapture;
+
+ public:
+ AssertionHandler
+ ( StringRef macroName,
+ SourceLineInfo const& lineInfo,
+ StringRef capturedExpression,
+ ResultDisposition::Flags resultDisposition );
+ ~AssertionHandler() {
+ if ( !m_completed ) {
+ m_resultCapture.handleIncomplete( m_assertionInfo );
+ }
+ }
+
+ template<typename T>
+ void handleExpr( ExprLhs<T> const& expr ) {
+ handleExpr( expr.makeUnaryExpr() );
+ }
+ void handleExpr( ITransientExpression const& expr );
+
+ void handleMessage(ResultWas::OfType resultType, StringRef const& message);
+
+ void handleExceptionThrownAsExpected();
+ void handleUnexpectedExceptionNotThrown();
+ void handleExceptionNotThrownAsExpected();
+ void handleThrowingCallSkipped();
+ void handleUnexpectedInflightException();
+
+ void complete();
+ void setCompleted();
+
+ // query
+ auto allowThrows() const -> bool;
+ };
+
+ void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef matcherString );
+
+} // namespace Catch
+
+// end catch_assertionhandler.h
+// start catch_message.h
+
+#include <string>
+
+namespace Catch {
+
+ struct MessageInfo {
+ MessageInfo( std::string const& _macroName,
+ SourceLineInfo const& _lineInfo,
+ ResultWas::OfType _type );
+
+ std::string macroName;
+ std::string message;
+ SourceLineInfo lineInfo;
+ ResultWas::OfType type;
+ unsigned int sequence;
+
+ bool operator == ( MessageInfo const& other ) const;
+ bool operator < ( MessageInfo const& other ) const;
+ private:
+ static unsigned int globalCount;
+ };
+
+ struct MessageStream {
+
+ template<typename T>
+ MessageStream& operator << ( T const& value ) {
+ m_stream << value;
+ return *this;
+ }
+
+ ReusableStringStream m_stream;
+ };
+
+ struct MessageBuilder : MessageStream {
+ MessageBuilder( std::string const& macroName,
+ SourceLineInfo const& lineInfo,
+ ResultWas::OfType type );
+
+ template<typename T>
+ MessageBuilder& operator << ( T const& value ) {
+ m_stream << value;
+ return *this;
+ }
+
+ MessageInfo m_info;
+ };
+
+ class ScopedMessage {
+ public:
+ explicit ScopedMessage( MessageBuilder const& builder );
+ ~ScopedMessage();
+
+ MessageInfo m_info;
+ };
+
+} // end namespace Catch
+
+// end catch_message.h
+#if !defined(CATCH_CONFIG_DISABLE)
+
+#if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
+ #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__
+#else
+ #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
+#endif
+
+#if defined(CATCH_CONFIG_FAST_COMPILE)
+
+///////////////////////////////////////////////////////////////////////////////
+// Another way to speed-up compilation is to omit local try-catch for REQUIRE*
+// macros.
+#define INTERNAL_CATCH_TRY
+#define INTERNAL_CATCH_CATCH( capturer )
+
+#else // CATCH_CONFIG_FAST_COMPILE
+
+#define INTERNAL_CATCH_TRY try
+#define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); }
+
+#endif
+
+#define INTERNAL_CATCH_REACT( handler ) handler.complete();
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
+ do { \
+ Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
+ INTERNAL_CATCH_TRY { \
+ CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
+ catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
+ CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
+ } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
+ INTERNAL_CATCH_REACT( catchAssertionHandler ) \
+ } while( (void)0, false && static_cast<bool>( !!(__VA_ARGS__) ) ) // the expression here is never evaluated at runtime but it forces the compiler to give it a look
+ // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
+ INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
+ if( Catch::getResultCapture().lastAssertionPassed() )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \
+ INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
+ if( !Catch::getResultCapture().lastAssertionPassed() )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
+ do { \
+ Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
+ try { \
+ static_cast<void>(__VA_ARGS__); \
+ catchAssertionHandler.handleExceptionNotThrownAsExpected(); \
+ } \
+ catch( ... ) { \
+ catchAssertionHandler.handleUnexpectedInflightException(); \
+ } \
+ INTERNAL_CATCH_REACT( catchAssertionHandler ) \
+ } while( false )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
+ do { \
+ Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
+ if( catchAssertionHandler.allowThrows() ) \
+ try { \
+ static_cast<void>(__VA_ARGS__); \
+ catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
+ } \
+ catch( ... ) { \
+ catchAssertionHandler.handleExceptionThrownAsExpected(); \
+ } \
+ else \
+ catchAssertionHandler.handleThrowingCallSkipped(); \
+ INTERNAL_CATCH_REACT( catchAssertionHandler ) \
+ } while( false )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
+ do { \
+ Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
+ if( catchAssertionHandler.allowThrows() ) \
+ try { \
+ static_cast<void>(expr); \
+ catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
+ } \
+ catch( exceptionType const& ) { \
+ catchAssertionHandler.handleExceptionThrownAsExpected(); \
+ } \
+ catch( ... ) { \
+ catchAssertionHandler.handleUnexpectedInflightException(); \
+ } \
+ else \
+ catchAssertionHandler.handleThrowingCallSkipped(); \
+ INTERNAL_CATCH_REACT( catchAssertionHandler ) \
+ } while( false )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
+ do { \
+ Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
+ catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
+ INTERNAL_CATCH_REACT( catchAssertionHandler ) \
+ } while( false )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_INFO( macroName, log ) \
+ Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );
+
+///////////////////////////////////////////////////////////////////////////////
+// Although this is matcher-based, it can be used with just a string
+#define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
+ do { \
+ Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
+ if( catchAssertionHandler.allowThrows() ) \
+ try { \
+ static_cast<void>(__VA_ARGS__); \
+ catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
+ } \
+ catch( ... ) { \
+ Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher ); \
+ } \
+ else \
+ catchAssertionHandler.handleThrowingCallSkipped(); \
+ INTERNAL_CATCH_REACT( catchAssertionHandler ) \
+ } while( false )
+
+#endif // CATCH_CONFIG_DISABLE
+
+// end catch_capture.hpp
+// start catch_section.h
+
+// start catch_section_info.h
+
+// start catch_totals.h
+
+#include <cstddef>
+
+namespace Catch {
+
+ struct Counts {
+ Counts operator - ( Counts const& other ) const;
+ Counts& operator += ( Counts const& other );
+
+ std::size_t total() const;
+ bool allPassed() const;
+ bool allOk() const;
+
+ std::size_t passed = 0;
+ std::size_t failed = 0;
+ std::size_t failedButOk = 0;
+ };
+
+ struct Totals {
+
+ Totals operator - ( Totals const& other ) const;
+ Totals& operator += ( Totals const& other );
+
+ Totals delta( Totals const& prevTotals ) const;
+
+ int error = 0;
+ Counts assertions;
+ Counts testCases;
+ };
+}
+
+// end catch_totals.h
+#include <string>
+
+namespace Catch {
+
+ struct SectionInfo {
+ SectionInfo
+ ( SourceLineInfo const& _lineInfo,
+ std::string const& _name,
+ std::string const& _description = std::string() );
+
+ std::string name;
+ std::string description;
+ SourceLineInfo lineInfo;
+ };
+
+ struct SectionEndInfo {
+ SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds );
+
+ SectionInfo sectionInfo;
+ Counts prevAssertions;
+ double durationInSeconds;
+ };
+
+} // end namespace Catch
+
+// end catch_section_info.h
+// start catch_timer.h
+
+#include <cstdint>
+
+namespace Catch {
+
+ auto getCurrentNanosecondsSinceEpoch() -> uint64_t;
+ auto getEstimatedClockResolution() -> uint64_t;
+
+ class Timer {
+ uint64_t m_nanoseconds = 0;
+ public:
+ void start();
+ auto getElapsedNanoseconds() const -> uint64_t;
+ auto getElapsedMicroseconds() const -> uint64_t;
+ auto getElapsedMilliseconds() const -> unsigned int;
+ auto getElapsedSeconds() const -> double;
+ };
+
+} // namespace Catch
+
+// end catch_timer.h
+#include <string>
+
+namespace Catch {
+
+ class Section : NonCopyable {
+ public:
+ Section( SectionInfo const& info );
+ ~Section();
+
+ // This indicates whether the section should be executed or not
+ explicit operator bool() const;
+
+ private:
+ SectionInfo m_info;
+
+ std::string m_name;
+ Counts m_assertions;
+ bool m_sectionIncluded;
+ Timer m_timer;
+ };
+
+} // end namespace Catch
+
+ #define INTERNAL_CATCH_SECTION( ... ) \
+ if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
+
+// end catch_section.h
+// start catch_benchmark.h
+
+#include <cstdint>
+#include <string>
+
+namespace Catch {
+
+ class BenchmarkLooper {
+
+ std::string m_name;
+ std::size_t m_count = 0;
+ std::size_t m_iterationsToRun = 1;
+ uint64_t m_resolution;
+ Timer m_timer;
+
+ static auto getResolution() -> uint64_t;
+ public:
+ // Keep most of this inline as it's on the code path that is being timed
+ BenchmarkLooper( StringRef name )
+ : m_name( name ),
+ m_resolution( getResolution() )
+ {
+ reportStart();
+ m_timer.start();
+ }
+
+ explicit operator bool() {
+ if( m_count < m_iterationsToRun )
+ return true;
+ return needsMoreIterations();
+ }
+
+ void increment() {
+ ++m_count;
+ }
+
+ void reportStart();
+ auto needsMoreIterations() -> bool;
+ };
+
+} // end namespace Catch
+
+#define BENCHMARK( name ) \
+ for( Catch::BenchmarkLooper looper( name ); looper; looper.increment() )
+
+// end catch_benchmark.h
+// start catch_interfaces_exception.h
+
+// start catch_interfaces_registry_hub.h
+
+#include <string>
+#include <memory>
+
+namespace Catch {
+
+ class TestCase;
+ struct ITestCaseRegistry;
+ struct IExceptionTranslatorRegistry;
+ struct IExceptionTranslator;
+ struct IReporterRegistry;
+ struct IReporterFactory;
+ struct ITagAliasRegistry;
+ class StartupExceptionRegistry;
+
+ using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
+
+ struct IRegistryHub {
+ virtual ~IRegistryHub();
+
+ virtual IReporterRegistry const& getReporterRegistry() const = 0;
+ virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
+ virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
+
+ virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
+
+ virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;
+ };
+
+ struct IMutableRegistryHub {
+ virtual ~IMutableRegistryHub();
+ virtual void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) = 0;
+ virtual void registerListener( IReporterFactoryPtr const& factory ) = 0;
+ virtual void registerTest( TestCase const& testInfo ) = 0;
+ virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
+ virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;
+ virtual void registerStartupException() noexcept = 0;
+ };
+
+ IRegistryHub& getRegistryHub();
+ IMutableRegistryHub& getMutableRegistryHub();
+ void cleanUp();
+ std::string translateActiveException();
+
+}
+
+// end catch_interfaces_registry_hub.h
+#if defined(CATCH_CONFIG_DISABLE)
+ #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \
+ static std::string translatorName( signature )
+#endif
+
+#include <exception>
+#include <string>
+#include <vector>
+
+namespace Catch {
+ using exceptionTranslateFunction = std::string(*)();
+
+ struct IExceptionTranslator;
+ using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>;
+
+ struct IExceptionTranslator {
+ virtual ~IExceptionTranslator();
+ virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
+ };
+
+ struct IExceptionTranslatorRegistry {
+ virtual ~IExceptionTranslatorRegistry();
+
+ virtual std::string translateActiveException() const = 0;
+ };
+
+ class ExceptionTranslatorRegistrar {
+ template<typename T>
+ class ExceptionTranslator : public IExceptionTranslator {
+ public:
+
+ ExceptionTranslator( std::string(*translateFunction)( T& ) )
+ : m_translateFunction( translateFunction )
+ {}
+
+ std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override {
+ try {
+ if( it == itEnd )
+ std::rethrow_exception(std::current_exception());
+ else
+ return (*it)->translate( it+1, itEnd );
+ }
+ catch( T& ex ) {
+ return m_translateFunction( ex );
+ }
+ }
+
+ protected:
+ std::string(*m_translateFunction)( T& );
+ };
+
+ public:
+ template<typename T>
+ ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
+ getMutableRegistryHub().registerTranslator
+ ( new ExceptionTranslator<T>( translateFunction ) );
+ }
+ };
+}
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
+ static std::string translatorName( signature ); \
+ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+ namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \
+ CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
+ static std::string translatorName( signature )
+
+#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
+
+// end catch_interfaces_exception.h
+// start catch_approx.h
+
+#include <type_traits>
+#include <stdexcept>
+
+namespace Catch {
+namespace Detail {
+
+ class Approx {
+ private:
+ bool equalityComparisonImpl(double other) const;
+
+ public:
+ explicit Approx ( double value );
+
+ static Approx custom();
+
+ template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+ Approx operator()( T const& value ) {
+ Approx approx( static_cast<double>(value) );
+ approx.epsilon( m_epsilon );
+ approx.margin( m_margin );
+ approx.scale( m_scale );
+ return approx;
+ }
+
+ template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+ explicit Approx( T const& value ): Approx(static_cast<double>(value))
+ {}
+
+ template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+ friend bool operator == ( const T& lhs, Approx const& rhs ) {
+ auto lhs_v = static_cast<double>(lhs);
+ return rhs.equalityComparisonImpl(lhs_v);
+ }
+
+ template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+ friend bool operator == ( Approx const& lhs, const T& rhs ) {
+ return operator==( rhs, lhs );
+ }
+
+ template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+ friend bool operator != ( T const& lhs, Approx const& rhs ) {
+ return !operator==( lhs, rhs );
+ }
+
+ template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+ friend bool operator != ( Approx const& lhs, T const& rhs ) {
+ return !operator==( rhs, lhs );
+ }
+
+ template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+ friend bool operator <= ( T const& lhs, Approx const& rhs ) {
+ return static_cast<double>(lhs) < rhs.m_value || lhs == rhs;
+ }
+
+ template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+ friend bool operator <= ( Approx const& lhs, T const& rhs ) {
+ return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;
+ }
+
+ template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+ friend bool operator >= ( T const& lhs, Approx const& rhs ) {
+ return static_cast<double>(lhs) > rhs.m_value || lhs == rhs;
+ }
+
+ template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+ friend bool operator >= ( Approx const& lhs, T const& rhs ) {
+ return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;
+ }
+
+ template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+ Approx& epsilon( T const& newEpsilon ) {
+ double epsilonAsDouble = static_cast<double>(newEpsilon);
+ if( epsilonAsDouble < 0 || epsilonAsDouble > 1.0 ) {
+ throw std::domain_error
+ ( "Invalid Approx::epsilon: " +
+ Catch::Detail::stringify( epsilonAsDouble ) +
+ ", Approx::epsilon has to be between 0 and 1" );
+ }
+ m_epsilon = epsilonAsDouble;
+ return *this;
+ }
+
+ template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+ Approx& margin( T const& newMargin ) {
+ double marginAsDouble = static_cast<double>(newMargin);
+ if( marginAsDouble < 0 ) {
+ throw std::domain_error
+ ( "Invalid Approx::margin: " +
+ Catch::Detail::stringify( marginAsDouble ) +
+ ", Approx::Margin has to be non-negative." );
+
+ }
+ m_margin = marginAsDouble;
+ return *this;
+ }
+
+ template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+ Approx& scale( T const& newScale ) {
+ m_scale = static_cast<double>(newScale);
+ return *this;
+ }
+
+ std::string toString() const;
+
+ private:
+ double m_epsilon;
+ double m_margin;
+ double m_scale;
+ double m_value;
+ };
+}
+
+template<>
+struct StringMaker<Catch::Detail::Approx> {
+ static std::string convert(Catch::Detail::Approx const& value);
+};
+
+} // end namespace Catch
+
+// end catch_approx.h
+// start catch_string_manip.h
+
+#include <string>
+#include <iosfwd>
+
+namespace Catch {
+
+ bool startsWith( std::string const& s, std::string const& prefix );
+ bool startsWith( std::string const& s, char prefix );
+ bool endsWith( std::string const& s, std::string const& suffix );
+ bool endsWith( std::string const& s, char suffix );
+ bool contains( std::string const& s, std::string const& infix );
+ void toLowerInPlace( std::string& s );
+ std::string toLower( std::string const& s );
+ std::string trim( std::string const& str );
+ bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
+
+ struct pluralise {
+ pluralise( std::size_t count, std::string const& label );
+
+ friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
+
+ std::size_t m_count;
+ std::string m_label;
+ };
+}
+
+// end catch_string_manip.h
+#ifndef CATCH_CONFIG_DISABLE_MATCHERS
+// start catch_capture_matchers.h
+
+// start catch_matchers.h
+
+#include <string>
+#include <vector>
+
+namespace Catch {
+namespace Matchers {
+ namespace Impl {
+
+ template<typename ArgT> struct MatchAllOf;
+ template<typename ArgT> struct MatchAnyOf;
+ template<typename ArgT> struct MatchNotOf;
+
+ class MatcherUntypedBase {
+ public:
+ MatcherUntypedBase() = default;
+ MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
+ MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = delete;
+ std::string toString() const;
+
+ protected:
+ virtual ~MatcherUntypedBase();
+ virtual std::string describe() const = 0;
+ mutable std::string m_cachedToString;
+ };
+
+ template<typename ObjectT>
+ struct MatcherMethod {
+ virtual bool match( ObjectT const& arg ) const = 0;
+ };
+ template<typename PtrT>
+ struct MatcherMethod<PtrT*> {
+ virtual bool match( PtrT* arg ) const = 0;
+ };
+
+ template<typename T>
+ struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
+
+ MatchAllOf<T> operator && ( MatcherBase const& other ) const;
+ MatchAnyOf<T> operator || ( MatcherBase const& other ) const;
+ MatchNotOf<T> operator ! () const;
+ };
+
+ template<typename ArgT>
+ struct MatchAllOf : MatcherBase<ArgT> {
+ bool match( ArgT const& arg ) const override {
+ for( auto matcher : m_matchers ) {
+ if (!matcher->match(arg))
+ return false;
+ }
+ return true;
+ }
+ std::string describe() const override {
+ std::string description;
+ description.reserve( 4 + m_matchers.size()*32 );
+ description += "( ";
+ bool first = true;
+ for( auto matcher : m_matchers ) {
+ if( first )
+ first = false;
+ else
+ description += " and ";
+ description += matcher->toString();
+ }
+ description += " )";
+ return description;
+ }
+
+ MatchAllOf<ArgT>& operator && ( MatcherBase<ArgT> const& other ) {
+ m_matchers.push_back( &other );
+ return *this;
+ }
+
+ std::vector<MatcherBase<ArgT> const*> m_matchers;
+ };
+ template<typename ArgT>
+ struct MatchAnyOf : MatcherBase<ArgT> {
+
+ bool match( ArgT const& arg ) const override {
+ for( auto matcher : m_matchers ) {
+ if (matcher->match(arg))
+ return true;
+ }
+ return false;
+ }
+ std::string describe() const override {
+ std::string description;
+ description.reserve( 4 + m_matchers.size()*32 );
+ description += "( ";
+ bool first = true;
+ for( auto matcher : m_matchers ) {
+ if( first )
+ first = false;
+ else
+ description += " or ";
+ description += matcher->toString();
+ }
+ description += " )";
+ return description;
+ }
+
+ MatchAnyOf<ArgT>& operator || ( MatcherBase<ArgT> const& other ) {
+ m_matchers.push_back( &other );
+ return *this;
+ }
+
+ std::vector<MatcherBase<ArgT> const*> m_matchers;
+ };
+
+ template<typename ArgT>
+ struct MatchNotOf : MatcherBase<ArgT> {
+
+ MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}
+
+ bool match( ArgT const& arg ) const override {
+ return !m_underlyingMatcher.match( arg );
+ }
+
+ std::string describe() const override {
+ return "not " + m_underlyingMatcher.toString();
+ }
+ MatcherBase<ArgT> const& m_underlyingMatcher;
+ };
+
+ template<typename T>
+ MatchAllOf<T> MatcherBase<T>::operator && ( MatcherBase const& other ) const {
+ return MatchAllOf<T>() && *this && other;
+ }
+ template<typename T>
+ MatchAnyOf<T> MatcherBase<T>::operator || ( MatcherBase const& other ) const {
+ return MatchAnyOf<T>() || *this || other;
+ }
+ template<typename T>
+ MatchNotOf<T> MatcherBase<T>::operator ! () const {
+ return MatchNotOf<T>( *this );
+ }
+
+ } // namespace Impl
+
+} // namespace Matchers
+
+using namespace Matchers;
+using Matchers::Impl::MatcherBase;
+
+} // namespace Catch
+
+// end catch_matchers.h
+// start catch_matchers_floating.h
+
+#include <type_traits>
+#include <cmath>
+
+namespace Catch {
+namespace Matchers {
+
+ namespace Floating {
+
+ enum class FloatingPointKind : uint8_t;
+
+ struct WithinAbsMatcher : MatcherBase<double> {
+ WithinAbsMatcher(double target, double margin);
+ bool match(double const& matchee) const override;
+ std::string describe() const override;
+ private:
+ double m_target;
+ double m_margin;
+ };
+
+ struct WithinUlpsMatcher : MatcherBase<double> {
+ WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType);
+ bool match(double const& matchee) const override;
+ std::string describe() const override;
+ private:
+ double m_target;
+ int m_ulps;
+ FloatingPointKind m_type;
+ };
+
+ } // namespace Floating
+
+ // The following functions create the actual matcher objects.
+ // This allows the types to be inferred
+ Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff);
+ Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff);
+ Floating::WithinAbsMatcher WithinAbs(double target, double margin);
+
+} // namespace Matchers
+} // namespace Catch
+
+// end catch_matchers_floating.h
+// start catch_matchers_generic.hpp
+
+#include <functional>
+#include <string>
+
+namespace Catch {
+namespace Matchers {
+namespace Generic {
+
+namespace Detail {
+ std::string finalizeDescription(const std::string& desc);
+}
+
+template <typename T>
+class PredicateMatcher : public MatcherBase<T> {
+ std::function<bool(T const&)> m_predicate;
+ std::string m_description;
+public:
+
+ PredicateMatcher(std::function<bool(T const&)> const& elem, std::string const& descr)
+ :m_predicate(std::move(elem)),
+ m_description(Detail::finalizeDescription(descr))
+ {}
+
+ bool match( T const& item ) const override {
+ return m_predicate(item);
+ }
+
+ std::string describe() const override {
+ return m_description;
+ }
+};
+
+} // namespace Generic
+
+ // The following functions create the actual matcher objects.
+ // The user has to explicitly specify type to the function, because
+ // infering std::function<bool(T const&)> is hard (but possible) and
+ // requires a lot of TMP.
+ template<typename T>
+ Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate, std::string const& description = "") {
+ return Generic::PredicateMatcher<T>(predicate, description);
+ }
+
+} // namespace Matchers
+} // namespace Catch
+
+// end catch_matchers_generic.hpp
+// start catch_matchers_string.h
+
+#include <string>
+
+namespace Catch {
+namespace Matchers {
+
+ namespace StdString {
+
+ struct CasedString
+ {
+ CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity );
+ std::string adjustString( std::string const& str ) const;
+ std::string caseSensitivitySuffix() const;
+
+ CaseSensitive::Choice m_caseSensitivity;
+ std::string m_str;
+ };
+
+ struct StringMatcherBase : MatcherBase<std::string> {
+ StringMatcherBase( std::string const& operation, CasedString const& comparator );
+ std::string describe() const override;
+
+ CasedString m_comparator;
+ std::string m_operation;
+ };
+
+ struct EqualsMatcher : StringMatcherBase {
+ EqualsMatcher( CasedString const& comparator );
+ bool match( std::string const& source ) const override;
+ };
+ struct ContainsMatcher : StringMatcherBase {
+ ContainsMatcher( CasedString const& comparator );
+ bool match( std::string const& source ) const override;
+ };
+ struct StartsWithMatcher : StringMatcherBase {
+ StartsWithMatcher( CasedString const& comparator );
+ bool match( std::string const& source ) const override;
+ };
+ struct EndsWithMatcher : StringMatcherBase {
+ EndsWithMatcher( CasedString const& comparator );
+ bool match( std::string const& source ) const override;
+ };
+
+ struct RegexMatcher : MatcherBase<std::string> {
+ RegexMatcher( std::string regex, CaseSensitive::Choice caseSensitivity );
+ bool match( std::string const& matchee ) const override;
+ std::string describe() const override;
+
+ private:
+ std::string m_regex;
+ CaseSensitive::Choice m_caseSensitivity;
+ };
+
+ } // namespace StdString
+
+ // The following functions create the actual matcher objects.
+ // This allows the types to be inferred
+
+ StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
+ StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
+ StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
+ StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
+ StdString::RegexMatcher Matches( std::string const& regex, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
+
+} // namespace Matchers
+} // namespace Catch
+
+// end catch_matchers_string.h
+// start catch_matchers_vector.h
+
+#include <algorithm>
+
+namespace Catch {
+namespace Matchers {
+
+ namespace Vector {
+ namespace Detail {
+ template <typename InputIterator, typename T>
+ size_t count(InputIterator first, InputIterator last, T const& item) {
+ size_t cnt = 0;
+ for (; first != last; ++first) {
+ if (*first == item) {
+ ++cnt;
+ }
+ }
+ return cnt;
+ }
+ template <typename InputIterator, typename T>
+ bool contains(InputIterator first, InputIterator last, T const& item) {
+ for (; first != last; ++first) {
+ if (*first == item) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ template<typename T>
+ struct ContainsElementMatcher : MatcherBase<std::vector<T>> {
+
+ ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}
+
+ bool match(std::vector<T> const &v) const override {
+ for (auto const& el : v) {
+ if (el == m_comparator) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ std::string describe() const override {
+ return "Contains: " + ::Catch::Detail::stringify( m_comparator );
+ }
+
+ T const& m_comparator;
+ };
+
+ template<typename T>
+ struct ContainsMatcher : MatcherBase<std::vector<T>> {
+
+ ContainsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
+
+ bool match(std::vector<T> const &v) const override {
+ // !TBD: see note in EqualsMatcher
+ if (m_comparator.size() > v.size())
+ return false;
+ for (auto const& comparator : m_comparator) {
+ auto present = false;
+ for (const auto& el : v) {
+ if (el == comparator) {
+ present = true;
+ break;
+ }
+ }
+ if (!present) {
+ return false;
+ }
+ }
+ return true;
+ }
+ std::string describe() const override {
+ return "Contains: " + ::Catch::Detail::stringify( m_comparator );
+ }
+
+ std::vector<T> const& m_comparator;
+ };
+
+ template<typename T>
+ struct EqualsMatcher : MatcherBase<std::vector<T>> {
+
+ EqualsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
+
+ bool match(std::vector<T> const &v) const override {
+ // !TBD: This currently works if all elements can be compared using !=
+ // - a more general approach would be via a compare template that defaults
+ // to using !=. but could be specialised for, e.g. std::vector<T> etc
+ // - then just call that directly
+ if (m_comparator.size() != v.size())
+ return false;
+ for (std::size_t i = 0; i < v.size(); ++i)
+ if (m_comparator[i] != v[i])
+ return false;
+ return true;
+ }
+ std::string describe() const override {
+ return "Equals: " + ::Catch::Detail::stringify( m_comparator );
+ }
+ std::vector<T> const& m_comparator;
+ };
+
+ template<typename T>
+ struct UnorderedEqualsMatcher : MatcherBase<std::vector<T>> {
+ UnorderedEqualsMatcher(std::vector<T> const& target) : m_target(target) {}
+ bool match(std::vector<T> const& vec) const override {
+ // Note: This is a reimplementation of std::is_permutation,
+ // because I don't want to include <algorithm> inside the common path
+ if (m_target.size() != vec.size()) {
+ return false;
+ }
+ auto lfirst = m_target.begin(), llast = m_target.end();
+ auto rfirst = vec.begin(), rlast = vec.end();
+ // Cut common prefix to optimize checking of permuted parts
+ while (lfirst != llast && *lfirst != *rfirst) {
+ ++lfirst; ++rfirst;
+ }
+ if (lfirst == llast) {
+ return true;
+ }
+
+ for (auto mid = lfirst; mid != llast; ++mid) {
+ // Skip already counted items
+ if (Detail::contains(lfirst, mid, *mid)) {
+ continue;
+ }
+ size_t num_vec = Detail::count(rfirst, rlast, *mid);
+ if (num_vec == 0 || Detail::count(lfirst, llast, *mid) != num_vec) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ std::string describe() const override {
+ return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target);
+ }
+ private:
+ std::vector<T> const& m_target;
+ };
+
+ } // namespace Vector
+
+ // The following functions create the actual matcher objects.
+ // This allows the types to be inferred
+
+ template<typename T>
+ Vector::ContainsMatcher<T> Contains( std::vector<T> const& comparator ) {
+ return Vector::ContainsMatcher<T>( comparator );
+ }
+
+ template<typename T>
+ Vector::ContainsElementMatcher<T> VectorContains( T const& comparator ) {
+ return Vector::ContainsElementMatcher<T>( comparator );
+ }
+
+ template<typename T>
+ Vector::EqualsMatcher<T> Equals( std::vector<T> const& comparator ) {
+ return Vector::EqualsMatcher<T>( comparator );
+ }
+
+ template<typename T>
+ Vector::UnorderedEqualsMatcher<T> UnorderedEquals(std::vector<T> const& target) {
+ return Vector::UnorderedEqualsMatcher<T>(target);
+ }
+
+} // namespace Matchers
+} // namespace Catch
+
+// end catch_matchers_vector.h
+namespace Catch {
+
+ template<typename ArgT, typename MatcherT>
+ class MatchExpr : public ITransientExpression {
+ ArgT const& m_arg;
+ MatcherT m_matcher;
+ StringRef m_matcherString;
+ public:
+ MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef matcherString )
+ : ITransientExpression{ true, matcher.match( arg ) },
+ m_arg( arg ),
+ m_matcher( matcher ),
+ m_matcherString( matcherString )
+ {}
+
+ void streamReconstructedExpression( std::ostream &os ) const override {
+ auto matcherAsString = m_matcher.toString();
+ os << Catch::Detail::stringify( m_arg ) << ' ';
+ if( matcherAsString == Detail::unprintableString )
+ os << m_matcherString;
+ else
+ os << matcherAsString;
+ }
+ };
+
+ using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
+
+ void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef matcherString );
+
+ template<typename ArgT, typename MatcherT>
+ auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef matcherString ) -> MatchExpr<ArgT, MatcherT> {
+ return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString );
+ }
+
+} // namespace Catch
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
+ do { \
+ Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
+ INTERNAL_CATCH_TRY { \
+ catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher ) ); \
+ } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
+ INTERNAL_CATCH_REACT( catchAssertionHandler ) \
+ } while( false )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
+ do { \
+ Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
+ if( catchAssertionHandler.allowThrows() ) \
+ try { \
+ static_cast<void>(__VA_ARGS__ ); \
+ catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
+ } \
+ catch( exceptionType const& ex ) { \
+ catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher ) ); \
+ } \
+ catch( ... ) { \
+ catchAssertionHandler.handleUnexpectedInflightException(); \
+ } \
+ else \
+ catchAssertionHandler.handleThrowingCallSkipped(); \
+ INTERNAL_CATCH_REACT( catchAssertionHandler ) \
+ } while( false )
+
+// end catch_capture_matchers.h
+#endif
+
+// These files are included here so the single_include script doesn't put them
+// in the conditionally compiled sections
+// start catch_test_case_info.h
+
+#include <string>
+#include <vector>
+#include <memory>
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+namespace Catch {
+
+ struct ITestInvoker;
+
+ struct TestCaseInfo {
+ enum SpecialProperties{
+ None = 0,
+ IsHidden = 1 << 1,
+ ShouldFail = 1 << 2,
+ MayFail = 1 << 3,
+ Throws = 1 << 4,
+ NonPortable = 1 << 5,
+ Benchmark = 1 << 6
+ };
+
+ TestCaseInfo( std::string const& _name,
+ std::string const& _className,
+ std::string const& _description,
+ std::vector<std::string> const& _tags,
+ SourceLineInfo const& _lineInfo );
+
+ friend void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags );
+
+ bool isHidden() const;
+ bool throws() const;
+ bool okToFail() const;
+ bool expectedToFail() const;
+
+ std::string tagsAsString() const;
+
+ std::string name;
+ std::string className;
+ std::string description;
+ std::vector<std::string> tags;
+ std::vector<std::string> lcaseTags;
+ SourceLineInfo lineInfo;
+ SpecialProperties properties;
+ };
+
+ class TestCase : public TestCaseInfo {
+ public:
+
+ TestCase( ITestInvoker* testCase, TestCaseInfo&& info );
+
+ TestCase withName( std::string const& _newName ) const;
+
+ void invoke() const;
+
+ TestCaseInfo const& getTestCaseInfo() const;
+
+ bool operator == ( TestCase const& other ) const;
+ bool operator < ( TestCase const& other ) const;
+
+ private:
+ std::shared_ptr<ITestInvoker> test;
+ };
+
+ TestCase makeTestCase( ITestInvoker* testCase,
+ std::string const& className,
+ NameAndTags const& nameAndTags,
+ SourceLineInfo const& lineInfo );
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+// end catch_test_case_info.h
+// start catch_interfaces_runner.h
+
+namespace Catch {
+
+ struct IRunner {
+ virtual ~IRunner();
+ virtual bool aborting() const = 0;
+ };
+}
+
+// end catch_interfaces_runner.h
+
+#ifdef __OBJC__
+// start catch_objc.hpp
+
+#import <objc/runtime.h>
+
+#include <string>
+
+// NB. Any general catch headers included here must be included
+// in catch.hpp first to make sure they are included by the single
+// header for non obj-usage
+
+///////////////////////////////////////////////////////////////////////////////
+// This protocol is really only here for (self) documenting purposes, since
+// all its methods are optional.
+@protocol OcFixture
+
+@optional
+
+-(void) setUp;
+-(void) tearDown;
+
+@end
+
+namespace Catch {
+
+ class OcMethod : public ITestInvoker {
+
+ public:
+ OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
+
+ virtual void invoke() const {
+ id obj = [[m_cls alloc] init];
+
+ performOptionalSelector( obj, @selector(setUp) );
+ performOptionalSelector( obj, m_sel );
+ performOptionalSelector( obj, @selector(tearDown) );
+
+ arcSafeRelease( obj );
+ }
+ private:
+ virtual ~OcMethod() {}
+
+ Class m_cls;
+ SEL m_sel;
+ };
+
+ namespace Detail{
+
+ inline std::string getAnnotation( Class cls,
+ std::string const& annotationName,
+ std::string const& testCaseName ) {
+ NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
+ SEL sel = NSSelectorFromString( selStr );
+ arcSafeRelease( selStr );
+ id value = performOptionalSelector( cls, sel );
+ if( value )
+ return [(NSString*)value UTF8String];
+ return "";
+ }
+ }
+
+ inline std::size_t registerTestMethods() {
+ std::size_t noTestMethods = 0;
+ int noClasses = objc_getClassList( nullptr, 0 );
+
+ Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
+ objc_getClassList( classes, noClasses );
+
+ for( int c = 0; c < noClasses; c++ ) {
+ Class cls = classes[c];
+ {
+ u_int count;
+ Method* methods = class_copyMethodList( cls, &count );
+ for( u_int m = 0; m < count ; m++ ) {
+ SEL selector = method_getName(methods[m]);
+ std::string methodName = sel_getName(selector);
+ if( startsWith( methodName, "Catch_TestCase_" ) ) {
+ std::string testCaseName = methodName.substr( 15 );
+ std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
+ std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
+ const char* className = class_getName( cls );
+
+ getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo("",0) ) );
+ noTestMethods++;
+ }
+ }
+ free(methods);
+ }
+ }
+ return noTestMethods;
+ }
+
+#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
+
+ namespace Matchers {
+ namespace Impl {
+ namespace NSStringMatchers {
+
+ struct StringHolder : MatcherBase<NSString*>{
+ StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
+ StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
+ StringHolder() {
+ arcSafeRelease( m_substr );
+ }
+
+ bool match( NSString* arg ) const override {
+ return false;
+ }
+
+ NSString* CATCH_ARC_STRONG m_substr;
+ };
+
+ struct Equals : StringHolder {
+ Equals( NSString* substr ) : StringHolder( substr ){}
+
+ bool match( NSString* str ) const override {
+ return (str != nil || m_substr == nil ) &&
+ [str isEqualToString:m_substr];
+ }
+
+ std::string describe() const override {
+ return "equals string: " + Catch::Detail::stringify( m_substr );
+ }
+ };
+
+ struct Contains : StringHolder {
+ Contains( NSString* substr ) : StringHolder( substr ){}
+
+ bool match( NSString* str ) const {
+ return (str != nil || m_substr == nil ) &&
+ [str rangeOfString:m_substr].location != NSNotFound;
+ }
+
+ std::string describe() const override {
+ return "contains string: " + Catch::Detail::stringify( m_substr );
+ }
+ };
+
+ struct StartsWith : StringHolder {
+ StartsWith( NSString* substr ) : StringHolder( substr ){}
+
+ bool match( NSString* str ) const override {
+ return (str != nil || m_substr == nil ) &&
+ [str rangeOfString:m_substr].location == 0;
+ }
+
+ std::string describe() const override {
+ return "starts with: " + Catch::Detail::stringify( m_substr );
+ }
+ };
+ struct EndsWith : StringHolder {
+ EndsWith( NSString* substr ) : StringHolder( substr ){}
+
+ bool match( NSString* str ) const override {
+ return (str != nil || m_substr == nil ) &&
+ [str rangeOfString:m_substr].location == [str length] - [m_substr length];
+ }
+
+ std::string describe() const override {
+ return "ends with: " + Catch::Detail::stringify( m_substr );
+ }
+ };
+
+ } // namespace NSStringMatchers
+ } // namespace Impl
+
+ inline Impl::NSStringMatchers::Equals
+ Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
+
+ inline Impl::NSStringMatchers::Contains
+ Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
+
+ inline Impl::NSStringMatchers::StartsWith
+ StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
+
+ inline Impl::NSStringMatchers::EndsWith
+ EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
+
+ } // namespace Matchers
+
+ using namespace Matchers;
+
+#endif // CATCH_CONFIG_DISABLE_MATCHERS
+
+} // namespace Catch
+
+///////////////////////////////////////////////////////////////////////////////
+#define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix
+#define OC_TEST_CASE2( name, desc, uniqueSuffix ) \
++(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \
+{ \
+return @ name; \
+} \
++(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \
+{ \
+return @ desc; \
+} \
+-(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix )
+
+#define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ )
+
+// end catch_objc.hpp
+#endif
+
+#ifdef CATCH_CONFIG_EXTERNAL_INTERFACES
+// start catch_external_interfaces.h
+
+// start catch_reporter_bases.hpp
+
+// start catch_interfaces_reporter.h
+
+// start catch_config.hpp
+
+// start catch_test_spec_parser.h
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+// start catch_test_spec.h
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+// start catch_wildcard_pattern.h
+
+namespace Catch
+{
+ class WildcardPattern {
+ enum WildcardPosition {
+ NoWildcard = 0,
+ WildcardAtStart = 1,
+ WildcardAtEnd = 2,
+ WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
+ };
+
+ public:
+
+ WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity );
+ virtual ~WildcardPattern() = default;
+ virtual bool matches( std::string const& str ) const;
+
+ private:
+ std::string adjustCase( std::string const& str ) const;
+ CaseSensitive::Choice m_caseSensitivity;
+ WildcardPosition m_wildcard = NoWildcard;
+ std::string m_pattern;
+ };
+}
+
+// end catch_wildcard_pattern.h
+#include <string>
+#include <vector>
+#include <memory>
+
+namespace Catch {
+
+ class TestSpec {
+ struct Pattern {
+ virtual ~Pattern();
+ virtual bool matches( TestCaseInfo const& testCase ) const = 0;
+ };
+ using PatternPtr = std::shared_ptr<Pattern>;
+
+ class NamePattern : public Pattern {
+ public:
+ NamePattern( std::string const& name );
+ virtual ~NamePattern();
+ virtual bool matches( TestCaseInfo const& testCase ) const override;
+ private:
+ WildcardPattern m_wildcardPattern;
+ };
+
+ class TagPattern : public Pattern {
+ public:
+ TagPattern( std::string const& tag );
+ virtual ~TagPattern();
+ virtual bool matches( TestCaseInfo const& testCase ) const override;
+ private:
+ std::string m_tag;
+ };
+
+ class ExcludedPattern : public Pattern {
+ public:
+ ExcludedPattern( PatternPtr const& underlyingPattern );
+ virtual ~ExcludedPattern();
+ virtual bool matches( TestCaseInfo const& testCase ) const override;
+ private:
+ PatternPtr m_underlyingPattern;
+ };
+
+ struct Filter {
+ std::vector<PatternPtr> m_patterns;
+
+ bool matches( TestCaseInfo const& testCase ) const;
+ };
+
+ public:
+ bool hasFilters() const;
+ bool matches( TestCaseInfo const& testCase ) const;
+
+ private:
+ std::vector<Filter> m_filters;
+
+ friend class TestSpecParser;
+ };
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+// end catch_test_spec.h
+// start catch_interfaces_tag_alias_registry.h
+
+#include <string>
+
+namespace Catch {
+
+ struct TagAlias;
+
+ struct ITagAliasRegistry {
+ virtual ~ITagAliasRegistry();
+ // Nullptr if not present
+ virtual TagAlias const* find( std::string const& alias ) const = 0;
+ virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
+
+ static ITagAliasRegistry const& get();
+ };
+
+} // end namespace Catch
+
+// end catch_interfaces_tag_alias_registry.h
+namespace Catch {
+
+ class TestSpecParser {
+ enum Mode{ None, Name, QuotedName, Tag, EscapedName };
+ Mode m_mode = None;
+ bool m_exclusion = false;
+ std::size_t m_start = std::string::npos, m_pos = 0;
+ std::string m_arg;
+ std::vector<std::size_t> m_escapeChars;
+ TestSpec::Filter m_currentFilter;
+ TestSpec m_testSpec;
+ ITagAliasRegistry const* m_tagAliases = nullptr;
+
+ public:
+ TestSpecParser( ITagAliasRegistry const& tagAliases );
+
+ TestSpecParser& parse( std::string const& arg );
+ TestSpec testSpec();
+
+ private:
+ void visitChar( char c );
+ void startNewMode( Mode mode, std::size_t start );
+ void escape();
+ std::string subString() const;
+
+ template<typename T>
+ void addPattern() {
+ std::string token = subString();
+ for( std::size_t i = 0; i < m_escapeChars.size(); ++i )
+ token = token.substr( 0, m_escapeChars[i]-m_start-i ) + token.substr( m_escapeChars[i]-m_start-i+1 );
+ m_escapeChars.clear();
+ if( startsWith( token, "exclude:" ) ) {
+ m_exclusion = true;
+ token = token.substr( 8 );
+ }
+ if( !token.empty() ) {
+ TestSpec::PatternPtr pattern = std::make_shared<T>( token );
+ if( m_exclusion )
+ pattern = std::make_shared<TestSpec::ExcludedPattern>( pattern );
+ m_currentFilter.m_patterns.push_back( pattern );
+ }
+ m_exclusion = false;
+ m_mode = None;
+ }
+
+ void addFilter();
+ };
+ TestSpec parseTestSpec( std::string const& arg );
+
+} // namespace Catch
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+// end catch_test_spec_parser.h
+// start catch_interfaces_config.h
+
+#include <iosfwd>
+#include <string>
+#include <vector>
+#include <memory>
+
+namespace Catch {
+
+ enum class Verbosity {
+ Quiet = 0,
+ Normal,
+ High
+ };
+
+ struct WarnAbout { enum What {
+ Nothing = 0x00,
+ NoAssertions = 0x01,
+ NoTests = 0x02
+ }; };
+
+ struct ShowDurations { enum OrNot {
+ DefaultForReporter,
+ Always,
+ Never
+ }; };
+ struct RunTests { enum InWhatOrder {
+ InDeclarationOrder,
+ InLexicographicalOrder,
+ InRandomOrder
+ }; };
+ struct UseColour { enum YesOrNo {
+ Auto,
+ Yes,
+ No
+ }; };
+ struct WaitForKeypress { enum When {
+ Never,
+ BeforeStart = 1,
+ BeforeExit = 2,
+ BeforeStartAndExit = BeforeStart | BeforeExit
+ }; };
+
+ class TestSpec;
+
+ struct IConfig : NonCopyable {
+
+ virtual ~IConfig();
+
+ virtual bool allowThrows() const = 0;
+ virtual std::ostream& stream() const = 0;
+ virtual std::string name() const = 0;
+ virtual bool includeSuccessfulResults() const = 0;
+ virtual bool shouldDebugBreak() const = 0;
+ virtual bool warnAboutMissingAssertions() const = 0;
+ virtual bool warnAboutNoTests() const = 0;
+ virtual int abortAfter() const = 0;
+ virtual bool showInvisibles() const = 0;
+ virtual ShowDurations::OrNot showDurations() const = 0;
+ virtual TestSpec const& testSpec() const = 0;
+ virtual bool hasTestFilters() const = 0;
+ virtual RunTests::InWhatOrder runOrder() const = 0;
+ virtual unsigned int rngSeed() const = 0;
+ virtual int benchmarkResolutionMultiple() const = 0;
+ virtual UseColour::YesOrNo useColour() const = 0;
+ virtual std::vector<std::string> const& getSectionsToRun() const = 0;
+ virtual Verbosity verbosity() const = 0;
+ };
+
+ using IConfigPtr = std::shared_ptr<IConfig const>;
+}
+
+// end catch_interfaces_config.h
+// Libstdc++ doesn't like incomplete classes for unique_ptr
+
+#include <memory>
+#include <vector>
+#include <string>
+
+#ifndef CATCH_CONFIG_CONSOLE_WIDTH
+#define CATCH_CONFIG_CONSOLE_WIDTH 80
+#endif
+
+namespace Catch {
+
+ struct IStream;
+
+ struct ConfigData {
+ bool listTests = false;
+ bool listTags = false;
+ bool listReporters = false;
+ bool listTestNamesOnly = false;
+
+ bool showSuccessfulTests = false;
+ bool shouldDebugBreak = false;
+ bool noThrow = false;
+ bool showHelp = false;
+ bool showInvisibles = false;
+ bool filenamesAsTags = false;
+ bool libIdentify = false;
+
+ int abortAfter = -1;
+ unsigned int rngSeed = 0;
+ int benchmarkResolutionMultiple = 100;
+
+ Verbosity verbosity = Verbosity::Normal;
+ WarnAbout::What warnings = WarnAbout::Nothing;
+ ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter;
+ RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder;
+ UseColour::YesOrNo useColour = UseColour::Auto;
+ WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;
+
+ std::string outputFilename;
+ std::string name;
+ std::string processName;
+
+ std::vector<std::string> reporterNames;
+ std::vector<std::string> testsOrTags;
+ std::vector<std::string> sectionsToRun;
+ };
+
+ class Config : public IConfig {
+ public:
+
+ Config() = default;
+ Config( ConfigData const& data );
+ virtual ~Config() = default;
+
+ std::string const& getFilename() const;
+
+ bool listTests() const;
+ bool listTestNamesOnly() const;
+ bool listTags() const;
+ bool listReporters() const;
+
+ std::string getProcessName() const;
+
+ std::vector<std::string> const& getReporterNames() const;
+ std::vector<std::string> const& getTestsOrTags() const;
+ std::vector<std::string> const& getSectionsToRun() const override;
+
+ virtual TestSpec const& testSpec() const override;
+ bool hasTestFilters() const override;
+
+ bool showHelp() const;
+
+ // IConfig interface
+ bool allowThrows() const override;
+ std::ostream& stream() const override;
+ std::string name() const override;
+ bool includeSuccessfulResults() const override;
+ bool warnAboutMissingAssertions() const override;
+ bool warnAboutNoTests() const override;
+ ShowDurations::OrNot showDurations() const override;
+ RunTests::InWhatOrder runOrder() const override;
+ unsigned int rngSeed() const override;
+ int benchmarkResolutionMultiple() const override;
+ UseColour::YesOrNo useColour() const override;
+ bool shouldDebugBreak() const override;
+ int abortAfter() const override;
+ bool showInvisibles() const override;
+ Verbosity verbosity() const override;
+
+ private:
+
+ IStream const* openStream();
+ ConfigData m_data;
+
+ std::unique_ptr<IStream const> m_stream;
+ TestSpec m_testSpec;
+ bool m_hasTestFilters = false;
+ };
+
+} // end namespace Catch
+
+// end catch_config.hpp
+// start catch_assertionresult.h
+
+#include <string>
+
+namespace Catch {
+
+ struct AssertionResultData
+ {
+ AssertionResultData() = delete;
+
+ AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression );
+
+ std::string message;
+ mutable std::string reconstructedExpression;
+ LazyExpression lazyExpression;
+ ResultWas::OfType resultType;
+
+ std::string reconstructExpression() const;
+ };
+
+ class AssertionResult {
+ public:
+ AssertionResult() = delete;
+ AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
+
+ bool isOk() const;
+ bool succeeded() const;
+ ResultWas::OfType getResultType() const;
+ bool hasExpression() const;
+ bool hasMessage() const;
+ std::string getExpression() const;
+ std::string getExpressionInMacro() const;
+ bool hasExpandedExpression() const;
+ std::string getExpandedExpression() const;
+ std::string getMessage() const;
+ SourceLineInfo getSourceInfo() const;
+ StringRef getTestMacroName() const;
+
+ //protected:
+ AssertionInfo m_info;
+ AssertionResultData m_resultData;
+ };
+
+} // end namespace Catch
+
+// end catch_assertionresult.h
+// start catch_option.hpp
+
+namespace Catch {
+
+ // An optional type
+ template<typename T>
+ class Option {
+ public:
+ Option() : nullableValue( nullptr ) {}
+ Option( T const& _value )
+ : nullableValue( new( storage ) T( _value ) )
+ {}
+ Option( Option const& _other )
+ : nullableValue( _other ? new( storage ) T( *_other ) : nullptr )
+ {}
+
+ ~Option() {
+ reset();
+ }
+
+ Option& operator= ( Option const& _other ) {
+ if( &_other != this ) {
+ reset();
+ if( _other )
+ nullableValue = new( storage ) T( *_other );
+ }
+ return *this;
+ }
+ Option& operator = ( T const& _value ) {
+ reset();
+ nullableValue = new( storage ) T( _value );
+ return *this;
+ }
+
+ void reset() {
+ if( nullableValue )
+ nullableValue->~T();
+ nullableValue = nullptr;
+ }
+
+ T& operator*() { return *nullableValue; }
+ T const& operator*() const { return *nullableValue; }
+ T* operator->() { return nullableValue; }
+ const T* operator->() const { return nullableValue; }
+
+ T valueOr( T const& defaultValue ) const {
+ return nullableValue ? *nullableValue : defaultValue;
+ }
+
+ bool some() const { return nullableValue != nullptr; }
+ bool none() const { return nullableValue == nullptr; }
+
+ bool operator !() const { return nullableValue == nullptr; }
+ explicit operator bool() const {
+ return some();
+ }
+
+ private:
+ T *nullableValue;
+ alignas(alignof(T)) char storage[sizeof(T)];
+ };
+
+} // end namespace Catch
+
+// end catch_option.hpp
+#include <string>
+#include <iosfwd>
+#include <map>
+#include <set>
+#include <memory>
+
+namespace Catch {
+
+ struct ReporterConfig {
+ explicit ReporterConfig( IConfigPtr const& _fullConfig );
+
+ ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream );
+
+ std::ostream& stream() const;
+ IConfigPtr fullConfig() const;
+
+ private:
+ std::ostream* m_stream;
+ IConfigPtr m_fullConfig;
+ };
+
+ struct ReporterPreferences {
+ bool shouldRedirectStdOut = false;
+ };
+
+ template<typename T>
+ struct LazyStat : Option<T> {
+ LazyStat& operator=( T const& _value ) {
+ Option<T>::operator=( _value );
+ used = false;
+ return *this;
+ }
+ void reset() {
+ Option<T>::reset();
+ used = false;
+ }
+ bool used = false;
+ };
+
+ struct TestRunInfo {
+ TestRunInfo( std::string const& _name );
+ std::string name;
+ };
+ struct GroupInfo {
+ GroupInfo( std::string const& _name,
+ std::size_t _groupIndex,
+ std::size_t _groupsCount );
+
+ std::string name;
+ std::size_t groupIndex;
+ std::size_t groupsCounts;
+ };
+
+ struct AssertionStats {
+ AssertionStats( AssertionResult const& _assertionResult,
+ std::vector<MessageInfo> const& _infoMessages,
+ Totals const& _totals );
+
+ AssertionStats( AssertionStats const& ) = default;
+ AssertionStats( AssertionStats && ) = default;
+ AssertionStats& operator = ( AssertionStats const& ) = default;
+ AssertionStats& operator = ( AssertionStats && ) = default;
+ virtual ~AssertionStats();
+
+ AssertionResult assertionResult;
+ std::vector<MessageInfo> infoMessages;
+ Totals totals;
+ };
+
+ struct SectionStats {
+ SectionStats( SectionInfo const& _sectionInfo,
+ Counts const& _assertions,
+ double _durationInSeconds,
+ bool _missingAssertions );
+ SectionStats( SectionStats const& ) = default;
+ SectionStats( SectionStats && ) = default;
+ SectionStats& operator = ( SectionStats const& ) = default;
+ SectionStats& operator = ( SectionStats && ) = default;
+ virtual ~SectionStats();
+
+ SectionInfo sectionInfo;
+ Counts assertions;
+ double durationInSeconds;
+ bool missingAssertions;
+ };
+
+ struct TestCaseStats {
+ TestCaseStats( TestCaseInfo const& _testInfo,
+ Totals const& _totals,
+ std::string const& _stdOut,
+ std::string const& _stdErr,
+ bool _aborting );
+
+ TestCaseStats( TestCaseStats const& ) = default;
+ TestCaseStats( TestCaseStats && ) = default;
+ TestCaseStats& operator = ( TestCaseStats const& ) = default;
+ TestCaseStats& operator = ( TestCaseStats && ) = default;
+ virtual ~TestCaseStats();
+
+ TestCaseInfo testInfo;
+ Totals totals;
+ std::string stdOut;
+ std::string stdErr;
+ bool aborting;
+ };
+
+ struct TestGroupStats {
+ TestGroupStats( GroupInfo const& _groupInfo,
+ Totals const& _totals,
+ bool _aborting );
+ TestGroupStats( GroupInfo const& _groupInfo );
+
+ TestGroupStats( TestGroupStats const& ) = default;
+ TestGroupStats( TestGroupStats && ) = default;
+ TestGroupStats& operator = ( TestGroupStats const& ) = default;
+ TestGroupStats& operator = ( TestGroupStats && ) = default;
+ virtual ~TestGroupStats();
+
+ GroupInfo groupInfo;
+ Totals totals;
+ bool aborting;
+ };
+
+ struct TestRunStats {
+ TestRunStats( TestRunInfo const& _runInfo,
+ Totals const& _totals,
+ bool _aborting );
+
+ TestRunStats( TestRunStats const& ) = default;
+ TestRunStats( TestRunStats && ) = default;
+ TestRunStats& operator = ( TestRunStats const& ) = default;
+ TestRunStats& operator = ( TestRunStats && ) = default;
+ virtual ~TestRunStats();
+
+ TestRunInfo runInfo;
+ Totals totals;
+ bool aborting;
+ };
+
+ struct BenchmarkInfo {
+ std::string name;
+ };
+ struct BenchmarkStats {
+ BenchmarkInfo info;
+ std::size_t iterations;
+ uint64_t elapsedTimeInNanoseconds;
+ };
+
+ struct IStreamingReporter {
+ virtual ~IStreamingReporter() = default;
+
+ // Implementing class must also provide the following static methods:
+ // static std::string getDescription();
+ // static std::set<Verbosity> getSupportedVerbosities()
+
+ virtual ReporterPreferences getPreferences() const = 0;
+
+ virtual void noMatchingTestCases( std::string const& spec ) = 0;
+
+ virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
+ virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
+
+ virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
+ virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
+
+ // *** experimental ***
+ virtual void benchmarkStarting( BenchmarkInfo const& ) {}
+
+ virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
+
+ // The return value indicates if the messages buffer should be cleared:
+ virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
+
+ // *** experimental ***
+ virtual void benchmarkEnded( BenchmarkStats const& ) {}
+
+ virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
+ virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
+
+ virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
+
+ // Default empty implementation provided
+ virtual void fatalErrorEncountered( StringRef name );
+
+ virtual bool isMulti() const;
+ };
+ using IStreamingReporterPtr = std::unique_ptr<IStreamingReporter>;
+
+ struct IReporterFactory {
+ virtual ~IReporterFactory();
+ virtual IStreamingReporterPtr create( ReporterConfig const& config ) const = 0;
+ virtual std::string getDescription() const = 0;
+ };
+ using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
+
+ struct IReporterRegistry {
+ using FactoryMap = std::map<std::string, IReporterFactoryPtr>;
+ using Listeners = std::vector<IReporterFactoryPtr>;
+
+ virtual ~IReporterRegistry();
+ virtual IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const = 0;
+ virtual FactoryMap const& getFactories() const = 0;
+ virtual Listeners const& getListeners() const = 0;
+ };
+
+ void addReporter( IStreamingReporterPtr& existingReporter, IStreamingReporterPtr&& additionalReporter );
+
+} // end namespace Catch
+
+// end catch_interfaces_reporter.h
+#include <algorithm>
+#include <cstring>
+#include <cfloat>
+#include <cstdio>
+#include <assert.h>
+#include <memory>
+#include <ostream>
+
+namespace Catch {
+ void prepareExpandedExpression(AssertionResult& result);
+
+ // Returns double formatted as %.3f (format expected on output)
+ std::string getFormattedDuration( double duration );
+
+ template<typename DerivedT>
+ struct StreamingReporterBase : IStreamingReporter {
+
+ StreamingReporterBase( ReporterConfig const& _config )
+ : m_config( _config.fullConfig() ),
+ stream( _config.stream() )
+ {
+ m_reporterPrefs.shouldRedirectStdOut = false;
+ if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
+ throw std::domain_error( "Verbosity level not supported by this reporter" );
+ }
+
+ ReporterPreferences getPreferences() const override {
+ return m_reporterPrefs;
+ }
+
+ static std::set<Verbosity> getSupportedVerbosities() {
+ return { Verbosity::Normal };
+ }
+
+ ~StreamingReporterBase() override = default;
+
+ void noMatchingTestCases(std::string const&) override {}
+
+ void testRunStarting(TestRunInfo const& _testRunInfo) override {
+ currentTestRunInfo = _testRunInfo;
+ }
+ void testGroupStarting(GroupInfo const& _groupInfo) override {
+ currentGroupInfo = _groupInfo;
+ }
+
+ void testCaseStarting(TestCaseInfo const& _testInfo) override {
+ currentTestCaseInfo = _testInfo;
+ }
+ void sectionStarting(SectionInfo const& _sectionInfo) override {
+ m_sectionStack.push_back(_sectionInfo);
+ }
+
+ void sectionEnded(SectionStats const& /* _sectionStats */) override {
+ m_sectionStack.pop_back();
+ }
+ void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override {
+ currentTestCaseInfo.reset();
+ }
+ void testGroupEnded(TestGroupStats const& /* _testGroupStats */) override {
+ currentGroupInfo.reset();
+ }
+ void testRunEnded(TestRunStats const& /* _testRunStats */) override {
+ currentTestCaseInfo.reset();
+ currentGroupInfo.reset();
+ currentTestRunInfo.reset();
+ }
+
+ void skipTest(TestCaseInfo const&) override {
+ // Don't do anything with this by default.
+ // It can optionally be overridden in the derived class.
+ }
+
+ IConfigPtr m_config;
+ std::ostream& stream;
+
+ LazyStat<TestRunInfo> currentTestRunInfo;
+ LazyStat<GroupInfo> currentGroupInfo;
+ LazyStat<TestCaseInfo> currentTestCaseInfo;
+
+ std::vector<SectionInfo> m_sectionStack;
+ ReporterPreferences m_reporterPrefs;
+ };
+
+ template<typename DerivedT>
+ struct CumulativeReporterBase : IStreamingReporter {
+ template<typename T, typename ChildNodeT>
+ struct Node {
+ explicit Node( T const& _value ) : value( _value ) {}
+ virtual ~Node() {}
+
+ using ChildNodes = std::vector<std::shared_ptr<ChildNodeT>>;
+ T value;
+ ChildNodes children;
+ };
+ struct SectionNode {
+ explicit SectionNode(SectionStats const& _stats) : stats(_stats) {}
+ virtual ~SectionNode() = default;
+
+ bool operator == (SectionNode const& other) const {
+ return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
+ }
+ bool operator == (std::shared_ptr<SectionNode> const& other) const {
+ return operator==(*other);
+ }
+
+ SectionStats stats;
+ using ChildSections = std::vector<std::shared_ptr<SectionNode>>;
+ using Assertions = std::vector<AssertionStats>;
+ ChildSections childSections;
+ Assertions assertions;
+ std::string stdOut;
+ std::string stdErr;
+ };
+
+ struct BySectionInfo {
+ BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
+ BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
+ bool operator() (std::shared_ptr<SectionNode> const& node) const {
+ return ((node->stats.sectionInfo.name == m_other.name) &&
+ (node->stats.sectionInfo.lineInfo == m_other.lineInfo));
+ }
+ void operator=(BySectionInfo const&) = delete;
+
+ private:
+ SectionInfo const& m_other;
+ };
+
+ using TestCaseNode = Node<TestCaseStats, SectionNode>;
+ using TestGroupNode = Node<TestGroupStats, TestCaseNode>;
+ using TestRunNode = Node<TestRunStats, TestGroupNode>;
+
+ CumulativeReporterBase( ReporterConfig const& _config )
+ : m_config( _config.fullConfig() ),
+ stream( _config.stream() )
+ {
+ m_reporterPrefs.shouldRedirectStdOut = false;
+ if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
+ throw std::domain_error( "Verbosity level not supported by this reporter" );
+ }
+ ~CumulativeReporterBase() override = default;
+
+ ReporterPreferences getPreferences() const override {
+ return m_reporterPrefs;
+ }
+
+ static std::set<Verbosity> getSupportedVerbosities() {
+ return { Verbosity::Normal };
+ }
+
+ void testRunStarting( TestRunInfo const& ) override {}
+ void testGroupStarting( GroupInfo const& ) override {}
+
+ void testCaseStarting( TestCaseInfo const& ) override {}
+
+ void sectionStarting( SectionInfo const& sectionInfo ) override {
+ SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
+ std::shared_ptr<SectionNode> node;
+ if( m_sectionStack.empty() ) {
+ if( !m_rootSection )
+ m_rootSection = std::make_shared<SectionNode>( incompleteStats );
+ node = m_rootSection;
+ }
+ else {
+ SectionNode& parentNode = *m_sectionStack.back();
+ auto it =
+ std::find_if( parentNode.childSections.begin(),
+ parentNode.childSections.end(),
+ BySectionInfo( sectionInfo ) );
+ if( it == parentNode.childSections.end() ) {
+ node = std::make_shared<SectionNode>( incompleteStats );
+ parentNode.childSections.push_back( node );
+ }
+ else
+ node = *it;
+ }
+ m_sectionStack.push_back( node );
+ m_deepestSection = std::move(node);
+ }
+
+ void assertionStarting(AssertionInfo const&) override {}
+
+ bool assertionEnded(AssertionStats const& assertionStats) override {
+ assert(!m_sectionStack.empty());
+ // AssertionResult holds a pointer to a temporary DecomposedExpression,
+ // which getExpandedExpression() calls to build the expression string.
+ // Our section stack copy of the assertionResult will likely outlive the
+ // temporary, so it must be expanded or discarded now to avoid calling
+ // a destroyed object later.
+ prepareExpandedExpression(const_cast<AssertionResult&>( assertionStats.assertionResult ) );
+ SectionNode& sectionNode = *m_sectionStack.back();
+ sectionNode.assertions.push_back(assertionStats);
+ return true;
+ }
+ void sectionEnded(SectionStats const& sectionStats) override {
+ assert(!m_sectionStack.empty());
+ SectionNode& node = *m_sectionStack.back();
+ node.stats = sectionStats;
+ m_sectionStack.pop_back();
+ }
+ void testCaseEnded(TestCaseStats const& testCaseStats) override {
+ auto node = std::make_shared<TestCaseNode>(testCaseStats);
+ assert(m_sectionStack.size() == 0);
+ node->children.push_back(m_rootSection);
+ m_testCases.push_back(node);
+ m_rootSection.reset();
+
+ assert(m_deepestSection);
+ m_deepestSection->stdOut = testCaseStats.stdOut;
+ m_deepestSection->stdErr = testCaseStats.stdErr;
+ }
+ void testGroupEnded(TestGroupStats const& testGroupStats) override {
+ auto node = std::make_shared<TestGroupNode>(testGroupStats);
+ node->children.swap(m_testCases);
+ m_testGroups.push_back(node);
+ }
+ void testRunEnded(TestRunStats const& testRunStats) override {
+ auto node = std::make_shared<TestRunNode>(testRunStats);
+ node->children.swap(m_testGroups);
+ m_testRuns.push_back(node);
+ testRunEndedCumulative();
+ }
+ virtual void testRunEndedCumulative() = 0;
+
+ void skipTest(TestCaseInfo const&) override {}
+
+ IConfigPtr m_config;
+ std::ostream& stream;
+ std::vector<AssertionStats> m_assertions;
+ std::vector<std::vector<std::shared_ptr<SectionNode>>> m_sections;
+ std::vector<std::shared_ptr<TestCaseNode>> m_testCases;
+ std::vector<std::shared_ptr<TestGroupNode>> m_testGroups;
+
+ std::vector<std::shared_ptr<TestRunNode>> m_testRuns;
+
+ std::shared_ptr<SectionNode> m_rootSection;
+ std::shared_ptr<SectionNode> m_deepestSection;
+ std::vector<std::shared_ptr<SectionNode>> m_sectionStack;
+ ReporterPreferences m_reporterPrefs;
+ };
+
+ template<char C>
+ char const* getLineOfChars() {
+ static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
+ if( !*line ) {
+ std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
+ line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
+ }
+ return line;
+ }
+
+ struct TestEventListenerBase : StreamingReporterBase<TestEventListenerBase> {
+ TestEventListenerBase( ReporterConfig const& _config );
+
+ void assertionStarting(AssertionInfo const&) override;
+ bool assertionEnded(AssertionStats const&) override;
+ };
+
+} // end namespace Catch
+
+// end catch_reporter_bases.hpp
+// start catch_console_colour.h
+
+namespace Catch {
+
+ struct Colour {
+ enum Code {
+ None = 0,
+
+ White,
+ Red,
+ Green,
+ Blue,
+ Cyan,
+ Yellow,
+ Grey,
+
+ Bright = 0x10,
+
+ BrightRed = Bright | Red,
+ BrightGreen = Bright | Green,
+ LightGrey = Bright | Grey,
+ BrightWhite = Bright | White,
+ BrightYellow = Bright | Yellow,
+
+ // By intention
+ FileName = LightGrey,
+ Warning = BrightYellow,
+ ResultError = BrightRed,
+ ResultSuccess = BrightGreen,
+ ResultExpectedFailure = Warning,
+
+ Error = BrightRed,
+ Success = Green,
+
+ OriginalExpression = Cyan,
+ ReconstructedExpression = BrightYellow,
+
+ SecondaryText = LightGrey,
+ Headers = White
+ };
+
+ // Use constructed object for RAII guard
+ Colour( Code _colourCode );
+ Colour( Colour&& other ) noexcept;
+ Colour& operator=( Colour&& other ) noexcept;
+ ~Colour();
+
+ // Use static method for one-shot changes
+ static void use( Code _colourCode );
+
+ private:
+ bool m_moved = false;
+ };
+
+ std::ostream& operator << ( std::ostream& os, Colour const& );
+
+} // end namespace Catch
+
+// end catch_console_colour.h
+// start catch_reporter_registrars.hpp
+
+
+namespace Catch {
+
+ template<typename T>
+ class ReporterRegistrar {
+
+ class ReporterFactory : public IReporterFactory {
+
+ virtual IStreamingReporterPtr create( ReporterConfig const& config ) const override {
+ return std::unique_ptr<T>( new T( config ) );
+ }
+
+ virtual std::string getDescription() const override {
+ return T::getDescription();
+ }
+ };
+
+ public:
+
+ explicit ReporterRegistrar( std::string const& name ) {
+ getMutableRegistryHub().registerReporter( name, std::make_shared<ReporterFactory>() );
+ }
+ };
+
+ template<typename T>
+ class ListenerRegistrar {
+
+ class ListenerFactory : public IReporterFactory {
+
+ virtual IStreamingReporterPtr create( ReporterConfig const& config ) const override {
+ return std::unique_ptr<T>( new T( config ) );
+ }
+ virtual std::string getDescription() const override {
+ return std::string();
+ }
+ };
+
+ public:
+
+ ListenerRegistrar() {
+ getMutableRegistryHub().registerListener( std::make_shared<ListenerFactory>() );
+ }
+ };
+}
+
+#if !defined(CATCH_CONFIG_DISABLE)
+
+#define CATCH_REGISTER_REPORTER( name, reporterType ) \
+ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+ namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \
+ CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
+
+#define CATCH_REGISTER_LISTENER( listenerType ) \
+ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+ namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \
+ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
+#else // CATCH_CONFIG_DISABLE
+
+#define CATCH_REGISTER_REPORTER(name, reporterType)
+#define CATCH_REGISTER_LISTENER(listenerType)
+
+#endif // CATCH_CONFIG_DISABLE
+
+// end catch_reporter_registrars.hpp
+// Allow users to base their work off existing reporters
+// start catch_reporter_compact.h
+
+namespace Catch {
+
+ struct CompactReporter : StreamingReporterBase<CompactReporter> {
+
+ using StreamingReporterBase::StreamingReporterBase;
+
+ ~CompactReporter() override;
+
+ static std::string getDescription();
+
+ ReporterPreferences getPreferences() const override;
+
+ void noMatchingTestCases(std::string const& spec) override;
+
+ void assertionStarting(AssertionInfo const&) override;
+
+ bool assertionEnded(AssertionStats const& _assertionStats) override;
+
+ void sectionEnded(SectionStats const& _sectionStats) override;
+
+ void testRunEnded(TestRunStats const& _testRunStats) override;
+
+ };
+
+} // end namespace Catch
+
+// end catch_reporter_compact.h
+// start catch_reporter_console.h
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
+ // Note that 4062 (not all labels are handled
+ // and default is missing) is enabled
+#endif
+
+namespace Catch {
+ // Fwd decls
+ struct SummaryColumn;
+ class TablePrinter;
+
+ struct ConsoleReporter : StreamingReporterBase<ConsoleReporter> {
+ std::unique_ptr<TablePrinter> m_tablePrinter;
+
+ ConsoleReporter(ReporterConfig const& config);
+ ~ConsoleReporter() override;
+ static std::string getDescription();
+
+ void noMatchingTestCases(std::string const& spec) override;
+
+ void assertionStarting(AssertionInfo const&) override;
+
+ bool assertionEnded(AssertionStats const& _assertionStats) override;
+
+ void sectionStarting(SectionInfo const& _sectionInfo) override;
+ void sectionEnded(SectionStats const& _sectionStats) override;
+
+ void benchmarkStarting(BenchmarkInfo const& info) override;
+ void benchmarkEnded(BenchmarkStats const& stats) override;
+
+ void testCaseEnded(TestCaseStats const& _testCaseStats) override;
+ void testGroupEnded(TestGroupStats const& _testGroupStats) override;
+ void testRunEnded(TestRunStats const& _testRunStats) override;
+
+ private:
+
+ void lazyPrint();
+
+ void lazyPrintWithoutClosingBenchmarkTable();
+ void lazyPrintRunInfo();
+ void lazyPrintGroupInfo();
+ void printTestCaseAndSectionHeader();
+
+ void printClosedHeader(std::string const& _name);
+ void printOpenHeader(std::string const& _name);
+
+ // if string has a : in first line will set indent to follow it on
+ // subsequent lines
+ void printHeaderString(std::string const& _string, std::size_t indent = 0);
+
+ void printTotals(Totals const& totals);
+ void printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row);
+
+ void printTotalsDivider(Totals const& totals);
+ void printSummaryDivider();
+
+ private:
+ bool m_headerPrinted = false;
+ };
+
+} // end namespace Catch
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+// end catch_reporter_console.h
+// start catch_reporter_junit.h
+
+// start catch_xmlwriter.h
+
+#include <vector>
+
+namespace Catch {
+
+ class XmlEncode {
+ public:
+ enum ForWhat { ForTextNodes, ForAttributes };
+
+ XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes );
+
+ void encodeTo( std::ostream& os ) const;
+
+ friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode );
+
+ private:
+ std::string m_str;
+ ForWhat m_forWhat;
+ };
+
+ class XmlWriter {
+ public:
+
+ class ScopedElement {
+ public:
+ ScopedElement( XmlWriter* writer );
+
+ ScopedElement( ScopedElement&& other ) noexcept;
+ ScopedElement& operator=( ScopedElement&& other ) noexcept;
+
+ ~ScopedElement();
+
+ ScopedElement& writeText( std::string const& text, bool indent = true );
+
+ template<typename T>
+ ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
+ m_writer->writeAttribute( name, attribute );
+ return *this;
+ }
+
+ private:
+ mutable XmlWriter* m_writer = nullptr;
+ };
+
+ XmlWriter( std::ostream& os = Catch::cout() );
+ ~XmlWriter();
+
+ XmlWriter( XmlWriter const& ) = delete;
+ XmlWriter& operator=( XmlWriter const& ) = delete;
+
+ XmlWriter& startElement( std::string const& name );
+
+ ScopedElement scopedElement( std::string const& name );
+
+ XmlWriter& endElement();
+
+ XmlWriter& writeAttribute( std::string const& name, std::string const& attribute );
+
+ XmlWriter& writeAttribute( std::string const& name, bool attribute );
+
+ template<typename T>
+ XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
+ ReusableStringStream rss;
+ rss << attribute;
+ return writeAttribute( name, rss.str() );
+ }
+
+ XmlWriter& writeText( std::string const& text, bool indent = true );
+
+ XmlWriter& writeComment( std::string const& text );
+
+ void writeStylesheetRef( std::string const& url );
+
+ XmlWriter& writeBlankLine();
+
+ void ensureTagClosed();
+
+ private:
+
+ void writeDeclaration();
+
+ void newlineIfNecessary();
+
+ bool m_tagIsOpen = false;
+ bool m_needsNewline = false;
+ std::vector<std::string> m_tags;
+ std::string m_indent;
+ std::ostream& m_os;
+ };
+
+}
+
+// end catch_xmlwriter.h
+namespace Catch {
+
+ class JunitReporter : public CumulativeReporterBase<JunitReporter> {
+ public:
+ JunitReporter(ReporterConfig const& _config);
+
+ ~JunitReporter() override;
+
+ static std::string getDescription();
+
+ void noMatchingTestCases(std::string const& /*spec*/) override;
+
+ void testRunStarting(TestRunInfo const& runInfo) override;
+
+ void testGroupStarting(GroupInfo const& groupInfo) override;
+
+ void testCaseStarting(TestCaseInfo const& testCaseInfo) override;
+ bool assertionEnded(AssertionStats const& assertionStats) override;
+
+ void testCaseEnded(TestCaseStats const& testCaseStats) override;
+
+ void testGroupEnded(TestGroupStats const& testGroupStats) override;
+
+ void testRunEndedCumulative() override;
+
+ void writeGroup(TestGroupNode const& groupNode, double suiteTime);
+
+ void writeTestCase(TestCaseNode const& testCaseNode);
+
+ void writeSection(std::string const& className,
+ std::string const& rootName,
+ SectionNode const& sectionNode);
+
+ void writeAssertions(SectionNode const& sectionNode);
+ void writeAssertion(AssertionStats const& stats);
+
+ XmlWriter xml;
+ Timer suiteTimer;
+ std::string stdOutForSuite;
+ std::string stdErrForSuite;
+ unsigned int unexpectedExceptions = 0;
+ bool m_okToFail = false;
+ };
+
+} // end namespace Catch
+
+// end catch_reporter_junit.h
+// start catch_reporter_xml.h
+
+namespace Catch {
+ class XmlReporter : public StreamingReporterBase<XmlReporter> {
+ public:
+ XmlReporter(ReporterConfig const& _config);
+
+ ~XmlReporter() override;
+
+ static std::string getDescription();
+
+ virtual std::string getStylesheetRef() const;
+
+ void writeSourceInfo(SourceLineInfo const& sourceInfo);
+
+ public: // StreamingReporterBase
+
+ void noMatchingTestCases(std::string const& s) override;
+
+ void testRunStarting(TestRunInfo const& testInfo) override;
+
+ void testGroupStarting(GroupInfo const& groupInfo) override;
+
+ void testCaseStarting(TestCaseInfo const& testInfo) override;
+
+ void sectionStarting(SectionInfo const& sectionInfo) override;
+
+ void assertionStarting(AssertionInfo const&) override;
+
+ bool assertionEnded(AssertionStats const& assertionStats) override;
+
+ void sectionEnded(SectionStats const& sectionStats) override;
+
+ void testCaseEnded(TestCaseStats const& testCaseStats) override;
+
+ void testGroupEnded(TestGroupStats const& testGroupStats) override;
+
+ void testRunEnded(TestRunStats const& testRunStats) override;
+
+ private:
+ Timer m_testCaseTimer;
+ XmlWriter m_xml;
+ int m_sectionDepth = 0;
+ };
+
+} // end namespace Catch
+
+// end catch_reporter_xml.h
+
+// end catch_external_interfaces.h
+#endif
+
+#endif // ! CATCH_CONFIG_IMPL_ONLY
+
+#ifdef CATCH_IMPL
+// start catch_impl.hpp
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wweak-vtables"
+#endif
+
+// Keep these here for external reporters
+// start catch_test_case_tracker.h
+
+#include <string>
+#include <vector>
+#include <memory>
+
+namespace Catch {
+namespace TestCaseTracking {
+
+ struct NameAndLocation {
+ std::string name;
+ SourceLineInfo location;
+
+ NameAndLocation( std::string const& _name, SourceLineInfo const& _location );
+ };
+
+ struct ITracker;
+
+ using ITrackerPtr = std::shared_ptr<ITracker>;
+
+ struct ITracker {
+ virtual ~ITracker();
+
+ // static queries
+ virtual NameAndLocation const& nameAndLocation() const = 0;
+
+ // dynamic queries
+ virtual bool isComplete() const = 0; // Successfully completed or failed
+ virtual bool isSuccessfullyCompleted() const = 0;
+ virtual bool isOpen() const = 0; // Started but not complete
+ virtual bool hasChildren() const = 0;
+
+ virtual ITracker& parent() = 0;
+
+ // actions
+ virtual void close() = 0; // Successfully complete
+ virtual void fail() = 0;
+ virtual void markAsNeedingAnotherRun() = 0;
+
+ virtual void addChild( ITrackerPtr const& child ) = 0;
+ virtual ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) = 0;
+ virtual void openChild() = 0;
+
+ // Debug/ checking
+ virtual bool isSectionTracker() const = 0;
+ virtual bool isIndexTracker() const = 0;
+ };
+
+ class TrackerContext {
+
+ enum RunState {
+ NotStarted,
+ Executing,
+ CompletedCycle
+ };
+
+ ITrackerPtr m_rootTracker;
+ ITracker* m_currentTracker = nullptr;
+ RunState m_runState = NotStarted;
+
+ public:
+
+ static TrackerContext& instance();
+
+ ITracker& startRun();
+ void endRun();
+
+ void startCycle();
+ void completeCycle();
+
+ bool completedCycle() const;
+ ITracker& currentTracker();
+ void setCurrentTracker( ITracker* tracker );
+ };
+
+ class TrackerBase : public ITracker {
+ protected:
+ enum CycleState {
+ NotStarted,
+ Executing,
+ ExecutingChildren,
+ NeedsAnotherRun,
+ CompletedSuccessfully,
+ Failed
+ };
+
+ class TrackerHasName {
+ NameAndLocation m_nameAndLocation;
+ public:
+ TrackerHasName( NameAndLocation const& nameAndLocation );
+ bool operator ()( ITrackerPtr const& tracker ) const;
+ };
+
+ using Children = std::vector<ITrackerPtr>;
+ NameAndLocation m_nameAndLocation;
+ TrackerContext& m_ctx;
+ ITracker* m_parent;
+ Children m_children;
+ CycleState m_runState = NotStarted;
+
+ public:
+ TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
+
+ NameAndLocation const& nameAndLocation() const override;
+ bool isComplete() const override;
+ bool isSuccessfullyCompleted() const override;
+ bool isOpen() const override;
+ bool hasChildren() const override;
+
+ void addChild( ITrackerPtr const& child ) override;
+
+ ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override;
+ ITracker& parent() override;
+
+ void openChild() override;
+
+ bool isSectionTracker() const override;
+ bool isIndexTracker() const override;
+
+ void open();
+
+ void close() override;
+ void fail() override;
+ void markAsNeedingAnotherRun() override;
+
+ private:
+ void moveToParent();
+ void moveToThis();
+ };
+
+ class SectionTracker : public TrackerBase {
+ std::vector<std::string> m_filters;
+ public:
+ SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
+
+ bool isSectionTracker() const override;
+
+ static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation );
+
+ void tryOpen();
+
+ void addInitialFilters( std::vector<std::string> const& filters );
+ void addNextFilters( std::vector<std::string> const& filters );
+ };
+
+ class IndexTracker : public TrackerBase {
+ int m_size;
+ int m_index = -1;
+ public:
+ IndexTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size );
+
+ bool isIndexTracker() const override;
+ void close() override;
+
+ static IndexTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size );
+
+ int index() const;
+
+ void moveNext();
+ };
+
+} // namespace TestCaseTracking
+
+using TestCaseTracking::ITracker;
+using TestCaseTracking::TrackerContext;
+using TestCaseTracking::SectionTracker;
+using TestCaseTracking::IndexTracker;
+
+} // namespace Catch
+
+// end catch_test_case_tracker.h
+
+// start catch_leak_detector.h
+
+namespace Catch {
+
+ struct LeakDetector {
+ LeakDetector();
+ };
+
+}
+// end catch_leak_detector.h
+// Cpp files will be included in the single-header file here
+// start catch_approx.cpp
+
+#include <cmath>
+#include <limits>
+
+namespace {
+
+// Performs equivalent check of std::fabs(lhs - rhs) <= margin
+// But without the subtraction to allow for INFINITY in comparison
+bool marginComparison(double lhs, double rhs, double margin) {
+ return (lhs + margin >= rhs) && (rhs + margin >= lhs);
+}
+
+}
+
+namespace Catch {
+namespace Detail {
+
+ Approx::Approx ( double value )
+ : m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
+ m_margin( 0.0 ),
+ m_scale( 0.0 ),
+ m_value( value )
+ {}
+
+ Approx Approx::custom() {
+ return Approx( 0 );
+ }
+
+ std::string Approx::toString() const {
+ ReusableStringStream rss;
+ rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
+ return rss.str();
+ }
+
+ bool Approx::equalityComparisonImpl(const double other) const {
+ // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
+ // Thanks to Richard Harris for his help refining the scaled margin value
+ return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value)));
+ }
+
+} // end namespace Detail
+
+std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
+ return value.toString();
+}
+
+} // end namespace Catch
+// end catch_approx.cpp
+// start catch_assertionhandler.cpp
+
+// start catch_context.h
+
+#include <memory>
+
+namespace Catch {
+
+ struct IResultCapture;
+ struct IRunner;
+ struct IConfig;
+ struct IMutableContext;
+
+ using IConfigPtr = std::shared_ptr<IConfig const>;
+
+ struct IContext
+ {
+ virtual ~IContext();
+
+ virtual IResultCapture* getResultCapture() = 0;
+ virtual IRunner* getRunner() = 0;
+ virtual IConfigPtr const& getConfig() const = 0;
+ };
+
+ struct IMutableContext : IContext
+ {
+ virtual ~IMutableContext();
+ virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
+ virtual void setRunner( IRunner* runner ) = 0;
+ virtual void setConfig( IConfigPtr const& config ) = 0;
+
+ private:
+ static IMutableContext *currentContext;
+ friend IMutableContext& getCurrentMutableContext();
+ friend void cleanUpContext();
+ static void createContext();
+ };
+
+ inline IMutableContext& getCurrentMutableContext()
+ {
+ if( !IMutableContext::currentContext )
+ IMutableContext::createContext();
+ return *IMutableContext::currentContext;
+ }
+
+ inline IContext& getCurrentContext()
+ {
+ return getCurrentMutableContext();
+ }
+
+ void cleanUpContext();
+}
+
+// end catch_context.h
+// start catch_debugger.h
+
+namespace Catch {
+ bool isDebuggerActive();
+}
+
+#ifdef CATCH_PLATFORM_MAC
+
+ #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
+
+#elif defined(CATCH_PLATFORM_LINUX)
+ // If we can use inline assembler, do it because this allows us to break
+ // directly at the location of the failing check instead of breaking inside
+ // raise() called from it, i.e. one stack frame below.
+ #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
+ #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */
+ #else // Fall back to the generic way.
+ #include <signal.h>
+
+ #define CATCH_TRAP() raise(SIGTRAP)
+ #endif
+#elif defined(_MSC_VER)
+ #define CATCH_TRAP() __debugbreak()
+#elif defined(__MINGW32__)
+ extern "C" __declspec(dllimport) void __stdcall DebugBreak();
+ #define CATCH_TRAP() DebugBreak()
+#endif
+
+#ifdef CATCH_TRAP
+ #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); }
+#else
+ namespace Catch {
+ inline void doNothing() {}
+ }
+ #define CATCH_BREAK_INTO_DEBUGGER() Catch::doNothing()
+#endif
+
+// end catch_debugger.h
+// start catch_run_context.h
+
+// start catch_fatal_condition.h
+
+// start catch_windows_h_proxy.h
+
+
+#if defined(CATCH_PLATFORM_WINDOWS)
+
+#if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
+# define CATCH_DEFINED_NOMINMAX
+# define NOMINMAX
+#endif
+#if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
+# define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+#endif
+
+#ifdef __AFXDLL
+#include <AfxWin.h>
+#else
+#include <windows.h>
+#endif
+
+#ifdef CATCH_DEFINED_NOMINMAX
+# undef NOMINMAX
+#endif
+#ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
+# undef WIN32_LEAN_AND_MEAN
+#endif
+
+#endif // defined(CATCH_PLATFORM_WINDOWS)
+
+// end catch_windows_h_proxy.h
+#if defined( CATCH_CONFIG_WINDOWS_SEH )
+
+namespace Catch {
+
+ struct FatalConditionHandler {
+
+ static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo);
+ FatalConditionHandler();
+ static void reset();
+ ~FatalConditionHandler();
+
+ private:
+ static bool isSet;
+ static ULONG guaranteeSize;
+ static PVOID exceptionHandlerHandle;
+ };
+
+} // namespace Catch
+
+#elif defined ( CATCH_CONFIG_POSIX_SIGNALS )
+
+#include <signal.h>
+
+namespace Catch {
+
+ struct FatalConditionHandler {
+
+ static bool isSet;
+ static struct sigaction oldSigActions[];
+ static stack_t oldSigStack;
+ static char altStackMem[];
+
+ static void handleSignal( int sig );
+
+ FatalConditionHandler();
+ ~FatalConditionHandler();
+ static void reset();
+ };
+
+} // namespace Catch
+
+#else
+
+namespace Catch {
+ struct FatalConditionHandler {
+ void reset();
+ };
+}
+
+#endif
+
+// end catch_fatal_condition.h
+#include <string>
+
+namespace Catch {
+
+ struct IMutableContext;
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ class RunContext : public IResultCapture, public IRunner {
+
+ public:
+ RunContext( RunContext const& ) = delete;
+ RunContext& operator =( RunContext const& ) = delete;
+
+ explicit RunContext( IConfigPtr const& _config, IStreamingReporterPtr&& reporter );
+
+ ~RunContext() override;
+
+ void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount );
+ void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount );
+
+ Totals runTest(TestCase const& testCase);
+
+ IConfigPtr config() const;
+ IStreamingReporter& reporter() const;
+
+ public: // IResultCapture
+
+ // Assertion handlers
+ void handleExpr
+ ( AssertionInfo const& info,
+ ITransientExpression const& expr,
+ AssertionReaction& reaction ) override;
+ void handleMessage
+ ( AssertionInfo const& info,
+ ResultWas::OfType resultType,
+ StringRef const& message,
+ AssertionReaction& reaction ) override;
+ void handleUnexpectedExceptionNotThrown
+ ( AssertionInfo const& info,
+ AssertionReaction& reaction ) override;
+ void handleUnexpectedInflightException
+ ( AssertionInfo const& info,
+ std::string const& message,
+ AssertionReaction& reaction ) override;
+ void handleIncomplete
+ ( AssertionInfo const& info ) override;
+ void handleNonExpr
+ ( AssertionInfo const &info,
+ ResultWas::OfType resultType,
+ AssertionReaction &reaction ) override;
+
+ bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) override;
+
+ void sectionEnded( SectionEndInfo const& endInfo ) override;
+ void sectionEndedEarly( SectionEndInfo const& endInfo ) override;
+
+ void benchmarkStarting( BenchmarkInfo const& info ) override;
+ void benchmarkEnded( BenchmarkStats const& stats ) override;
+
+ void pushScopedMessage( MessageInfo const& message ) override;
+ void popScopedMessage( MessageInfo const& message ) override;
+
+ std::string getCurrentTestName() const override;
+
+ const AssertionResult* getLastResult() const override;
+
+ void exceptionEarlyReported() override;
+
+ void handleFatalErrorCondition( StringRef message ) override;
+
+ bool lastAssertionPassed() override;
+
+ void assertionPassed() override;
+
+ public:
+ // !TBD We need to do this another way!
+ bool aborting() const final;
+
+ private:
+
+ void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr );
+ void invokeActiveTestCase();
+
+ void resetAssertionInfo();
+ bool testForMissingAssertions( Counts& assertions );
+
+ void assertionEnded( AssertionResult const& result );
+ void reportExpr
+ ( AssertionInfo const &info,
+ ResultWas::OfType resultType,
+ ITransientExpression const *expr,
+ bool negated );
+
+ void populateReaction( AssertionReaction& reaction );
+
+ private:
+
+ void handleUnfinishedSections();
+
+ TestRunInfo m_runInfo;
+ IMutableContext& m_context;
+ TestCase const* m_activeTestCase = nullptr;
+ ITracker* m_testCaseTracker;
+ Option<AssertionResult> m_lastResult;
+
+ IConfigPtr m_config;
+ Totals m_totals;
+ IStreamingReporterPtr m_reporter;
+ std::vector<MessageInfo> m_messages;
+ AssertionInfo m_lastAssertionInfo;
+ std::vector<SectionEndInfo> m_unfinishedSections;
+ std::vector<ITracker*> m_activeSections;
+ TrackerContext m_trackerContext;
+ bool m_lastAssertionPassed = false;
+ bool m_shouldReportUnexpected = true;
+ bool m_includeSuccessfulResults;
+ };
+
+} // end namespace Catch
+
+// end catch_run_context.h
+namespace Catch {
+
+ auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {
+ expr.streamReconstructedExpression( os );
+ return os;
+ }
+
+ LazyExpression::LazyExpression( bool isNegated )
+ : m_isNegated( isNegated )
+ {}
+
+ LazyExpression::LazyExpression( LazyExpression const& other ) : m_isNegated( other.m_isNegated ) {}
+
+ LazyExpression::operator bool() const {
+ return m_transientExpression != nullptr;
+ }
+
+ auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream& {
+ if( lazyExpr.m_isNegated )
+ os << "!";
+
+ if( lazyExpr ) {
+ if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() )
+ os << "(" << *lazyExpr.m_transientExpression << ")";
+ else
+ os << *lazyExpr.m_transientExpression;
+ }
+ else {
+ os << "{** error - unchecked empty expression requested **}";
+ }
+ return os;
+ }
+
+ AssertionHandler::AssertionHandler
+ ( StringRef macroName,
+ SourceLineInfo const& lineInfo,
+ StringRef capturedExpression,
+ ResultDisposition::Flags resultDisposition )
+ : m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition },
+ m_resultCapture( getResultCapture() )
+ {}
+
+ void AssertionHandler::handleExpr( ITransientExpression const& expr ) {
+ m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction );
+ }
+ void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const& message) {
+ m_resultCapture.handleMessage( m_assertionInfo, resultType, message, m_reaction );
+ }
+
+ auto AssertionHandler::allowThrows() const -> bool {
+ return getCurrentContext().getConfig()->allowThrows();
+ }
+
+ void AssertionHandler::complete() {
+ setCompleted();
+ if( m_reaction.shouldDebugBreak ) {
+
+ // If you find your debugger stopping you here then go one level up on the
+ // call-stack for the code that caused it (typically a failed assertion)
+
+ // (To go back to the test and change execution, jump over the throw, next)
+ CATCH_BREAK_INTO_DEBUGGER();
+ }
+ if( m_reaction.shouldThrow )
+ throw Catch::TestFailureException();
+ }
+ void AssertionHandler::setCompleted() {
+ m_completed = true;
+ }
+
+ void AssertionHandler::handleUnexpectedInflightException() {
+ m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction );
+ }
+
+ void AssertionHandler::handleExceptionThrownAsExpected() {
+ m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
+ }
+ void AssertionHandler::handleExceptionNotThrownAsExpected() {
+ m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
+ }
+
+ void AssertionHandler::handleUnexpectedExceptionNotThrown() {
+ m_resultCapture.handleUnexpectedExceptionNotThrown( m_assertionInfo, m_reaction );
+ }
+
+ void AssertionHandler::handleThrowingCallSkipped() {
+ m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
+ }
+
+ // This is the overload that takes a string and infers the Equals matcher from it
+ // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp
+ void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef matcherString ) {
+ handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString );
+ }
+
+} // namespace Catch
+// end catch_assertionhandler.cpp
+// start catch_assertionresult.cpp
+
+namespace Catch {
+ AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const & _lazyExpression):
+ lazyExpression(_lazyExpression),
+ resultType(_resultType) {}
+
+ std::string AssertionResultData::reconstructExpression() const {
+
+ if( reconstructedExpression.empty() ) {
+ if( lazyExpression ) {
+ ReusableStringStream rss;
+ rss << lazyExpression;
+ reconstructedExpression = rss.str();
+ }
+ }
+ return reconstructedExpression;
+ }
+
+ AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
+ : m_info( info ),
+ m_resultData( data )
+ {}
+
+ // Result was a success
+ bool AssertionResult::succeeded() const {
+ return Catch::isOk( m_resultData.resultType );
+ }
+
+ // Result was a success, or failure is suppressed
+ bool AssertionResult::isOk() const {
+ return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
+ }
+
+ ResultWas::OfType AssertionResult::getResultType() const {
+ return m_resultData.resultType;
+ }
+
+ bool AssertionResult::hasExpression() const {
+ return m_info.capturedExpression[0] != 0;
+ }
+
+ bool AssertionResult::hasMessage() const {
+ return !m_resultData.message.empty();
+ }
+
+ std::string AssertionResult::getExpression() const {
+ if( isFalseTest( m_info.resultDisposition ) )
+ return "!(" + m_info.capturedExpression + ")";
+ else
+ return m_info.capturedExpression;
+ }
+
+ std::string AssertionResult::getExpressionInMacro() const {
+ std::string expr;
+ if( m_info.macroName[0] == 0 )
+ expr = m_info.capturedExpression;
+ else {
+ expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );
+ expr += m_info.macroName;
+ expr += "( ";
+ expr += m_info.capturedExpression;
+ expr += " )";
+ }
+ return expr;
+ }
+
+ bool AssertionResult::hasExpandedExpression() const {
+ return hasExpression() && getExpandedExpression() != getExpression();
+ }
+
+ std::string AssertionResult::getExpandedExpression() const {
+ std::string expr = m_resultData.reconstructExpression();
+ return expr.empty()
+ ? getExpression()
+ : expr;
+ }
+
+ std::string AssertionResult::getMessage() const {
+ return m_resultData.message;
+ }
+ SourceLineInfo AssertionResult::getSourceInfo() const {
+ return m_info.lineInfo;
+ }
+
+ StringRef AssertionResult::getTestMacroName() const {
+ return m_info.macroName;
+ }
+
+} // end namespace Catch
+// end catch_assertionresult.cpp
+// start catch_benchmark.cpp
+
+namespace Catch {
+
+ auto BenchmarkLooper::getResolution() -> uint64_t {
+ return getEstimatedClockResolution() * getCurrentContext().getConfig()->benchmarkResolutionMultiple();
+ }
+
+ void BenchmarkLooper::reportStart() {
+ getResultCapture().benchmarkStarting( { m_name } );
+ }
+ auto BenchmarkLooper::needsMoreIterations() -> bool {
+ auto elapsed = m_timer.getElapsedNanoseconds();
+
+ // Exponentially increasing iterations until we're confident in our timer resolution
+ if( elapsed < m_resolution ) {
+ m_iterationsToRun *= 10;
+ return true;
+ }
+
+ getResultCapture().benchmarkEnded( { { m_name }, m_count, elapsed } );
+ return false;
+ }
+
+} // end namespace Catch
+// end catch_benchmark.cpp
+// start catch_capture_matchers.cpp
+
+namespace Catch {
+
+ using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
+
+ // This is the general overload that takes a any string matcher
+ // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers
+ // the Equals matcher (so the header does not mention matchers)
+ void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef matcherString ) {
+ std::string exceptionMessage = Catch::translateActiveException();
+ MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString );
+ handler.handleExpr( expr );
+ }
+
+} // namespace Catch
+// end catch_capture_matchers.cpp
+// start catch_commandline.cpp
+
+// start catch_commandline.h
+
+// start catch_clara.h
+
+// Use Catch's value for console width (store Clara's off to the side, if present)
+#ifdef CLARA_CONFIG_CONSOLE_WIDTH
+#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
+#undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
+#endif
+#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wweak-vtables"
+#pragma clang diagnostic ignored "-Wexit-time-destructors"
+#pragma clang diagnostic ignored "-Wshadow"
+#endif
+
+// start clara.hpp
+// Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See https://github.com/philsquared/Clara for more details
+
+// Clara v1.1.4
+
+
+#ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH
+#define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80
+#endif
+
+#ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
+#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH
+#endif
+
+#ifndef CLARA_CONFIG_OPTIONAL_TYPE
+#ifdef __has_include
+#if __has_include(<optional>) && __cplusplus >= 201703L
+#include <optional>
+#define CLARA_CONFIG_OPTIONAL_TYPE std::optional
+#endif
+#endif
+#endif
+
+// ----------- #included from clara_textflow.hpp -----------
+
+// TextFlowCpp
+//
+// A single-header library for wrapping and laying out basic text, by Phil Nash
+//
+// This work is licensed under the BSD 2-Clause license.
+// See the accompanying LICENSE file, or the one at https://opensource.org/licenses/BSD-2-Clause
+//
+// This project is hosted at https://github.com/philsquared/textflowcpp
+
+
+#include <cassert>
+#include <ostream>
+#include <sstream>
+#include <vector>
+
+#ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
+#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80
+#endif
+
+namespace Catch { namespace clara { namespace TextFlow {
+
+ inline auto isWhitespace( char c ) -> bool {
+ static std::string chars = " \t\n\r";
+ return chars.find( c ) != std::string::npos;
+ }
+ inline auto isBreakableBefore( char c ) -> bool {
+ static std::string chars = "[({<|";
+ return chars.find( c ) != std::string::npos;
+ }
+ inline auto isBreakableAfter( char c ) -> bool {
+ static std::string chars = "])}>.,:;*+-=&/\\";
+ return chars.find( c ) != std::string::npos;
+ }
+
+ class Columns;
+
+ class Column {
+ std::vector<std::string> m_strings;
+ size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
+ size_t m_indent = 0;
+ size_t m_initialIndent = std::string::npos;
+
+ public:
+ class iterator {
+ friend Column;
+
+ Column const& m_column;
+ size_t m_stringIndex = 0;
+ size_t m_pos = 0;
+
+ size_t m_len = 0;
+ size_t m_end = 0;
+ bool m_suffix = false;
+
+ iterator( Column const& column, size_t stringIndex )
+ : m_column( column ),
+ m_stringIndex( stringIndex )
+ {}
+
+ auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; }
+
+ auto isBoundary( size_t at ) const -> bool {
+ assert( at > 0 );
+ assert( at <= line().size() );
+
+ return at == line().size() ||
+ ( isWhitespace( line()[at] ) && !isWhitespace( line()[at-1] ) ) ||
+ isBreakableBefore( line()[at] ) ||
+ isBreakableAfter( line()[at-1] );
+ }
+
+ void calcLength() {
+ assert( m_stringIndex < m_column.m_strings.size() );
+
+ m_suffix = false;
+ auto width = m_column.m_width-indent();
+ m_end = m_pos;
+ while( m_end < line().size() && line()[m_end] != '\n' )
+ ++m_end;
+
+ if( m_end < m_pos + width ) {
+ m_len = m_end - m_pos;
+ }
+ else {
+ size_t len = width;
+ while (len > 0 && !isBoundary(m_pos + len))
+ --len;
+ while (len > 0 && isWhitespace( line()[m_pos + len - 1] ))
+ --len;
+
+ if (len > 0) {
+ m_len = len;
+ } else {
+ m_suffix = true;
+ m_len = width - 1;
+ }
+ }
+ }
+
+ auto indent() const -> size_t {
+ auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;
+ return initial == std::string::npos ? m_column.m_indent : initial;
+ }
+
+ auto addIndentAndSuffix(std::string const &plain) const -> std::string {
+ return std::string( indent(), ' ' ) + (m_suffix ? plain + "-" : plain);
+ }
+
+ public:
+ explicit iterator( Column const& column ) : m_column( column ) {
+ assert( m_column.m_width > m_column.m_indent );
+ assert( m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent );
+ calcLength();
+ if( m_len == 0 )
+ m_stringIndex++; // Empty string
+ }
+
+ auto operator *() const -> std::string {
+ assert( m_stringIndex < m_column.m_strings.size() );
+ assert( m_pos <= m_end );
+ if( m_pos + m_column.m_width < m_end )
+ return addIndentAndSuffix(line().substr(m_pos, m_len));
+ else
+ return addIndentAndSuffix(line().substr(m_pos, m_end - m_pos));
+ }
+
+ auto operator ++() -> iterator& {
+ m_pos += m_len;
+ if( m_pos < line().size() && line()[m_pos] == '\n' )
+ m_pos += 1;
+ else
+ while( m_pos < line().size() && isWhitespace( line()[m_pos] ) )
+ ++m_pos;
+
+ if( m_pos == line().size() ) {
+ m_pos = 0;
+ ++m_stringIndex;
+ }
+ if( m_stringIndex < m_column.m_strings.size() )
+ calcLength();
+ return *this;
+ }
+ auto operator ++(int) -> iterator {
+ iterator prev( *this );
+ operator++();
+ return prev;
+ }
+
+ auto operator ==( iterator const& other ) const -> bool {
+ return
+ m_pos == other.m_pos &&
+ m_stringIndex == other.m_stringIndex &&
+ &m_column == &other.m_column;
+ }
+ auto operator !=( iterator const& other ) const -> bool {
+ return !operator==( other );
+ }
+ };
+ using const_iterator = iterator;
+
+ explicit Column( std::string const& text ) { m_strings.push_back( text ); }
+
+ auto width( size_t newWidth ) -> Column& {
+ assert( newWidth > 0 );
+ m_width = newWidth;
+ return *this;
+ }
+ auto indent( size_t newIndent ) -> Column& {
+ m_indent = newIndent;
+ return *this;
+ }
+ auto initialIndent( size_t newIndent ) -> Column& {
+ m_initialIndent = newIndent;
+ return *this;
+ }
+
+ auto width() const -> size_t { return m_width; }
+ auto begin() const -> iterator { return iterator( *this ); }
+ auto end() const -> iterator { return { *this, m_strings.size() }; }
+
+ inline friend std::ostream& operator << ( std::ostream& os, Column const& col ) {
+ bool first = true;
+ for( auto line : col ) {
+ if( first )
+ first = false;
+ else
+ os << "\n";
+ os << line;
+ }
+ return os;
+ }
+
+ auto operator + ( Column const& other ) -> Columns;
+
+ auto toString() const -> std::string {
+ std::ostringstream oss;
+ oss << *this;
+ return oss.str();
+ }
+ };
+
+ class Spacer : public Column {
+
+ public:
+ explicit Spacer( size_t spaceWidth ) : Column( "" ) {
+ width( spaceWidth );
+ }
+ };
+
+ class Columns {
+ std::vector<Column> m_columns;
+
+ public:
+
+ class iterator {
+ friend Columns;
+ struct EndTag {};
+
+ std::vector<Column> const& m_columns;
+ std::vector<Column::iterator> m_iterators;
+ size_t m_activeIterators;
+
+ iterator( Columns const& columns, EndTag )
+ : m_columns( columns.m_columns ),
+ m_activeIterators( 0 )
+ {
+ m_iterators.reserve( m_columns.size() );
+
+ for( auto const& col : m_columns )
+ m_iterators.push_back( col.end() );
+ }
+
+ public:
+ explicit iterator( Columns const& columns )
+ : m_columns( columns.m_columns ),
+ m_activeIterators( m_columns.size() )
+ {
+ m_iterators.reserve( m_columns.size() );
+
+ for( auto const& col : m_columns )
+ m_iterators.push_back( col.begin() );
+ }
+
+ auto operator ==( iterator const& other ) const -> bool {
+ return m_iterators == other.m_iterators;
+ }
+ auto operator !=( iterator const& other ) const -> bool {
+ return m_iterators != other.m_iterators;
+ }
+ auto operator *() const -> std::string {
+ std::string row, padding;
+
+ for( size_t i = 0; i < m_columns.size(); ++i ) {
+ auto width = m_columns[i].width();
+ if( m_iterators[i] != m_columns[i].end() ) {
+ std::string col = *m_iterators[i];
+ row += padding + col;
+ if( col.size() < width )
+ padding = std::string( width - col.size(), ' ' );
+ else
+ padding = "";
+ }
+ else {
+ padding += std::string( width, ' ' );
+ }
+ }
+ return row;
+ }
+ auto operator ++() -> iterator& {
+ for( size_t i = 0; i < m_columns.size(); ++i ) {
+ if (m_iterators[i] != m_columns[i].end())
+ ++m_iterators[i];
+ }
+ return *this;
+ }
+ auto operator ++(int) -> iterator {
+ iterator prev( *this );
+ operator++();
+ return prev;
+ }
+ };
+ using const_iterator = iterator;
+
+ auto begin() const -> iterator { return iterator( *this ); }
+ auto end() const -> iterator { return { *this, iterator::EndTag() }; }
+
+ auto operator += ( Column const& col ) -> Columns& {
+ m_columns.push_back( col );
+ return *this;
+ }
+ auto operator + ( Column const& col ) -> Columns {
+ Columns combined = *this;
+ combined += col;
+ return combined;
+ }
+
+ inline friend std::ostream& operator << ( std::ostream& os, Columns const& cols ) {
+
+ bool first = true;
+ for( auto line : cols ) {
+ if( first )
+ first = false;
+ else
+ os << "\n";
+ os << line;
+ }
+ return os;
+ }
+
+ auto toString() const -> std::string {
+ std::ostringstream oss;
+ oss << *this;
+ return oss.str();
+ }
+ };
+
+ inline auto Column::operator + ( Column const& other ) -> Columns {
+ Columns cols;
+ cols += *this;
+ cols += other;
+ return cols;
+ }
+}}} // namespace Catch::clara::TextFlow
+
+// ----------- end of #include from clara_textflow.hpp -----------
+// ........... back in clara.hpp
+
+#include <memory>
+#include <set>
+#include <algorithm>
+
+#if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) )
+#define CATCH_PLATFORM_WINDOWS
+#endif
+
+namespace Catch { namespace clara {
+namespace detail {
+
+ // Traits for extracting arg and return type of lambdas (for single argument lambdas)
+ template<typename L>
+ struct UnaryLambdaTraits : UnaryLambdaTraits<decltype( &L::operator() )> {};
+
+ template<typename ClassT, typename ReturnT, typename... Args>
+ struct UnaryLambdaTraits<ReturnT( ClassT::* )( Args... ) const> {
+ static const bool isValid = false;
+ };
+
+ template<typename ClassT, typename ReturnT, typename ArgT>
+ struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {
+ static const bool isValid = true;
+ using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;
+ using ReturnType = ReturnT;
+ };
+
+ class TokenStream;
+
+ // Transport for raw args (copied from main args, or supplied via init list for testing)
+ class Args {
+ friend TokenStream;
+ std::string m_exeName;
+ std::vector<std::string> m_args;
+
+ public:
+ Args( int argc, char const* const* argv )
+ : m_exeName(argv[0]),
+ m_args(argv + 1, argv + argc) {}
+
+ Args( std::initializer_list<std::string> args )
+ : m_exeName( *args.begin() ),
+ m_args( args.begin()+1, args.end() )
+ {}
+
+ auto exeName() const -> std::string {
+ return m_exeName;
+ }
+ };
+
+ // Wraps a token coming from a token stream. These may not directly correspond to strings as a single string
+ // may encode an option + its argument if the : or = form is used
+ enum class TokenType {
+ Option, Argument
+ };
+ struct Token {
+ TokenType type;
+ std::string token;
+ };
+
+ inline auto isOptPrefix( char c ) -> bool {
+ return c == '-'
+#ifdef CATCH_PLATFORM_WINDOWS
+ || c == '/'
+#endif
+ ;
+ }
+
+ // Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
+ class TokenStream {
+ using Iterator = std::vector<std::string>::const_iterator;
+ Iterator it;
+ Iterator itEnd;
+ std::vector<Token> m_tokenBuffer;
+
+ void loadBuffer() {
+ m_tokenBuffer.resize( 0 );
+
+ // Skip any empty strings
+ while( it != itEnd && it->empty() )
+ ++it;
+
+ if( it != itEnd ) {
+ auto const &next = *it;
+ if( isOptPrefix( next[0] ) ) {
+ auto delimiterPos = next.find_first_of( " :=" );
+ if( delimiterPos != std::string::npos ) {
+ m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );
+ m_tokenBuffer.push_back( { TokenType::Argument, next.substr( delimiterPos + 1 ) } );
+ } else {
+ if( next[1] != '-' && next.size() > 2 ) {
+ std::string opt = "- ";
+ for( size_t i = 1; i < next.size(); ++i ) {
+ opt[1] = next[i];
+ m_tokenBuffer.push_back( { TokenType::Option, opt } );
+ }
+ } else {
+ m_tokenBuffer.push_back( { TokenType::Option, next } );
+ }
+ }
+ } else {
+ m_tokenBuffer.push_back( { TokenType::Argument, next } );
+ }
+ }
+ }
+
+ public:
+ explicit TokenStream( Args const &args ) : TokenStream( args.m_args.begin(), args.m_args.end() ) {}
+
+ TokenStream( Iterator it, Iterator itEnd ) : it( it ), itEnd( itEnd ) {
+ loadBuffer();
+ }
+
+ explicit operator bool() const {
+ return !m_tokenBuffer.empty() || it != itEnd;
+ }
+
+ auto count() const -> size_t { return m_tokenBuffer.size() + (itEnd - it); }
+
+ auto operator*() const -> Token {
+ assert( !m_tokenBuffer.empty() );
+ return m_tokenBuffer.front();
+ }
+
+ auto operator->() const -> Token const * {
+ assert( !m_tokenBuffer.empty() );
+ return &m_tokenBuffer.front();
+ }
+
+ auto operator++() -> TokenStream & {
+ if( m_tokenBuffer.size() >= 2 ) {
+ m_tokenBuffer.erase( m_tokenBuffer.begin() );
+ } else {
+ if( it != itEnd )
+ ++it;
+ loadBuffer();
+ }
+ return *this;
+ }
+ };
+
+ class ResultBase {
+ public:
+ enum Type {
+ Ok, LogicError, RuntimeError
+ };
+
+ protected:
+ ResultBase( Type type ) : m_type( type ) {}
+ virtual ~ResultBase() = default;
+
+ virtual void enforceOk() const = 0;
+
+ Type m_type;
+ };
+
+ template<typename T>
+ class ResultValueBase : public ResultBase {
+ public:
+ auto value() const -> T const & {
+ enforceOk();
+ return m_value;
+ }
+
+ protected:
+ ResultValueBase( Type type ) : ResultBase( type ) {}
+
+ ResultValueBase( ResultValueBase const &other ) : ResultBase( other ) {
+ if( m_type == ResultBase::Ok )
+ new( &m_value ) T( other.m_value );
+ }
+
+ ResultValueBase( Type, T const &value ) : ResultBase( Ok ) {
+ new( &m_value ) T( value );
+ }
+
+ auto operator=( ResultValueBase const &other ) -> ResultValueBase & {
+ if( m_type == ResultBase::Ok )
+ m_value.~T();
+ ResultBase::operator=(other);
+ if( m_type == ResultBase::Ok )
+ new( &m_value ) T( other.m_value );
+ return *this;
+ }
+
+ ~ResultValueBase() override {
+ if( m_type == Ok )
+ m_value.~T();
+ }
+
+ union {
+ T m_value;
+ };
+ };
+
+ template<>
+ class ResultValueBase<void> : public ResultBase {
+ protected:
+ using ResultBase::ResultBase;
+ };
+
+ template<typename T = void>
+ class BasicResult : public ResultValueBase<T> {
+ public:
+ template<typename U>
+ explicit BasicResult( BasicResult<U> const &other )
+ : ResultValueBase<T>( other.type() ),
+ m_errorMessage( other.errorMessage() )
+ {
+ assert( type() != ResultBase::Ok );
+ }
+
+ template<typename U>
+ static auto ok( U const &value ) -> BasicResult { return { ResultBase::Ok, value }; }
+ static auto ok() -> BasicResult { return { ResultBase::Ok }; }
+ static auto logicError( std::string const &message ) -> BasicResult { return { ResultBase::LogicError, message }; }
+ static auto runtimeError( std::string const &message ) -> BasicResult { return { ResultBase::RuntimeError, message }; }
+
+ explicit operator bool() const { return m_type == ResultBase::Ok; }
+ auto type() const -> ResultBase::Type { return m_type; }
+ auto errorMessage() const -> std::string { return m_errorMessage; }
+
+ protected:
+ void enforceOk() const override {
+
+ // Errors shouldn't reach this point, but if they do
+ // the actual error message will be in m_errorMessage
+ assert( m_type != ResultBase::LogicError );
+ assert( m_type != ResultBase::RuntimeError );
+ if( m_type != ResultBase::Ok )
+ std::abort();
+ }
+
+ std::string m_errorMessage; // Only populated if resultType is an error
+
+ BasicResult( ResultBase::Type type, std::string const &message )
+ : ResultValueBase<T>(type),
+ m_errorMessage(message)
+ {
+ assert( m_type != ResultBase::Ok );
+ }
+
+ using ResultValueBase<T>::ResultValueBase;
+ using ResultBase::m_type;
+ };
+
+ enum class ParseResultType {
+ Matched, NoMatch, ShortCircuitAll, ShortCircuitSame
+ };
+
+ class ParseState {
+ public:
+
+ ParseState( ParseResultType type, TokenStream const &remainingTokens )
+ : m_type(type),
+ m_remainingTokens( remainingTokens )
+ {}
+
+ auto type() const -> ParseResultType { return m_type; }
+ auto remainingTokens() const -> TokenStream { return m_remainingTokens; }
+
+ private:
+ ParseResultType m_type;
+ TokenStream m_remainingTokens;
+ };
+
+ using Result = BasicResult<void>;
+ using ParserResult = BasicResult<ParseResultType>;
+ using InternalParseResult = BasicResult<ParseState>;
+
+ struct HelpColumns {
+ std::string left;
+ std::string right;
+ };
+
+ template<typename T>
+ inline auto convertInto( std::string const &source, T& target ) -> ParserResult {
+ std::stringstream ss;
+ ss << source;
+ ss >> target;
+ if( ss.fail() )
+ return ParserResult::runtimeError( "Unable to convert '" + source + "' to destination type" );
+ else
+ return ParserResult::ok( ParseResultType::Matched );
+ }
+ inline auto convertInto( std::string const &source, std::string& target ) -> ParserResult {
+ target = source;
+ return ParserResult::ok( ParseResultType::Matched );
+ }
+ inline auto convertInto( std::string const &source, bool &target ) -> ParserResult {
+ std::string srcLC = source;
+ std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( char c ) { return static_cast<char>( ::tolower(c) ); } );
+ if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on")
+ target = true;
+ else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")
+ target = false;
+ else
+ return ParserResult::runtimeError( "Expected a boolean value but did not recognise: '" + source + "'" );
+ return ParserResult::ok( ParseResultType::Matched );
+ }
+#ifdef CLARA_CONFIG_OPTIONAL_TYPE
+ template<typename T>
+ inline auto convertInto( std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T>& target ) -> ParserResult {
+ T temp;
+ auto result = convertInto( source, temp );
+ if( result )
+ target = std::move(temp);
+ return result;
+ }
+#endif // CLARA_CONFIG_OPTIONAL_TYPE
+
+ struct NonCopyable {
+ NonCopyable() = default;
+ NonCopyable( NonCopyable const & ) = delete;
+ NonCopyable( NonCopyable && ) = delete;
+ NonCopyable &operator=( NonCopyable const & ) = delete;
+ NonCopyable &operator=( NonCopyable && ) = delete;
+ };
+
+ struct BoundRef : NonCopyable {
+ virtual ~BoundRef() = default;
+ virtual auto isContainer() const -> bool { return false; }
+ virtual auto isFlag() const -> bool { return false; }
+ };
+ struct BoundValueRefBase : BoundRef {
+ virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
+ };
+ struct BoundFlagRefBase : BoundRef {
+ virtual auto setFlag( bool flag ) -> ParserResult = 0;
+ virtual auto isFlag() const -> bool { return true; }
+ };
+
+ template<typename T>
+ struct BoundValueRef : BoundValueRefBase {
+ T &m_ref;
+
+ explicit BoundValueRef( T &ref ) : m_ref( ref ) {}
+
+ auto setValue( std::string const &arg ) -> ParserResult override {
+ return convertInto( arg, m_ref );
+ }
+ };
+
+ template<typename T>
+ struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
+ std::vector<T> &m_ref;
+
+ explicit BoundValueRef( std::vector<T> &ref ) : m_ref( ref ) {}
+
+ auto isContainer() const -> bool override { return true; }
+
+ auto setValue( std::string const &arg ) -> ParserResult override {
+ T temp;
+ auto result = convertInto( arg, temp );
+ if( result )
+ m_ref.push_back( temp );
+ return result;
+ }
+ };
+
+ struct BoundFlagRef : BoundFlagRefBase {
+ bool &m_ref;
+
+ explicit BoundFlagRef( bool &ref ) : m_ref( ref ) {}
+
+ auto setFlag( bool flag ) -> ParserResult override {
+ m_ref = flag;
+ return ParserResult::ok( ParseResultType::Matched );
+ }
+ };
+
+ template<typename ReturnType>
+ struct LambdaInvoker {
+ static_assert( std::is_same<ReturnType, ParserResult>::value, "Lambda must return void or clara::ParserResult" );
+
+ template<typename L, typename ArgType>
+ static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
+ return lambda( arg );
+ }
+ };
+
+ template<>
+ struct LambdaInvoker<void> {
+ template<typename L, typename ArgType>
+ static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
+ lambda( arg );
+ return ParserResult::ok( ParseResultType::Matched );
+ }
+ };
+
+ template<typename ArgType, typename L>
+ inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
+ ArgType temp{};
+ auto result = convertInto( arg, temp );
+ return !result
+ ? result
+ : LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );
+ }
+
+ template<typename L>
+ struct BoundLambda : BoundValueRefBase {
+ L m_lambda;
+
+ static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
+ explicit BoundLambda( L const &lambda ) : m_lambda( lambda ) {}
+
+ auto setValue( std::string const &arg ) -> ParserResult override {
+ return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>( m_lambda, arg );
+ }
+ };
+
+ template<typename L>
+ struct BoundFlagLambda : BoundFlagRefBase {
+ L m_lambda;
+
+ static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
+ static_assert( std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value, "flags must be boolean" );
+
+ explicit BoundFlagLambda( L const &lambda ) : m_lambda( lambda ) {}
+
+ auto setFlag( bool flag ) -> ParserResult override {
+ return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( m_lambda, flag );
+ }
+ };
+
+ enum class Optionality { Optional, Required };
+
+ struct Parser;
+
+ class ParserBase {
+ public:
+ virtual ~ParserBase() = default;
+ virtual auto validate() const -> Result { return Result::ok(); }
+ virtual auto parse( std::string const& exeName, TokenStream const &tokens) const -> InternalParseResult = 0;
+ virtual auto cardinality() const -> size_t { return 1; }
+
+ auto parse( Args const &args ) const -> InternalParseResult {
+ return parse( args.exeName(), TokenStream( args ) );
+ }
+ };
+
+ template<typename DerivedT>
+ class ComposableParserImpl : public ParserBase {
+ public:
+ template<typename T>
+ auto operator|( T const &other ) const -> Parser;
+
+ template<typename T>
+ auto operator+( T const &other ) const -> Parser;
+ };
+
+ // Common code and state for Args and Opts
+ template<typename DerivedT>
+ class ParserRefImpl : public ComposableParserImpl<DerivedT> {
+ protected:
+ Optionality m_optionality = Optionality::Optional;
+ std::shared_ptr<BoundRef> m_ref;
+ std::string m_hint;
+ std::string m_description;
+
+ explicit ParserRefImpl( std::shared_ptr<BoundRef> const &ref ) : m_ref( ref ) {}
+
+ public:
+ template<typename T>
+ ParserRefImpl( T &ref, std::string const &hint )
+ : m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),
+ m_hint( hint )
+ {}
+
+ template<typename LambdaT>
+ ParserRefImpl( LambdaT const &ref, std::string const &hint )
+ : m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ),
+ m_hint(hint)
+ {}
+
+ auto operator()( std::string const &description ) -> DerivedT & {
+ m_description = description;
+ return static_cast<DerivedT &>( *this );
+ }
+
+ auto optional() -> DerivedT & {
+ m_optionality = Optionality::Optional;
+ return static_cast<DerivedT &>( *this );
+ };
+
+ auto required() -> DerivedT & {
+ m_optionality = Optionality::Required;
+ return static_cast<DerivedT &>( *this );
+ };
+
+ auto isOptional() const -> bool {
+ return m_optionality == Optionality::Optional;
+ }
+
+ auto cardinality() const -> size_t override {
+ if( m_ref->isContainer() )
+ return 0;
+ else
+ return 1;
+ }
+
+ auto hint() const -> std::string { return m_hint; }
+ };
+
+ class ExeName : public ComposableParserImpl<ExeName> {
+ std::shared_ptr<std::string> m_name;
+ std::shared_ptr<BoundValueRefBase> m_ref;
+
+ template<typename LambdaT>
+ static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> {
+ return std::make_shared<BoundLambda<LambdaT>>( lambda) ;
+ }
+
+ public:
+ ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {}
+
+ explicit ExeName( std::string &ref ) : ExeName() {
+ m_ref = std::make_shared<BoundValueRef<std::string>>( ref );
+ }
+
+ template<typename LambdaT>
+ explicit ExeName( LambdaT const& lambda ) : ExeName() {
+ m_ref = std::make_shared<BoundLambda<LambdaT>>( lambda );
+ }
+
+ // The exe name is not parsed out of the normal tokens, but is handled specially
+ auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
+ return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
+ }
+
+ auto name() const -> std::string { return *m_name; }
+ auto set( std::string const& newName ) -> ParserResult {
+
+ auto lastSlash = newName.find_last_of( "\\/" );
+ auto filename = ( lastSlash == std::string::npos )
+ ? newName
+ : newName.substr( lastSlash+1 );
+
+ *m_name = filename;
+ if( m_ref )
+ return m_ref->setValue( filename );
+ else
+ return ParserResult::ok( ParseResultType::Matched );
+ }
+ };
+
+ class Arg : public ParserRefImpl<Arg> {
+ public:
+ using ParserRefImpl::ParserRefImpl;
+
+ auto parse( std::string const &, TokenStream const &tokens ) const -> InternalParseResult override {
+ auto validationResult = validate();
+ if( !validationResult )
+ return InternalParseResult( validationResult );
+
+ auto remainingTokens = tokens;
+ auto const &token = *remainingTokens;
+ if( token.type != TokenType::Argument )
+ return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
+
+ assert( !m_ref->isFlag() );
+ auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
+
+ auto result = valueRef->setValue( remainingTokens->token );
+ if( !result )
+ return InternalParseResult( result );
+ else
+ return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
+ }
+ };
+
+ inline auto normaliseOpt( std::string const &optName ) -> std::string {
+#ifdef CATCH_PLATFORM_WINDOWS
+ if( optName[0] == '/' )
+ return "-" + optName.substr( 1 );
+ else
+#endif
+ return optName;
+ }
+
+ class Opt : public ParserRefImpl<Opt> {
+ protected:
+ std::vector<std::string> m_optNames;
+
+ public:
+ template<typename LambdaT>
+ explicit Opt( LambdaT const &ref ) : ParserRefImpl( std::make_shared<BoundFlagLambda<LambdaT>>( ref ) ) {}
+
+ explicit Opt( bool &ref ) : ParserRefImpl( std::make_shared<BoundFlagRef>( ref ) ) {}
+
+ template<typename LambdaT>
+ Opt( LambdaT const &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
+
+ template<typename T>
+ Opt( T &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
+
+ auto operator[]( std::string const &optName ) -> Opt & {
+ m_optNames.push_back( optName );
+ return *this;
+ }
+
+ auto getHelpColumns() const -> std::vector<HelpColumns> {
+ std::ostringstream oss;
+ bool first = true;
+ for( auto const &opt : m_optNames ) {
+ if (first)
+ first = false;
+ else
+ oss << ", ";
+ oss << opt;
+ }
+ if( !m_hint.empty() )
+ oss << " <" << m_hint << ">";
+ return { { oss.str(), m_description } };
+ }
+
+ auto isMatch( std::string const &optToken ) const -> bool {
+ auto normalisedToken = normaliseOpt( optToken );
+ for( auto const &name : m_optNames ) {
+ if( normaliseOpt( name ) == normalisedToken )
+ return true;
+ }
+ return false;
+ }
+
+ using ParserBase::parse;
+
+ auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
+ auto validationResult = validate();
+ if( !validationResult )
+ return InternalParseResult( validationResult );
+
+ auto remainingTokens = tokens;
+ if( remainingTokens && remainingTokens->type == TokenType::Option ) {
+ auto const &token = *remainingTokens;
+ if( isMatch(token.token ) ) {
+ if( m_ref->isFlag() ) {
+ auto flagRef = static_cast<detail::BoundFlagRefBase*>( m_ref.get() );
+ auto result = flagRef->setFlag( true );
+ if( !result )
+ return InternalParseResult( result );
+ if( result.value() == ParseResultType::ShortCircuitAll )
+ return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
+ } else {
+ auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
+ ++remainingTokens;
+ if( !remainingTokens )
+ return InternalParseResult::runtimeError( "Expected argument following " + token.token );
+ auto const &argToken = *remainingTokens;
+ if( argToken.type != TokenType::Argument )
+ return InternalParseResult::runtimeError( "Expected argument following " + token.token );
+ auto result = valueRef->setValue( argToken.token );
+ if( !result )
+ return InternalParseResult( result );
+ if( result.value() == ParseResultType::ShortCircuitAll )
+ return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
+ }
+ return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
+ }
+ }
+ return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
+ }
+
+ auto validate() const -> Result override {
+ if( m_optNames.empty() )
+ return Result::logicError( "No options supplied to Opt" );
+ for( auto const &name : m_optNames ) {
+ if( name.empty() )
+ return Result::logicError( "Option name cannot be empty" );
+#ifdef CATCH_PLATFORM_WINDOWS
+ if( name[0] != '-' && name[0] != '/' )
+ return Result::logicError( "Option name must begin with '-' or '/'" );
+#else
+ if( name[0] != '-' )
+ return Result::logicError( "Option name must begin with '-'" );
+#endif
+ }
+ return ParserRefImpl::validate();
+ }
+ };
+
+ struct Help : Opt {
+ Help( bool &showHelpFlag )
+ : Opt([&]( bool flag ) {
+ showHelpFlag = flag;
+ return ParserResult::ok( ParseResultType::ShortCircuitAll );
+ })
+ {
+ static_cast<Opt &>( *this )
+ ("display usage information")
+ ["-?"]["-h"]["--help"]
+ .optional();
+ }
+ };
+
+ struct Parser : ParserBase {
+
+ mutable ExeName m_exeName;
+ std::vector<Opt> m_options;
+ std::vector<Arg> m_args;
+
+ auto operator|=( ExeName const &exeName ) -> Parser & {
+ m_exeName = exeName;
+ return *this;
+ }
+
+ auto operator|=( Arg const &arg ) -> Parser & {
+ m_args.push_back(arg);
+ return *this;
+ }
+
+ auto operator|=( Opt const &opt ) -> Parser & {
+ m_options.push_back(opt);
+ return *this;
+ }
+
+ auto operator|=( Parser const &other ) -> Parser & {
+ m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end());
+ m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end());
+ return *this;
+ }
+
+ template<typename T>
+ auto operator|( T const &other ) const -> Parser {
+ return Parser( *this ) |= other;
+ }
+
+ // Forward deprecated interface with '+' instead of '|'
+ template<typename T>
+ auto operator+=( T const &other ) -> Parser & { return operator|=( other ); }
+ template<typename T>
+ auto operator+( T const &other ) const -> Parser { return operator|( other ); }
+
+ auto getHelpColumns() const -> std::vector<HelpColumns> {
+ std::vector<HelpColumns> cols;
+ for (auto const &o : m_options) {
+ auto childCols = o.getHelpColumns();
+ cols.insert( cols.end(), childCols.begin(), childCols.end() );
+ }
+ return cols;
+ }
+
+ void writeToStream( std::ostream &os ) const {
+ if (!m_exeName.name().empty()) {
+ os << "usage:\n" << " " << m_exeName.name() << " ";
+ bool required = true, first = true;
+ for( auto const &arg : m_args ) {
+ if (first)
+ first = false;
+ else
+ os << " ";
+ if( arg.isOptional() && required ) {
+ os << "[";
+ required = false;
+ }
+ os << "<" << arg.hint() << ">";
+ if( arg.cardinality() == 0 )
+ os << " ... ";
+ }
+ if( !required )
+ os << "]";
+ if( !m_options.empty() )
+ os << " options";
+ os << "\n\nwhere options are:" << std::endl;
+ }
+
+ auto rows = getHelpColumns();
+ size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;
+ size_t optWidth = 0;
+ for( auto const &cols : rows )
+ optWidth = (std::max)(optWidth, cols.left.size() + 2);
+
+ optWidth = (std::min)(optWidth, consoleWidth/2);
+
+ for( auto const &cols : rows ) {
+ auto row =
+ TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
+ TextFlow::Spacer(4) +
+ TextFlow::Column( cols.right ).width( consoleWidth - 7 - optWidth );
+ os << row << std::endl;
+ }
+ }
+
+ friend auto operator<<( std::ostream &os, Parser const &parser ) -> std::ostream& {
+ parser.writeToStream( os );
+ return os;
+ }
+
+ auto validate() const -> Result override {
+ for( auto const &opt : m_options ) {
+ auto result = opt.validate();
+ if( !result )
+ return result;
+ }
+ for( auto const &arg : m_args ) {
+ auto result = arg.validate();
+ if( !result )
+ return result;
+ }
+ return Result::ok();
+ }
+
+ using ParserBase::parse;
+
+ auto parse( std::string const& exeName, TokenStream const &tokens ) const -> InternalParseResult override {
+
+ struct ParserInfo {
+ ParserBase const* parser = nullptr;
+ size_t count = 0;
+ };
+ const size_t totalParsers = m_options.size() + m_args.size();
+ assert( totalParsers < 512 );
+ // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do
+ ParserInfo parseInfos[512];
+
+ {
+ size_t i = 0;
+ for (auto const &opt : m_options) parseInfos[i++].parser = &opt;
+ for (auto const &arg : m_args) parseInfos[i++].parser = &arg;
+ }
+
+ m_exeName.set( exeName );
+
+ auto result = InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
+ while( result.value().remainingTokens() ) {
+ bool tokenParsed = false;
+
+ for( size_t i = 0; i < totalParsers; ++i ) {
+ auto& parseInfo = parseInfos[i];
+ if( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() ) {
+ result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
+ if (!result)
+ return result;
+ if (result.value().type() != ParseResultType::NoMatch) {
+ tokenParsed = true;
+ ++parseInfo.count;
+ break;
+ }
+ }
+ }
+
+ if( result.value().type() == ParseResultType::ShortCircuitAll )
+ return result;
+ if( !tokenParsed )
+ return InternalParseResult::runtimeError( "Unrecognised token: " + result.value().remainingTokens()->token );
+ }
+ // !TBD Check missing required options
+ return result;
+ }
+ };
+
+ template<typename DerivedT>
+ template<typename T>
+ auto ComposableParserImpl<DerivedT>::operator|( T const &other ) const -> Parser {
+ return Parser() | static_cast<DerivedT const &>( *this ) | other;
+ }
+} // namespace detail
+
+// A Combined parser
+using detail::Parser;
+
+// A parser for options
+using detail::Opt;
+
+// A parser for arguments
+using detail::Arg;
+
+// Wrapper for argc, argv from main()
+using detail::Args;
+
+// Specifies the name of the executable
+using detail::ExeName;
+
+// Convenience wrapper for option parser that specifies the help option
+using detail::Help;
+
+// enum of result types from a parse
+using detail::ParseResultType;
+
+// Result type for parser operation
+using detail::ParserResult;
+
+}} // namespace Catch::clara
+
+// end clara.hpp
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+// Restore Clara's value for console width, if present
+#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
+#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
+#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
+#endif
+
+// end catch_clara.h
+namespace Catch {
+
+ clara::Parser makeCommandLineParser( ConfigData& config );
+
+} // end namespace Catch
+
+// end catch_commandline.h
+#include <fstream>
+#include <ctime>
+
+namespace Catch {
+
+ clara::Parser makeCommandLineParser( ConfigData& config ) {
+
+ using namespace clara;
+
+ auto const setWarning = [&]( std::string const& warning ) {
+ auto warningSet = [&]() {
+ if( warning == "NoAssertions" )
+ return WarnAbout::NoAssertions;
+
+ if ( warning == "NoTests" )
+ return WarnAbout::NoTests;
+
+ return WarnAbout::Nothing;
+ }();
+
+ if (warningSet == WarnAbout::Nothing)
+ return ParserResult::runtimeError( "Unrecognised warning: '" + warning + "'" );
+ config.warnings = static_cast<WarnAbout::What>( config.warnings | warningSet );
+ return ParserResult::ok( ParseResultType::Matched );
+ };
+ auto const loadTestNamesFromFile = [&]( std::string const& filename ) {
+ std::ifstream f( filename.c_str() );
+ if( !f.is_open() )
+ return ParserResult::runtimeError( "Unable to load input file: '" + filename + "'" );
+
+ std::string line;
+ while( std::getline( f, line ) ) {
+ line = trim(line);
+ if( !line.empty() && !startsWith( line, '#' ) ) {
+ if( !startsWith( line, '"' ) )
+ line = '"' + line + '"';
+ config.testsOrTags.push_back( line + ',' );
+ }
+ }
+ return ParserResult::ok( ParseResultType::Matched );
+ };
+ auto const setTestOrder = [&]( std::string const& order ) {
+ if( startsWith( "declared", order ) )
+ config.runOrder = RunTests::InDeclarationOrder;
+ else if( startsWith( "lexical", order ) )
+ config.runOrder = RunTests::InLexicographicalOrder;
+ else if( startsWith( "random", order ) )
+ config.runOrder = RunTests::InRandomOrder;
+ else
+ return clara::ParserResult::runtimeError( "Unrecognised ordering: '" + order + "'" );
+ return ParserResult::ok( ParseResultType::Matched );
+ };
+ auto const setRngSeed = [&]( std::string const& seed ) {
+ if( seed != "time" )
+ return clara::detail::convertInto( seed, config.rngSeed );
+ config.rngSeed = static_cast<unsigned int>( std::time(nullptr) );
+ return ParserResult::ok( ParseResultType::Matched );
+ };
+ auto const setColourUsage = [&]( std::string const& useColour ) {
+ auto mode = toLower( useColour );
+
+ if( mode == "yes" )
+ config.useColour = UseColour::Yes;
+ else if( mode == "no" )
+ config.useColour = UseColour::No;
+ else if( mode == "auto" )
+ config.useColour = UseColour::Auto;
+ else
+ return ParserResult::runtimeError( "colour mode must be one of: auto, yes or no. '" + useColour + "' not recognised" );
+ return ParserResult::ok( ParseResultType::Matched );
+ };
+ auto const setWaitForKeypress = [&]( std::string const& keypress ) {
+ auto keypressLc = toLower( keypress );
+ if( keypressLc == "start" )
+ config.waitForKeypress = WaitForKeypress::BeforeStart;
+ else if( keypressLc == "exit" )
+ config.waitForKeypress = WaitForKeypress::BeforeExit;
+ else if( keypressLc == "both" )
+ config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;
+ else
+ return ParserResult::runtimeError( "keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised" );
+ return ParserResult::ok( ParseResultType::Matched );
+ };
+ auto const setVerbosity = [&]( std::string const& verbosity ) {
+ auto lcVerbosity = toLower( verbosity );
+ if( lcVerbosity == "quiet" )
+ config.verbosity = Verbosity::Quiet;
+ else if( lcVerbosity == "normal" )
+ config.verbosity = Verbosity::Normal;
+ else if( lcVerbosity == "high" )
+ config.verbosity = Verbosity::High;
+ else
+ return ParserResult::runtimeError( "Unrecognised verbosity, '" + verbosity + "'" );
+ return ParserResult::ok( ParseResultType::Matched );
+ };
+
+ auto cli
+ = ExeName( config.processName )
+ | Help( config.showHelp )
+ | Opt( config.listTests )
+ ["-l"]["--list-tests"]
+ ( "list all/matching test cases" )
+ | Opt( config.listTags )
+ ["-t"]["--list-tags"]
+ ( "list all/matching tags" )
+ | Opt( config.showSuccessfulTests )
+ ["-s"]["--success"]
+ ( "include successful tests in output" )
+ | Opt( config.shouldDebugBreak )
+ ["-b"]["--break"]
+ ( "break into debugger on failure" )
+ | Opt( config.noThrow )
+ ["-e"]["--nothrow"]
+ ( "skip exception tests" )
+ | Opt( config.showInvisibles )
+ ["-i"]["--invisibles"]
+ ( "show invisibles (tabs, newlines)" )
+ | Opt( config.outputFilename, "filename" )
+ ["-o"]["--out"]
+ ( "output filename" )
+ | Opt( config.reporterNames, "name" )
+ ["-r"]["--reporter"]
+ ( "reporter to use (defaults to console)" )
+ | Opt( config.name, "name" )
+ ["-n"]["--name"]
+ ( "suite name" )
+ | Opt( [&]( bool ){ config.abortAfter = 1; } )
+ ["-a"]["--abort"]
+ ( "abort at first failure" )
+ | Opt( [&]( int x ){ config.abortAfter = x; }, "no. failures" )
+ ["-x"]["--abortx"]
+ ( "abort after x failures" )
+ | Opt( setWarning, "warning name" )
+ ["-w"]["--warn"]
+ ( "enable warnings" )
+ | Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" )
+ ["-d"]["--durations"]
+ ( "show test durations" )
+ | Opt( loadTestNamesFromFile, "filename" )
+ ["-f"]["--input-file"]
+ ( "load test names to run from a file" )
+ | Opt( config.filenamesAsTags )
+ ["-#"]["--filenames-as-tags"]
+ ( "adds a tag for the filename" )
+ | Opt( config.sectionsToRun, "section name" )
+ ["-c"]["--section"]
+ ( "specify section to run" )
+ | Opt( setVerbosity, "quiet|normal|high" )
+ ["-v"]["--verbosity"]
+ ( "set output verbosity" )
+ | Opt( config.listTestNamesOnly )
+ ["--list-test-names-only"]
+ ( "list all/matching test cases names only" )
+ | Opt( config.listReporters )
+ ["--list-reporters"]
+ ( "list all reporters" )
+ | Opt( setTestOrder, "decl|lex|rand" )
+ ["--order"]
+ ( "test case order (defaults to decl)" )
+ | Opt( setRngSeed, "'time'|number" )
+ ["--rng-seed"]
+ ( "set a specific seed for random numbers" )
+ | Opt( setColourUsage, "yes|no" )
+ ["--use-colour"]
+ ( "should output be colourised" )
+ | Opt( config.libIdentify )
+ ["--libidentify"]
+ ( "report name and version according to libidentify standard" )
+ | Opt( setWaitForKeypress, "start|exit|both" )
+ ["--wait-for-keypress"]
+ ( "waits for a keypress before exiting" )
+ | Opt( config.benchmarkResolutionMultiple, "multiplier" )
+ ["--benchmark-resolution-multiple"]
+ ( "multiple of clock resolution to run benchmarks" )
+
+ | Arg( config.testsOrTags, "test name|pattern|tags" )
+ ( "which test or tests to use" );
+
+ return cli;
+ }
+
+} // end namespace Catch
+// end catch_commandline.cpp
+// start catch_common.cpp
+
+#include <cstring>
+#include <ostream>
+
+namespace Catch {
+
+ bool SourceLineInfo::empty() const noexcept {
+ return file[0] == '\0';
+ }
+ bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const noexcept {
+ return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
+ }
+ bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept {
+ return line < other.line || ( line == other.line && (std::strcmp(file, other.file) < 0));
+ }
+
+ std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
+#ifndef __GNUG__
+ os << info.file << '(' << info.line << ')';
+#else
+ os << info.file << ':' << info.line;
+#endif
+ return os;
+ }
+
+ std::string StreamEndStop::operator+() const {
+ return std::string();
+ }
+
+ NonCopyable::NonCopyable() = default;
+ NonCopyable::~NonCopyable() = default;
+
+}
+// end catch_common.cpp
+// start catch_config.cpp
+
+// start catch_enforce.h
+
+#include <stdexcept>
+
+#define CATCH_PREPARE_EXCEPTION( type, msg ) \
+ type( ( Catch::ReusableStringStream() << msg ).str() )
+#define CATCH_INTERNAL_ERROR( msg ) \
+ throw CATCH_PREPARE_EXCEPTION( std::logic_error, CATCH_INTERNAL_LINEINFO << ": Internal Catch error: " << msg);
+#define CATCH_ERROR( msg ) \
+ throw CATCH_PREPARE_EXCEPTION( std::domain_error, msg )
+#define CATCH_ENFORCE( condition, msg ) \
+ do{ if( !(condition) ) CATCH_ERROR( msg ); } while(false)
+
+// end catch_enforce.h
+namespace Catch {
+
+ Config::Config( ConfigData const& data )
+ : m_data( data ),
+ m_stream( openStream() )
+ {
+ TestSpecParser parser(ITagAliasRegistry::get());
+ if (data.testsOrTags.empty()) {
+ parser.parse("~[.]"); // All not hidden tests
+ }
+ else {
+ m_hasTestFilters = true;
+ for( auto const& testOrTags : data.testsOrTags )
+ parser.parse( testOrTags );
+ }
+ m_testSpec = parser.testSpec();
+ }
+
+ std::string const& Config::getFilename() const {
+ return m_data.outputFilename ;
+ }
+
+ bool Config::listTests() const { return m_data.listTests; }
+ bool Config::listTestNamesOnly() const { return m_data.listTestNamesOnly; }
+ bool Config::listTags() const { return m_data.listTags; }
+ bool Config::listReporters() const { return m_data.listReporters; }
+
+ std::string Config::getProcessName() const { return m_data.processName; }
+
+ std::vector<std::string> const& Config::getReporterNames() const { return m_data.reporterNames; }
+ std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; }
+ std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }
+
+ TestSpec const& Config::testSpec() const { return m_testSpec; }
+ bool Config::hasTestFilters() const { return m_hasTestFilters; }
+
+ bool Config::showHelp() const { return m_data.showHelp; }
+
+ // IConfig interface
+ bool Config::allowThrows() const { return !m_data.noThrow; }
+ std::ostream& Config::stream() const { return m_stream->stream(); }
+ std::string Config::name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
+ bool Config::includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
+ bool Config::warnAboutMissingAssertions() const { return !!(m_data.warnings & WarnAbout::NoAssertions); }
+ bool Config::warnAboutNoTests() const { return !!(m_data.warnings & WarnAbout::NoTests); }
+ ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; }
+ RunTests::InWhatOrder Config::runOrder() const { return m_data.runOrder; }
+ unsigned int Config::rngSeed() const { return m_data.rngSeed; }
+ int Config::benchmarkResolutionMultiple() const { return m_data.benchmarkResolutionMultiple; }
+ UseColour::YesOrNo Config::useColour() const { return m_data.useColour; }
+ bool Config::shouldDebugBreak() const { return m_data.shouldDebugBreak; }
+ int Config::abortAfter() const { return m_data.abortAfter; }
+ bool Config::showInvisibles() const { return m_data.showInvisibles; }
+ Verbosity Config::verbosity() const { return m_data.verbosity; }
+
+ IStream const* Config::openStream() {
+ return Catch::makeStream(m_data.outputFilename);
+ }
+
+} // end namespace Catch
+// end catch_config.cpp
+// start catch_console_colour.cpp
+
+#if defined(__clang__)
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wexit-time-destructors"
+#endif
+
+// start catch_errno_guard.h
+
+namespace Catch {
+
+ class ErrnoGuard {
+ public:
+ ErrnoGuard();
+ ~ErrnoGuard();
+ private:
+ int m_oldErrno;
+ };
+
+}
+
+// end catch_errno_guard.h
+#include <sstream>
+
+namespace Catch {
+ namespace {
+
+ struct IColourImpl {
+ virtual ~IColourImpl() = default;
+ virtual void use( Colour::Code _colourCode ) = 0;
+ };
+
+ struct NoColourImpl : IColourImpl {
+ void use( Colour::Code ) {}
+
+ static IColourImpl* instance() {
+ static NoColourImpl s_instance;
+ return &s_instance;
+ }
+ };
+
+ } // anon namespace
+} // namespace Catch
+
+#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
+# ifdef CATCH_PLATFORM_WINDOWS
+# define CATCH_CONFIG_COLOUR_WINDOWS
+# else
+# define CATCH_CONFIG_COLOUR_ANSI
+# endif
+#endif
+
+#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
+
+namespace Catch {
+namespace {
+
+ class Win32ColourImpl : public IColourImpl {
+ public:
+ Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
+ {
+ CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
+ GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
+ originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
+ originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
+ }
+
+ virtual void use( Colour::Code _colourCode ) override {
+ switch( _colourCode ) {
+ case Colour::None: return setTextAttribute( originalForegroundAttributes );
+ case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
+ case Colour::Red: return setTextAttribute( FOREGROUND_RED );
+ case Colour::Green: return setTextAttribute( FOREGROUND_GREEN );
+ case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE );
+ case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
+ case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
+ case Colour::Grey: return setTextAttribute( 0 );
+
+ case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY );
+ case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
+ case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
+ case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
+ case Colour::BrightYellow: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN );
+
+ case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
+
+ default:
+ CATCH_ERROR( "Unknown colour requested" );
+ }
+ }
+
+ private:
+ void setTextAttribute( WORD _textAttribute ) {
+ SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
+ }
+ HANDLE stdoutHandle;
+ WORD originalForegroundAttributes;
+ WORD originalBackgroundAttributes;
+ };
+
+ IColourImpl* platformColourInstance() {
+ static Win32ColourImpl s_instance;
+
+ IConfigPtr config = getCurrentContext().getConfig();
+ UseColour::YesOrNo colourMode = config
+ ? config->useColour()
+ : UseColour::Auto;
+ if( colourMode == UseColour::Auto )
+ colourMode = UseColour::Yes;
+ return colourMode == UseColour::Yes
+ ? &s_instance
+ : NoColourImpl::instance();
+ }
+
+} // end anon namespace
+} // end namespace Catch
+
+#elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
+
+#include <unistd.h>
+
+namespace Catch {
+namespace {
+
+ // use POSIX/ ANSI console terminal codes
+ // Thanks to Adam Strzelecki for original contribution
+ // (http://github.com/nanoant)
+ // https://github.com/philsquared/Catch/pull/131
+ class PosixColourImpl : public IColourImpl {
+ public:
+ virtual void use( Colour::Code _colourCode ) override {
+ switch( _colourCode ) {
+ case Colour::None:
+ case Colour::White: return setColour( "[0m" );
+ case Colour::Red: return setColour( "[0;31m" );
+ case Colour::Green: return setColour( "[0;32m" );
+ case Colour::Blue: return setColour( "[0;34m" );
+ case Colour::Cyan: return setColour( "[0;36m" );
+ case Colour::Yellow: return setColour( "[0;33m" );
+ case Colour::Grey: return setColour( "[1;30m" );
+
+ case Colour::LightGrey: return setColour( "[0;37m" );
+ case Colour::BrightRed: return setColour( "[1;31m" );
+ case Colour::BrightGreen: return setColour( "[1;32m" );
+ case Colour::BrightWhite: return setColour( "[1;37m" );
+ case Colour::BrightYellow: return setColour( "[1;33m" );
+
+ case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
+ default: CATCH_INTERNAL_ERROR( "Unknown colour requested" );
+ }
+ }
+ static IColourImpl* instance() {
+ static PosixColourImpl s_instance;
+ return &s_instance;
+ }
+
+ private:
+ void setColour( const char* _escapeCode ) {
+ Catch::cout() << '\033' << _escapeCode;
+ }
+ };
+
+ bool useColourOnPlatform() {
+ return
+#ifdef CATCH_PLATFORM_MAC
+ !isDebuggerActive() &&
+#endif
+#if !(defined(__DJGPP__) && defined(__STRICT_ANSI__))
+ isatty(STDOUT_FILENO)
+#else
+ false
+#endif
+ ;
+ }
+ IColourImpl* platformColourInstance() {
+ ErrnoGuard guard;
+ IConfigPtr config = getCurrentContext().getConfig();
+ UseColour::YesOrNo colourMode = config
+ ? config->useColour()
+ : UseColour::Auto;
+ if( colourMode == UseColour::Auto )
+ colourMode = useColourOnPlatform()
+ ? UseColour::Yes
+ : UseColour::No;
+ return colourMode == UseColour::Yes
+ ? PosixColourImpl::instance()
+ : NoColourImpl::instance();
+ }
+
+} // end anon namespace
+} // end namespace Catch
+
+#else // not Windows or ANSI ///////////////////////////////////////////////
+
+namespace Catch {
+
+ static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
+
+} // end namespace Catch
+
+#endif // Windows/ ANSI/ None
+
+namespace Catch {
+
+ Colour::Colour( Code _colourCode ) { use( _colourCode ); }
+ Colour::Colour( Colour&& rhs ) noexcept {
+ m_moved = rhs.m_moved;
+ rhs.m_moved = true;
+ }
+ Colour& Colour::operator=( Colour&& rhs ) noexcept {
+ m_moved = rhs.m_moved;
+ rhs.m_moved = true;
+ return *this;
+ }
+
+ Colour::~Colour(){ if( !m_moved ) use( None ); }
+
+ void Colour::use( Code _colourCode ) {
+ static IColourImpl* impl = platformColourInstance();
+ impl->use( _colourCode );
+ }
+
+ std::ostream& operator << ( std::ostream& os, Colour const& ) {
+ return os;
+ }
+
+} // end namespace Catch
+
+#if defined(__clang__)
+# pragma clang diagnostic pop
+#endif
+
+// end catch_console_colour.cpp
+// start catch_context.cpp
+
+namespace Catch {
+
+ class Context : public IMutableContext, NonCopyable {
+
+ public: // IContext
+ virtual IResultCapture* getResultCapture() override {
+ return m_resultCapture;
+ }
+ virtual IRunner* getRunner() override {
+ return m_runner;
+ }
+
+ virtual IConfigPtr const& getConfig() const override {
+ return m_config;
+ }
+
+ virtual ~Context() override;
+
+ public: // IMutableContext
+ virtual void setResultCapture( IResultCapture* resultCapture ) override {
+ m_resultCapture = resultCapture;
+ }
+ virtual void setRunner( IRunner* runner ) override {
+ m_runner = runner;
+ }
+ virtual void setConfig( IConfigPtr const& config ) override {
+ m_config = config;
+ }
+
+ friend IMutableContext& getCurrentMutableContext();
+
+ private:
+ IConfigPtr m_config;
+ IRunner* m_runner = nullptr;
+ IResultCapture* m_resultCapture = nullptr;
+ };
+
+ IMutableContext *IMutableContext::currentContext = nullptr;
+
+ void IMutableContext::createContext()
+ {
+ currentContext = new Context();
+ }
+
+ void cleanUpContext() {
+ delete IMutableContext::currentContext;
+ IMutableContext::currentContext = nullptr;
+ }
+ IContext::~IContext() = default;
+ IMutableContext::~IMutableContext() = default;
+ Context::~Context() = default;
+}
+// end catch_context.cpp
+// start catch_debug_console.cpp
+
+// start catch_debug_console.h
+
+#include <string>
+
+namespace Catch {
+ void writeToDebugConsole( std::string const& text );
+}
+
+// end catch_debug_console.h
+#ifdef CATCH_PLATFORM_WINDOWS
+
+ namespace Catch {
+ void writeToDebugConsole( std::string const& text ) {
+ ::OutputDebugStringA( text.c_str() );
+ }
+ }
+
+#else
+
+ namespace Catch {
+ void writeToDebugConsole( std::string const& text ) {
+ // !TBD: Need a version for Mac/ XCode and other IDEs
+ Catch::cout() << text;
+ }
+ }
+
+#endif // Platform
+// end catch_debug_console.cpp
+// start catch_debugger.cpp
+
+#ifdef CATCH_PLATFORM_MAC
+
+# include <assert.h>
+# include <stdbool.h>
+# include <sys/types.h>
+# include <unistd.h>
+# include <sys/sysctl.h>
+# include <cstddef>
+# include <ostream>
+
+namespace Catch {
+
+ // The following function is taken directly from the following technical note:
+ // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
+
+ // Returns true if the current process is being debugged (either
+ // running under the debugger or has a debugger attached post facto).
+ bool isDebuggerActive(){
+
+ int mib[4];
+ struct kinfo_proc info;
+ std::size_t size;
+
+ // Initialize the flags so that, if sysctl fails for some bizarre
+ // reason, we get a predictable result.
+
+ info.kp_proc.p_flag = 0;
+
+ // Initialize mib, which tells sysctl the info we want, in this case
+ // we're looking for information about a specific process ID.
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_PID;
+ mib[3] = getpid();
+
+ // Call sysctl.
+
+ size = sizeof(info);
+ if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0 ) {
+ Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
+ return false;
+ }
+
+ // We're being debugged if the P_TRACED flag is set.
+
+ return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
+ }
+ } // namespace Catch
+
+#elif defined(CATCH_PLATFORM_LINUX)
+ #include <fstream>
+ #include <string>
+
+ namespace Catch{
+ // The standard POSIX way of detecting a debugger is to attempt to
+ // ptrace() the process, but this needs to be done from a child and not
+ // this process itself to still allow attaching to this process later
+ // if wanted, so is rather heavy. Under Linux we have the PID of the
+ // "debugger" (which doesn't need to be gdb, of course, it could also
+ // be strace, for example) in /proc/$PID/status, so just get it from
+ // there instead.
+ bool isDebuggerActive(){
+ // Libstdc++ has a bug, where std::ifstream sets errno to 0
+ // This way our users can properly assert over errno values
+ ErrnoGuard guard;
+ std::ifstream in("/proc/self/status");
+ for( std::string line; std::getline(in, line); ) {
+ static const int PREFIX_LEN = 11;
+ if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) {
+ // We're traced if the PID is not 0 and no other PID starts
+ // with 0 digit, so it's enough to check for just a single
+ // character.
+ return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
+ }
+ }
+
+ return false;
+ }
+ } // namespace Catch
+#elif defined(_MSC_VER)
+ extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
+ namespace Catch {
+ bool isDebuggerActive() {
+ return IsDebuggerPresent() != 0;
+ }
+ }
+#elif defined(__MINGW32__)
+ extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
+ namespace Catch {
+ bool isDebuggerActive() {
+ return IsDebuggerPresent() != 0;
+ }
+ }
+#else
+ namespace Catch {
+ bool isDebuggerActive() { return false; }
+ }
+#endif // Platform
+// end catch_debugger.cpp
+// start catch_decomposer.cpp
+
+namespace Catch {
+
+ ITransientExpression::~ITransientExpression() = default;
+
+ void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) {
+ if( lhs.size() + rhs.size() < 40 &&
+ lhs.find('\n') == std::string::npos &&
+ rhs.find('\n') == std::string::npos )
+ os << lhs << " " << op << " " << rhs;
+ else
+ os << lhs << "\n" << op << "\n" << rhs;
+ }
+}
+// end catch_decomposer.cpp
+// start catch_errno_guard.cpp
+
+#include <cerrno>
+
+namespace Catch {
+ ErrnoGuard::ErrnoGuard():m_oldErrno(errno){}
+ ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; }
+}
+// end catch_errno_guard.cpp
+// start catch_exception_translator_registry.cpp
+
+// start catch_exception_translator_registry.h
+
+#include <vector>
+#include <string>
+#include <memory>
+
+namespace Catch {
+
+ class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
+ public:
+ ~ExceptionTranslatorRegistry();
+ virtual void registerTranslator( const IExceptionTranslator* translator );
+ virtual std::string translateActiveException() const override;
+ std::string tryTranslators() const;
+
+ private:
+ std::vector<std::unique_ptr<IExceptionTranslator const>> m_translators;
+ };
+}
+
+// end catch_exception_translator_registry.h
+#ifdef __OBJC__
+#import "Foundation/Foundation.h"
+#endif
+
+namespace Catch {
+
+ ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() {
+ }
+
+ void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator* translator ) {
+ m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) );
+ }
+
+ std::string ExceptionTranslatorRegistry::translateActiveException() const {
+ try {
+#ifdef __OBJC__
+ // In Objective-C try objective-c exceptions first
+ @try {
+ return tryTranslators();
+ }
+ @catch (NSException *exception) {
+ return Catch::Detail::stringify( [exception description] );
+ }
+#else
+ // Compiling a mixed mode project with MSVC means that CLR
+ // exceptions will be caught in (...) as well. However, these
+ // do not fill-in std::current_exception and thus lead to crash
+ // when attempting rethrow.
+ // /EHa switch also causes structured exceptions to be caught
+ // here, but they fill-in current_exception properly, so
+ // at worst the output should be a little weird, instead of
+ // causing a crash.
+ if (std::current_exception() == nullptr) {
+ return "Non C++ exception. Possibly a CLR exception.";
+ }
+ return tryTranslators();
+#endif
+ }
+ catch( TestFailureException& ) {
+ std::rethrow_exception(std::current_exception());
+ }
+ catch( std::exception& ex ) {
+ return ex.what();
+ }
+ catch( std::string& msg ) {
+ return msg;
+ }
+ catch( const char* msg ) {
+ return msg;
+ }
+ catch(...) {
+ return "Unknown exception";
+ }
+ }
+
+ std::string ExceptionTranslatorRegistry::tryTranslators() const {
+ if( m_translators.empty() )
+ std::rethrow_exception(std::current_exception());
+ else
+ return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() );
+ }
+}
+// end catch_exception_translator_registry.cpp
+// start catch_fatal_condition.cpp
+
+#if defined(__GNUC__)
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+#endif
+
+#if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS )
+
+namespace {
+ // Report the error condition
+ void reportFatal( char const * const message ) {
+ Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message );
+ }
+}
+
+#endif // signals/SEH handling
+
+#if defined( CATCH_CONFIG_WINDOWS_SEH )
+
+namespace Catch {
+ struct SignalDefs { DWORD id; const char* name; };
+
+ // There is no 1-1 mapping between signals and windows exceptions.
+ // Windows can easily distinguish between SO and SigSegV,
+ // but SigInt, SigTerm, etc are handled differently.
+ static SignalDefs signalDefs[] = {
+ { EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal" },
+ { EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" },
+ { EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" },
+ { EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" },
+ };
+
+ LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
+ for (auto const& def : signalDefs) {
+ if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
+ reportFatal(def.name);
+ }
+ }
+ // If its not an exception we care about, pass it along.
+ // This stops us from eating debugger breaks etc.
+ return EXCEPTION_CONTINUE_SEARCH;
+ }
+
+ FatalConditionHandler::FatalConditionHandler() {
+ isSet = true;
+ // 32k seems enough for Catch to handle stack overflow,
+ // but the value was found experimentally, so there is no strong guarantee
+ guaranteeSize = 32 * 1024;
+ exceptionHandlerHandle = nullptr;
+ // Register as first handler in current chain
+ exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
+ // Pass in guarantee size to be filled
+ SetThreadStackGuarantee(&guaranteeSize);
+ }
+
+ void FatalConditionHandler::reset() {
+ if (isSet) {
+ RemoveVectoredExceptionHandler(exceptionHandlerHandle);
+ SetThreadStackGuarantee(&guaranteeSize);
+ exceptionHandlerHandle = nullptr;
+ isSet = false;
+ }
+ }
+
+ FatalConditionHandler::~FatalConditionHandler() {
+ reset();
+ }
+
+bool FatalConditionHandler::isSet = false;
+ULONG FatalConditionHandler::guaranteeSize = 0;
+PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr;
+
+} // namespace Catch
+
+#elif defined( CATCH_CONFIG_POSIX_SIGNALS )
+
+namespace Catch {
+
+ struct SignalDefs {
+ int id;
+ const char* name;
+ };
+ static SignalDefs signalDefs[] = {
+ { SIGINT, "SIGINT - Terminal interrupt signal" },
+ { SIGILL, "SIGILL - Illegal instruction signal" },
+ { SIGFPE, "SIGFPE - Floating point error signal" },
+ { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
+ { SIGTERM, "SIGTERM - Termination request signal" },
+ { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
+ };
+
+ void FatalConditionHandler::handleSignal( int sig ) {
+ char const * name = "<unknown signal>";
+ for (auto const& def : signalDefs) {
+ if (sig == def.id) {
+ name = def.name;
+ break;
+ }
+ }
+ reset();
+ reportFatal(name);
+ raise( sig );
+ }
+
+ FatalConditionHandler::FatalConditionHandler() {
+ isSet = true;
+ stack_t sigStack;
+ sigStack.ss_sp = altStackMem;
+ sigStack.ss_size = SIGSTKSZ;
+ sigStack.ss_flags = 0;
+ sigaltstack(&sigStack, &oldSigStack);
+ struct sigaction sa = { };
+
+ sa.sa_handler = handleSignal;
+ sa.sa_flags = SA_ONSTACK;
+ for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) {
+ sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
+ }
+ }
+
+ FatalConditionHandler::~FatalConditionHandler() {
+ reset();
+ }
+
+ void FatalConditionHandler::reset() {
+ if( isSet ) {
+ // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
+ for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {
+ sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
+ }
+ // Return the old stack
+ sigaltstack(&oldSigStack, nullptr);
+ isSet = false;
+ }
+ }
+
+ bool FatalConditionHandler::isSet = false;
+ struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
+ stack_t FatalConditionHandler::oldSigStack = {};
+ char FatalConditionHandler::altStackMem[SIGSTKSZ] = {};
+
+} // namespace Catch
+
+#else
+
+namespace Catch {
+ void FatalConditionHandler::reset() {}
+}
+
+#endif // signals/SEH handling
+
+#if defined(__GNUC__)
+# pragma GCC diagnostic pop
+#endif
+// end catch_fatal_condition.cpp
+// start catch_interfaces_capture.cpp
+
+namespace Catch {
+ IResultCapture::~IResultCapture() = default;
+}
+// end catch_interfaces_capture.cpp
+// start catch_interfaces_config.cpp
+
+namespace Catch {
+ IConfig::~IConfig() = default;
+}
+// end catch_interfaces_config.cpp
+// start catch_interfaces_exception.cpp
+
+namespace Catch {
+ IExceptionTranslator::~IExceptionTranslator() = default;
+ IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default;
+}
+// end catch_interfaces_exception.cpp
+// start catch_interfaces_registry_hub.cpp
+
+namespace Catch {
+ IRegistryHub::~IRegistryHub() = default;
+ IMutableRegistryHub::~IMutableRegistryHub() = default;
+}
+// end catch_interfaces_registry_hub.cpp
+// start catch_interfaces_reporter.cpp
+
+// start catch_reporter_multi.h
+
+namespace Catch {
+
+ class MultipleReporters : public IStreamingReporter {
+ using Reporters = std::vector<IStreamingReporterPtr>;
+ Reporters m_reporters;
+
+ public:
+ void add( IStreamingReporterPtr&& reporter );
+
+ public: // IStreamingReporter
+
+ ReporterPreferences getPreferences() const override;
+
+ void noMatchingTestCases( std::string const& spec ) override;
+
+ static std::set<Verbosity> getSupportedVerbosities();
+
+ void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override;
+ void benchmarkEnded( BenchmarkStats const& benchmarkStats ) override;
+
+ void testRunStarting( TestRunInfo const& testRunInfo ) override;
+ void testGroupStarting( GroupInfo const& groupInfo ) override;
+ void testCaseStarting( TestCaseInfo const& testInfo ) override;
+ void sectionStarting( SectionInfo const& sectionInfo ) override;
+ void assertionStarting( AssertionInfo const& assertionInfo ) override;
+
+ // The return value indicates if the messages buffer should be cleared:
+ bool assertionEnded( AssertionStats const& assertionStats ) override;
+ void sectionEnded( SectionStats const& sectionStats ) override;
+ void testCaseEnded( TestCaseStats const& testCaseStats ) override;
+ void testGroupEnded( TestGroupStats const& testGroupStats ) override;
+ void testRunEnded( TestRunStats const& testRunStats ) override;
+
+ void skipTest( TestCaseInfo const& testInfo ) override;
+ bool isMulti() const override;
+
+ };
+
+} // end namespace Catch
+
+// end catch_reporter_multi.h
+namespace Catch {
+
+ ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig )
+ : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
+
+ ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream )
+ : m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
+
+ std::ostream& ReporterConfig::stream() const { return *m_stream; }
+ IConfigPtr ReporterConfig::fullConfig() const { return m_fullConfig; }
+
+ TestRunInfo::TestRunInfo( std::string const& _name ) : name( _name ) {}
+
+ GroupInfo::GroupInfo( std::string const& _name,
+ std::size_t _groupIndex,
+ std::size_t _groupsCount )
+ : name( _name ),
+ groupIndex( _groupIndex ),
+ groupsCounts( _groupsCount )
+ {}
+
+ AssertionStats::AssertionStats( AssertionResult const& _assertionResult,
+ std::vector<MessageInfo> const& _infoMessages,
+ Totals const& _totals )
+ : assertionResult( _assertionResult ),
+ infoMessages( _infoMessages ),
+ totals( _totals )
+ {
+ assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression;
+
+ if( assertionResult.hasMessage() ) {
+ // Copy message into messages list.
+ // !TBD This should have been done earlier, somewhere
+ MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
+ builder << assertionResult.getMessage();
+ builder.m_info.message = builder.m_stream.str();
+
+ infoMessages.push_back( builder.m_info );
+ }
+ }
+
+ AssertionStats::~AssertionStats() = default;
+
+ SectionStats::SectionStats( SectionInfo const& _sectionInfo,
+ Counts const& _assertions,
+ double _durationInSeconds,
+ bool _missingAssertions )
+ : sectionInfo( _sectionInfo ),
+ assertions( _assertions ),
+ durationInSeconds( _durationInSeconds ),
+ missingAssertions( _missingAssertions )
+ {}
+
+ SectionStats::~SectionStats() = default;
+
+ TestCaseStats::TestCaseStats( TestCaseInfo const& _testInfo,
+ Totals const& _totals,
+ std::string const& _stdOut,
+ std::string const& _stdErr,
+ bool _aborting )
+ : testInfo( _testInfo ),
+ totals( _totals ),
+ stdOut( _stdOut ),
+ stdErr( _stdErr ),
+ aborting( _aborting )
+ {}
+
+ TestCaseStats::~TestCaseStats() = default;
+
+ TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo,
+ Totals const& _totals,
+ bool _aborting )
+ : groupInfo( _groupInfo ),
+ totals( _totals ),
+ aborting( _aborting )
+ {}
+
+ TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo )
+ : groupInfo( _groupInfo ),
+ aborting( false )
+ {}
+
+ TestGroupStats::~TestGroupStats() = default;
+
+ TestRunStats::TestRunStats( TestRunInfo const& _runInfo,
+ Totals const& _totals,
+ bool _aborting )
+ : runInfo( _runInfo ),
+ totals( _totals ),
+ aborting( _aborting )
+ {}
+
+ TestRunStats::~TestRunStats() = default;
+
+ void IStreamingReporter::fatalErrorEncountered( StringRef ) {}
+ bool IStreamingReporter::isMulti() const { return false; }
+
+ IReporterFactory::~IReporterFactory() = default;
+ IReporterRegistry::~IReporterRegistry() = default;
+
+ void addReporter( IStreamingReporterPtr& existingReporter, IStreamingReporterPtr&& additionalReporter ) {
+
+ if( !existingReporter ) {
+ existingReporter = std::move( additionalReporter );
+ return;
+ }
+
+ MultipleReporters* multi = nullptr;
+
+ if( existingReporter->isMulti() ) {
+ multi = static_cast<MultipleReporters*>( existingReporter.get() );
+ }
+ else {
+ auto newMulti = std::unique_ptr<MultipleReporters>( new MultipleReporters );
+ newMulti->add( std::move( existingReporter ) );
+ multi = newMulti.get();
+ existingReporter = std::move( newMulti );
+ }
+ multi->add( std::move( additionalReporter ) );
+ }
+
+} // end namespace Catch
+// end catch_interfaces_reporter.cpp
+// start catch_interfaces_runner.cpp
+
+namespace Catch {
+ IRunner::~IRunner() = default;
+}
+// end catch_interfaces_runner.cpp
+// start catch_interfaces_testcase.cpp
+
+namespace Catch {
+ ITestInvoker::~ITestInvoker() = default;
+ ITestCaseRegistry::~ITestCaseRegistry() = default;
+}
+// end catch_interfaces_testcase.cpp
+// start catch_leak_detector.cpp
+
+#ifdef CATCH_CONFIG_WINDOWS_CRTDBG
+#include <crtdbg.h>
+
+namespace Catch {
+
+ LeakDetector::LeakDetector() {
+ int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
+ flag |= _CRTDBG_LEAK_CHECK_DF;
+ flag |= _CRTDBG_ALLOC_MEM_DF;
+ _CrtSetDbgFlag(flag);
+ _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
+ _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
+ // Change this to leaking allocation's number to break there
+ _CrtSetBreakAlloc(-1);
+ }
+}
+
+#else
+
+ Catch::LeakDetector::LeakDetector() {}
+
+#endif
+// end catch_leak_detector.cpp
+// start catch_list.cpp
+
+// start catch_list.h
+
+#include <set>
+
+namespace Catch {
+
+ std::size_t listTests( Config const& config );
+
+ std::size_t listTestsNamesOnly( Config const& config );
+
+ struct TagInfo {
+ void add( std::string const& spelling );
+ std::string all() const;
+
+ std::set<std::string> spellings;
+ std::size_t count = 0;
+ };
+
+ std::size_t listTags( Config const& config );
+
+ std::size_t listReporters( Config const& /*config*/ );
+
+ Option<std::size_t> list( Config const& config );
+
+} // end namespace Catch
+
+// end catch_list.h
+// start catch_text.h
+
+namespace Catch {
+ using namespace clara::TextFlow;
+}
+
+// end catch_text.h
+#include <limits>
+#include <algorithm>
+#include <iomanip>
+
+namespace Catch {
+
+ std::size_t listTests( Config const& config ) {
+ TestSpec testSpec = config.testSpec();
+ if( config.hasTestFilters() )
+ Catch::cout() << "Matching test cases:\n";
+ else {
+ Catch::cout() << "All available test cases:\n";
+ }
+
+ auto matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
+ for( auto const& testCaseInfo : matchedTestCases ) {
+ Colour::Code colour = testCaseInfo.isHidden()
+ ? Colour::SecondaryText
+ : Colour::None;
+ Colour colourGuard( colour );
+
+ Catch::cout() << Column( testCaseInfo.name ).initialIndent( 2 ).indent( 4 ) << "\n";
+ if( config.verbosity() >= Verbosity::High ) {
+ Catch::cout() << Column( Catch::Detail::stringify( testCaseInfo.lineInfo ) ).indent(4) << std::endl;
+ std::string description = testCaseInfo.description;
+ if( description.empty() )
+ description = "(NO DESCRIPTION)";
+ Catch::cout() << Column( description ).indent(4) << std::endl;
+ }
+ if( !testCaseInfo.tags.empty() )
+ Catch::cout() << Column( testCaseInfo.tagsAsString() ).indent( 6 ) << "\n";
+ }
+
+ if( !config.hasTestFilters() )
+ Catch::cout() << pluralise( matchedTestCases.size(), "test case" ) << '\n' << std::endl;
+ else
+ Catch::cout() << pluralise( matchedTestCases.size(), "matching test case" ) << '\n' << std::endl;
+ return matchedTestCases.size();
+ }
+
+ std::size_t listTestsNamesOnly( Config const& config ) {
+ TestSpec testSpec = config.testSpec();
+ std::size_t matchedTests = 0;
+ std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
+ for( auto const& testCaseInfo : matchedTestCases ) {
+ matchedTests++;
+ if( startsWith( testCaseInfo.name, '#' ) )
+ Catch::cout() << '"' << testCaseInfo.name << '"';
+ else
+ Catch::cout() << testCaseInfo.name;
+ if ( config.verbosity() >= Verbosity::High )
+ Catch::cout() << "\t@" << testCaseInfo.lineInfo;
+ Catch::cout() << std::endl;
+ }
+ return matchedTests;
+ }
+
+ void TagInfo::add( std::string const& spelling ) {
+ ++count;
+ spellings.insert( spelling );
+ }
+
+ std::string TagInfo::all() const {
+ std::string out;
+ for( auto const& spelling : spellings )
+ out += "[" + spelling + "]";
+ return out;
+ }
+
+ std::size_t listTags( Config const& config ) {
+ TestSpec testSpec = config.testSpec();
+ if( config.hasTestFilters() )
+ Catch::cout() << "Tags for matching test cases:\n";
+ else {
+ Catch::cout() << "All available tags:\n";
+ }
+
+ std::map<std::string, TagInfo> tagCounts;
+
+ std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
+ for( auto const& testCase : matchedTestCases ) {
+ for( auto const& tagName : testCase.getTestCaseInfo().tags ) {
+ std::string lcaseTagName = toLower( tagName );
+ auto countIt = tagCounts.find( lcaseTagName );
+ if( countIt == tagCounts.end() )
+ countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
+ countIt->second.add( tagName );
+ }
+ }
+
+ for( auto const& tagCount : tagCounts ) {
+ ReusableStringStream rss;
+ rss << " " << std::setw(2) << tagCount.second.count << " ";
+ auto str = rss.str();
+ auto wrapper = Column( tagCount.second.all() )
+ .initialIndent( 0 )
+ .indent( str.size() )
+ .width( CATCH_CONFIG_CONSOLE_WIDTH-10 );
+ Catch::cout() << str << wrapper << '\n';
+ }
+ Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl;
+ return tagCounts.size();
+ }
+
+ std::size_t listReporters( Config const& /*config*/ ) {
+ Catch::cout() << "Available reporters:\n";
+ IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
+ std::size_t maxNameLen = 0;
+ for( auto const& factoryKvp : factories )
+ maxNameLen = (std::max)( maxNameLen, factoryKvp.first.size() );
+
+ for( auto const& factoryKvp : factories ) {
+ Catch::cout()
+ << Column( factoryKvp.first + ":" )
+ .indent(2)
+ .width( 5+maxNameLen )
+ + Column( factoryKvp.second->getDescription() )
+ .initialIndent(0)
+ .indent(2)
+ .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 )
+ << "\n";
+ }
+ Catch::cout() << std::endl;
+ return factories.size();
+ }
+
+ Option<std::size_t> list( Config const& config ) {
+ Option<std::size_t> listedCount;
+ if( config.listTests() )
+ listedCount = listedCount.valueOr(0) + listTests( config );
+ if( config.listTestNamesOnly() )
+ listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );
+ if( config.listTags() )
+ listedCount = listedCount.valueOr(0) + listTags( config );
+ if( config.listReporters() )
+ listedCount = listedCount.valueOr(0) + listReporters( config );
+ return listedCount;
+ }
+
+} // end namespace Catch
+// end catch_list.cpp
+// start catch_matchers.cpp
+
+namespace Catch {
+namespace Matchers {
+ namespace Impl {
+
+ std::string MatcherUntypedBase::toString() const {
+ if( m_cachedToString.empty() )
+ m_cachedToString = describe();
+ return m_cachedToString;
+ }
+
+ MatcherUntypedBase::~MatcherUntypedBase() = default;
+
+ } // namespace Impl
+} // namespace Matchers
+
+using namespace Matchers;
+using Matchers::Impl::MatcherBase;
+
+} // namespace Catch
+// end catch_matchers.cpp
+// start catch_matchers_floating.cpp
+
+#include <cstdlib>
+#include <cstdint>
+#include <cstring>
+#include <stdexcept>
+
+namespace Catch {
+namespace Matchers {
+namespace Floating {
+enum class FloatingPointKind : uint8_t {
+ Float,
+ Double
+};
+}
+}
+}
+
+namespace {
+
+template <typename T>
+struct Converter;
+
+template <>
+struct Converter<float> {
+ static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated");
+ Converter(float f) {
+ std::memcpy(&i, &f, sizeof(f));
+ }
+ int32_t i;
+};
+
+template <>
+struct Converter<double> {
+ static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated");
+ Converter(double d) {
+ std::memcpy(&i, &d, sizeof(d));
+ }
+ int64_t i;
+};
+
+template <typename T>
+auto convert(T t) -> Converter<T> {
+ return Converter<T>(t);
+}
+
+template <typename FP>
+bool almostEqualUlps(FP lhs, FP rhs, int maxUlpDiff) {
+ // Comparison with NaN should always be false.
+ // This way we can rule it out before getting into the ugly details
+ if (std::isnan(lhs) || std::isnan(rhs)) {
+ return false;
+ }
+
+ auto lc = convert(lhs);
+ auto rc = convert(rhs);
+
+ if ((lc.i < 0) != (rc.i < 0)) {
+ // Potentially we can have +0 and -0
+ return lhs == rhs;
+ }
+
+ auto ulpDiff = std::abs(lc.i - rc.i);
+ return ulpDiff <= maxUlpDiff;
+}
+
+}
+
+namespace Catch {
+namespace Matchers {
+namespace Floating {
+ WithinAbsMatcher::WithinAbsMatcher(double target, double margin)
+ :m_target{ target }, m_margin{ margin } {
+ if (m_margin < 0) {
+ throw std::domain_error("Allowed margin difference has to be >= 0");
+ }
+ }
+
+ // Performs equivalent check of std::fabs(lhs - rhs) <= margin
+ // But without the subtraction to allow for INFINITY in comparison
+ bool WithinAbsMatcher::match(double const& matchee) const {
+ return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee);
+ }
+
+ std::string WithinAbsMatcher::describe() const {
+ return "is within " + ::Catch::Detail::stringify(m_margin) + " of " + ::Catch::Detail::stringify(m_target);
+ }
+
+ WithinUlpsMatcher::WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType)
+ :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {
+ if (m_ulps < 0) {
+ throw std::domain_error("Allowed ulp difference has to be >= 0");
+ }
+ }
+
+ bool WithinUlpsMatcher::match(double const& matchee) const {
+ switch (m_type) {
+ case FloatingPointKind::Float:
+ return almostEqualUlps<float>(static_cast<float>(matchee), static_cast<float>(m_target), m_ulps);
+ case FloatingPointKind::Double:
+ return almostEqualUlps<double>(matchee, m_target, m_ulps);
+ default:
+ throw std::domain_error("Unknown FloatingPointKind value");
+ }
+ }
+
+ std::string WithinUlpsMatcher::describe() const {
+ return "is within " + std::to_string(m_ulps) + " ULPs of " + ::Catch::Detail::stringify(m_target) + ((m_type == FloatingPointKind::Float)? "f" : "");
+ }
+
+}// namespace Floating
+
+Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff) {
+ return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double);
+}
+
+Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff) {
+ return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float);
+}
+
+Floating::WithinAbsMatcher WithinAbs(double target, double margin) {
+ return Floating::WithinAbsMatcher(target, margin);
+}
+
+} // namespace Matchers
+} // namespace Catch
+
+// end catch_matchers_floating.cpp
+// start catch_matchers_generic.cpp
+
+std::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string& desc) {
+ if (desc.empty()) {
+ return "matches undescribed predicate";
+ } else {
+ return "matches predicate: \"" + desc + '"';
+ }
+}
+// end catch_matchers_generic.cpp
+// start catch_matchers_string.cpp
+
+#include <regex>
+
+namespace Catch {
+namespace Matchers {
+
+ namespace StdString {
+
+ CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
+ : m_caseSensitivity( caseSensitivity ),
+ m_str( adjustString( str ) )
+ {}
+ std::string CasedString::adjustString( std::string const& str ) const {
+ return m_caseSensitivity == CaseSensitive::No
+ ? toLower( str )
+ : str;
+ }
+ std::string CasedString::caseSensitivitySuffix() const {
+ return m_caseSensitivity == CaseSensitive::No
+ ? " (case insensitive)"
+ : std::string();
+ }
+
+ StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator )
+ : m_comparator( comparator ),
+ m_operation( operation ) {
+ }
+
+ std::string StringMatcherBase::describe() const {
+ std::string description;
+ description.reserve(5 + m_operation.size() + m_comparator.m_str.size() +
+ m_comparator.caseSensitivitySuffix().size());
+ description += m_operation;
+ description += ": \"";
+ description += m_comparator.m_str;
+ description += "\"";
+ description += m_comparator.caseSensitivitySuffix();
+ return description;
+ }
+
+ EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {}
+
+ bool EqualsMatcher::match( std::string const& source ) const {
+ return m_comparator.adjustString( source ) == m_comparator.m_str;
+ }
+
+ ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {}
+
+ bool ContainsMatcher::match( std::string const& source ) const {
+ return contains( m_comparator.adjustString( source ), m_comparator.m_str );
+ }
+
+ StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {}
+
+ bool StartsWithMatcher::match( std::string const& source ) const {
+ return startsWith( m_comparator.adjustString( source ), m_comparator.m_str );
+ }
+
+ EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {}
+
+ bool EndsWithMatcher::match( std::string const& source ) const {
+ return endsWith( m_comparator.adjustString( source ), m_comparator.m_str );
+ }
+
+ RegexMatcher::RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity): m_regex(std::move(regex)), m_caseSensitivity(caseSensitivity) {}
+
+ bool RegexMatcher::match(std::string const& matchee) const {
+ auto flags = std::regex::ECMAScript; // ECMAScript is the default syntax option anyway
+ if (m_caseSensitivity == CaseSensitive::Choice::No) {
+ flags |= std::regex::icase;
+ }
+ auto reg = std::regex(m_regex, flags);
+ return std::regex_match(matchee, reg);
+ }
+
+ std::string RegexMatcher::describe() const {
+ return "matches " + ::Catch::Detail::stringify(m_regex) + ((m_caseSensitivity == CaseSensitive::Choice::Yes)? " case sensitively" : " case insensitively");
+ }
+
+ } // namespace StdString
+
+ StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
+ return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) );
+ }
+ StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
+ return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) );
+ }
+ StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
+ return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) );
+ }
+ StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
+ return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) );
+ }
+
+ StdString::RegexMatcher Matches(std::string const& regex, CaseSensitive::Choice caseSensitivity) {
+ return StdString::RegexMatcher(regex, caseSensitivity);
+ }
+
+} // namespace Matchers
+} // namespace Catch
+// end catch_matchers_string.cpp
+// start catch_message.cpp
+
+// start catch_uncaught_exceptions.h
+
+namespace Catch {
+ bool uncaught_exceptions();
+} // end namespace Catch
+
+// end catch_uncaught_exceptions.h
+namespace Catch {
+
+ MessageInfo::MessageInfo( std::string const& _macroName,
+ SourceLineInfo const& _lineInfo,
+ ResultWas::OfType _type )
+ : macroName( _macroName ),
+ lineInfo( _lineInfo ),
+ type( _type ),
+ sequence( ++globalCount )
+ {}
+
+ bool MessageInfo::operator==( MessageInfo const& other ) const {
+ return sequence == other.sequence;
+ }
+
+ bool MessageInfo::operator<( MessageInfo const& other ) const {
+ return sequence < other.sequence;
+ }
+
+ // This may need protecting if threading support is added
+ unsigned int MessageInfo::globalCount = 0;
+
+ ////////////////////////////////////////////////////////////////////////////
+
+ Catch::MessageBuilder::MessageBuilder( std::string const& macroName,
+ SourceLineInfo const& lineInfo,
+ ResultWas::OfType type )
+ :m_info(macroName, lineInfo, type) {}
+
+ ////////////////////////////////////////////////////////////////////////////
+
+ ScopedMessage::ScopedMessage( MessageBuilder const& builder )
+ : m_info( builder.m_info )
+ {
+ m_info.message = builder.m_stream.str();
+ getResultCapture().pushScopedMessage( m_info );
+ }
+
+ ScopedMessage::~ScopedMessage() {
+ if ( !uncaught_exceptions() ){
+ getResultCapture().popScopedMessage(m_info);
+ }
+ }
+} // end namespace Catch
+// end catch_message.cpp
+// start catch_random_number_generator.cpp
+
+// start catch_random_number_generator.h
+
+#include <algorithm>
+
+namespace Catch {
+
+ struct IConfig;
+
+ void seedRng( IConfig const& config );
+
+ unsigned int rngSeed();
+
+ struct RandomNumberGenerator {
+ using result_type = unsigned int;
+
+ static constexpr result_type (min)() { return 0; }
+ static constexpr result_type (max)() { return 1000000; }
+
+ result_type operator()( result_type n ) const;
+ result_type operator()() const;
+
+ template<typename V>
+ static void shuffle( V& vector ) {
+ RandomNumberGenerator rng;
+ std::shuffle( vector.begin(), vector.end(), rng );
+ }
+ };
+
+}
+
+// end catch_random_number_generator.h
+#include <cstdlib>
+
+namespace Catch {
+
+ void seedRng( IConfig const& config ) {
+ if( config.rngSeed() != 0 )
+ std::srand( config.rngSeed() );
+ }
+ unsigned int rngSeed() {
+ return getCurrentContext().getConfig()->rngSeed();
+ }
+
+ RandomNumberGenerator::result_type RandomNumberGenerator::operator()( result_type n ) const {
+ return std::rand() % n;
+ }
+ RandomNumberGenerator::result_type RandomNumberGenerator::operator()() const {
+ return std::rand() % (max)();
+ }
+
+}
+// end catch_random_number_generator.cpp
+// start catch_registry_hub.cpp
+
+// start catch_test_case_registry_impl.h
+
+#include <vector>
+#include <set>
+#include <algorithm>
+#include <ios>
+
+namespace Catch {
+
+ class TestCase;
+ struct IConfig;
+
+ std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases );
+ bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
+
+ void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions );
+
+ std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
+ std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
+
+ class TestRegistry : public ITestCaseRegistry {
+ public:
+ virtual ~TestRegistry() = default;
+
+ virtual void registerTest( TestCase const& testCase );
+
+ std::vector<TestCase> const& getAllTests() const override;
+ std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const override;
+
+ private:
+ std::vector<TestCase> m_functions;
+ mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder;
+ mutable std::vector<TestCase> m_sortedFunctions;
+ std::size_t m_unnamedCount = 0;
+ std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ class TestInvokerAsFunction : public ITestInvoker {
+ void(*m_testAsFunction)();
+ public:
+ TestInvokerAsFunction( void(*testAsFunction)() ) noexcept;
+
+ void invoke() const override;
+ };
+
+ std::string extractClassName( StringRef const& classOrQualifiedMethodName );
+
+ ///////////////////////////////////////////////////////////////////////////
+
+} // end namespace Catch
+
+// end catch_test_case_registry_impl.h
+// start catch_reporter_registry.h
+
+#include <map>
+
+namespace Catch {
+
+ class ReporterRegistry : public IReporterRegistry {
+
+ public:
+
+ ~ReporterRegistry() override;
+
+ IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const override;
+
+ void registerReporter( std::string const& name, IReporterFactoryPtr const& factory );
+ void registerListener( IReporterFactoryPtr const& factory );
+
+ FactoryMap const& getFactories() const override;
+ Listeners const& getListeners() const override;
+
+ private:
+ FactoryMap m_factories;
+ Listeners m_listeners;
+ };
+}
+
+// end catch_reporter_registry.h
+// start catch_tag_alias_registry.h
+
+// start catch_tag_alias.h
+
+#include <string>
+
+namespace Catch {
+
+ struct TagAlias {
+ TagAlias(std::string const& _tag, SourceLineInfo _lineInfo);
+
+ std::string tag;
+ SourceLineInfo lineInfo;
+ };
+
+} // end namespace Catch
+
+// end catch_tag_alias.h
+#include <map>
+
+namespace Catch {
+
+ class TagAliasRegistry : public ITagAliasRegistry {
+ public:
+ ~TagAliasRegistry() override;
+ TagAlias const* find( std::string const& alias ) const override;
+ std::string expandAliases( std::string const& unexpandedTestSpec ) const override;
+ void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo );
+
+ private:
+ std::map<std::string, TagAlias> m_registry;
+ };
+
+} // end namespace Catch
+
+// end catch_tag_alias_registry.h
+// start catch_startup_exception_registry.h
+
+#include <vector>
+#include <exception>
+
+namespace Catch {
+
+ class StartupExceptionRegistry {
+ public:
+ void add(std::exception_ptr const& exception) noexcept;
+ std::vector<std::exception_ptr> const& getExceptions() const noexcept;
+ private:
+ std::vector<std::exception_ptr> m_exceptions;
+ };
+
+} // end namespace Catch
+
+// end catch_startup_exception_registry.h
+namespace Catch {
+
+ namespace {
+
+ class RegistryHub : public IRegistryHub, public IMutableRegistryHub,
+ private NonCopyable {
+
+ public: // IRegistryHub
+ RegistryHub() = default;
+ IReporterRegistry const& getReporterRegistry() const override {
+ return m_reporterRegistry;
+ }
+ ITestCaseRegistry const& getTestCaseRegistry() const override {
+ return m_testCaseRegistry;
+ }
+ IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() override {
+ return m_exceptionTranslatorRegistry;
+ }
+ ITagAliasRegistry const& getTagAliasRegistry() const override {
+ return m_tagAliasRegistry;
+ }
+ StartupExceptionRegistry const& getStartupExceptionRegistry() const override {
+ return m_exceptionRegistry;
+ }
+
+ public: // IMutableRegistryHub
+ void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) override {
+ m_reporterRegistry.registerReporter( name, factory );
+ }
+ void registerListener( IReporterFactoryPtr const& factory ) override {
+ m_reporterRegistry.registerListener( factory );
+ }
+ void registerTest( TestCase const& testInfo ) override {
+ m_testCaseRegistry.registerTest( testInfo );
+ }
+ void registerTranslator( const IExceptionTranslator* translator ) override {
+ m_exceptionTranslatorRegistry.registerTranslator( translator );
+ }
+ void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) override {
+ m_tagAliasRegistry.add( alias, tag, lineInfo );
+ }
+ void registerStartupException() noexcept override {
+ m_exceptionRegistry.add(std::current_exception());
+ }
+
+ private:
+ TestRegistry m_testCaseRegistry;
+ ReporterRegistry m_reporterRegistry;
+ ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
+ TagAliasRegistry m_tagAliasRegistry;
+ StartupExceptionRegistry m_exceptionRegistry;
+ };
+
+ // Single, global, instance
+ RegistryHub*& getTheRegistryHub() {
+ static RegistryHub* theRegistryHub = nullptr;
+ if( !theRegistryHub )
+ theRegistryHub = new RegistryHub();
+ return theRegistryHub;
+ }
+ }
+
+ IRegistryHub& getRegistryHub() {
+ return *getTheRegistryHub();
+ }
+ IMutableRegistryHub& getMutableRegistryHub() {
+ return *getTheRegistryHub();
+ }
+ void cleanUp() {
+ delete getTheRegistryHub();
+ getTheRegistryHub() = nullptr;
+ cleanUpContext();
+ ReusableStringStream::cleanup();
+ }
+ std::string translateActiveException() {
+ return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
+ }
+
+} // end namespace Catch
+// end catch_registry_hub.cpp
+// start catch_reporter_registry.cpp
+
+namespace Catch {
+
+ ReporterRegistry::~ReporterRegistry() = default;
+
+ IStreamingReporterPtr ReporterRegistry::create( std::string const& name, IConfigPtr const& config ) const {
+ auto it = m_factories.find( name );
+ if( it == m_factories.end() )
+ return nullptr;
+ return it->second->create( ReporterConfig( config ) );
+ }
+
+ void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) {
+ m_factories.emplace(name, factory);
+ }
+ void ReporterRegistry::registerListener( IReporterFactoryPtr const& factory ) {
+ m_listeners.push_back( factory );
+ }
+
+ IReporterRegistry::FactoryMap const& ReporterRegistry::getFactories() const {
+ return m_factories;
+ }
+ IReporterRegistry::Listeners const& ReporterRegistry::getListeners() const {
+ return m_listeners;
+ }
+
+}
+// end catch_reporter_registry.cpp
+// start catch_result_type.cpp
+
+namespace Catch {
+
+ bool isOk( ResultWas::OfType resultType ) {
+ return ( resultType & ResultWas::FailureBit ) == 0;
+ }
+ bool isJustInfo( int flags ) {
+ return flags == ResultWas::Info;
+ }
+
+ ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
+ return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
+ }
+
+ bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
+ bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; }
+
+} // end namespace Catch
+// end catch_result_type.cpp
+// start catch_run_context.cpp
+
+#include <cassert>
+#include <algorithm>
+#include <sstream>
+
+namespace Catch {
+
+ class RedirectedStream {
+ std::ostream& m_originalStream;
+ std::ostream& m_redirectionStream;
+ std::streambuf* m_prevBuf;
+
+ public:
+ RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream )
+ : m_originalStream( originalStream ),
+ m_redirectionStream( redirectionStream ),
+ m_prevBuf( m_originalStream.rdbuf() )
+ {
+ m_originalStream.rdbuf( m_redirectionStream.rdbuf() );
+ }
+ ~RedirectedStream() {
+ m_originalStream.rdbuf( m_prevBuf );
+ }
+ };
+
+ class RedirectedStdOut {
+ ReusableStringStream m_rss;
+ RedirectedStream m_cout;
+ public:
+ RedirectedStdOut() : m_cout( Catch::cout(), m_rss.get() ) {}
+ auto str() const -> std::string { return m_rss.str(); }
+ };
+
+ // StdErr has two constituent streams in C++, std::cerr and std::clog
+ // This means that we need to redirect 2 streams into 1 to keep proper
+ // order of writes
+ class RedirectedStdErr {
+ ReusableStringStream m_rss;
+ RedirectedStream m_cerr;
+ RedirectedStream m_clog;
+ public:
+ RedirectedStdErr()
+ : m_cerr( Catch::cerr(), m_rss.get() ),
+ m_clog( Catch::clog(), m_rss.get() )
+ {}
+ auto str() const -> std::string { return m_rss.str(); }
+ };
+
+ RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)
+ : m_runInfo(_config->name()),
+ m_context(getCurrentMutableContext()),
+ m_config(_config),
+ m_reporter(std::move(reporter)),
+ m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal },
+ m_includeSuccessfulResults( m_config->includeSuccessfulResults() )
+ {
+ m_context.setRunner(this);
+ m_context.setConfig(m_config);
+ m_context.setResultCapture(this);
+ m_reporter->testRunStarting(m_runInfo);
+ }
+
+ RunContext::~RunContext() {
+ m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));
+ }
+
+ void RunContext::testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount) {
+ m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount));
+ }
+
+ void RunContext::testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount) {
+ m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting()));
+ }
+
+ Totals RunContext::runTest(TestCase const& testCase) {
+ Totals prevTotals = m_totals;
+
+ std::string redirectedCout;
+ std::string redirectedCerr;
+
+ auto const& testInfo = testCase.getTestCaseInfo();
+
+ m_reporter->testCaseStarting(testInfo);
+
+ m_activeTestCase = &testCase;
+
+ ITracker& rootTracker = m_trackerContext.startRun();
+ assert(rootTracker.isSectionTracker());
+ static_cast<SectionTracker&>(rootTracker).addInitialFilters(m_config->getSectionsToRun());
+ do {
+ m_trackerContext.startCycle();
+ m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo));
+ runCurrentTest(redirectedCout, redirectedCerr);
+ } while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting());
+
+ Totals deltaTotals = m_totals.delta(prevTotals);
+ if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) {
+ deltaTotals.assertions.failed++;
+ deltaTotals.testCases.passed--;
+ deltaTotals.testCases.failed++;
+ }
+ m_totals.testCases += deltaTotals.testCases;
+ m_reporter->testCaseEnded(TestCaseStats(testInfo,
+ deltaTotals,
+ redirectedCout,
+ redirectedCerr,
+ aborting()));
+
+ m_activeTestCase = nullptr;
+ m_testCaseTracker = nullptr;
+
+ return deltaTotals;
+ }
+
+ IConfigPtr RunContext::config() const {
+ return m_config;
+ }
+
+ IStreamingReporter& RunContext::reporter() const {
+ return *m_reporter;
+ }
+
+ void RunContext::assertionEnded(AssertionResult const & result) {
+ if (result.getResultType() == ResultWas::Ok) {
+ m_totals.assertions.passed++;
+ m_lastAssertionPassed = true;
+ } else if (!result.isOk()) {
+ m_lastAssertionPassed = false;
+ if( m_activeTestCase->getTestCaseInfo().okToFail() )
+ m_totals.assertions.failedButOk++;
+ else
+ m_totals.assertions.failed++;
+ }
+ else {
+ m_lastAssertionPassed = true;
+ }
+
+ // We have no use for the return value (whether messages should be cleared), because messages were made scoped
+ // and should be let to clear themselves out.
+ static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
+
+ // Reset working state
+ resetAssertionInfo();
+ m_lastResult = result;
+ }
+ void RunContext::resetAssertionInfo() {
+ m_lastAssertionInfo.macroName = StringRef();
+ m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr;
+ }
+
+ bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) {
+ ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo));
+ if (!sectionTracker.isOpen())
+ return false;
+ m_activeSections.push_back(&sectionTracker);
+
+ m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
+
+ m_reporter->sectionStarting(sectionInfo);
+
+ assertions = m_totals.assertions;
+
+ return true;
+ }
+
+ bool RunContext::testForMissingAssertions(Counts& assertions) {
+ if (assertions.total() != 0)
+ return false;
+ if (!m_config->warnAboutMissingAssertions())
+ return false;
+ if (m_trackerContext.currentTracker().hasChildren())
+ return false;
+ m_totals.assertions.failed++;
+ assertions.failed++;
+ return true;
+ }
+
+ void RunContext::sectionEnded(SectionEndInfo const & endInfo) {
+ Counts assertions = m_totals.assertions - endInfo.prevAssertions;
+ bool missingAssertions = testForMissingAssertions(assertions);
+
+ if (!m_activeSections.empty()) {
+ m_activeSections.back()->close();
+ m_activeSections.pop_back();
+ }
+
+ m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));
+ m_messages.clear();
+ }
+
+ void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) {
+ if (m_unfinishedSections.empty())
+ m_activeSections.back()->fail();
+ else
+ m_activeSections.back()->close();
+ m_activeSections.pop_back();
+
+ m_unfinishedSections.push_back(endInfo);
+ }
+ void RunContext::benchmarkStarting( BenchmarkInfo const& info ) {
+ m_reporter->benchmarkStarting( info );
+ }
+ void RunContext::benchmarkEnded( BenchmarkStats const& stats ) {
+ m_reporter->benchmarkEnded( stats );
+ }
+
+ void RunContext::pushScopedMessage(MessageInfo const & message) {
+ m_messages.push_back(message);
+ }
+
+ void RunContext::popScopedMessage(MessageInfo const & message) {
+ m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
+ }
+
+ std::string RunContext::getCurrentTestName() const {
+ return m_activeTestCase
+ ? m_activeTestCase->getTestCaseInfo().name
+ : std::string();
+ }
+
+ const AssertionResult * RunContext::getLastResult() const {
+ return &(*m_lastResult);
+ }
+
+ void RunContext::exceptionEarlyReported() {
+ m_shouldReportUnexpected = false;
+ }
+
+ void RunContext::handleFatalErrorCondition( StringRef message ) {
+ // First notify reporter that bad things happened
+ m_reporter->fatalErrorEncountered(message);
+
+ // Don't rebuild the result -- the stringification itself can cause more fatal errors
+ // Instead, fake a result data.
+ AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } );
+ tempResult.message = message;
+ AssertionResult result(m_lastAssertionInfo, tempResult);
+
+ assertionEnded(result);
+
+ handleUnfinishedSections();
+
+ // Recreate section for test case (as we will lose the one that was in scope)
+ auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
+ SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description);
+
+ Counts assertions;
+ assertions.failed = 1;
+ SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false);
+ m_reporter->sectionEnded(testCaseSectionStats);
+
+ auto const& testInfo = m_activeTestCase->getTestCaseInfo();
+
+ Totals deltaTotals;
+ deltaTotals.testCases.failed = 1;
+ deltaTotals.assertions.failed = 1;
+ m_reporter->testCaseEnded(TestCaseStats(testInfo,
+ deltaTotals,
+ std::string(),
+ std::string(),
+ false));
+ m_totals.testCases.failed++;
+ testGroupEnded(std::string(), m_totals, 1, 1);
+ m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));
+ }
+
+ bool RunContext::lastAssertionPassed() {
+ return m_lastAssertionPassed;
+ }
+
+ void RunContext::assertionPassed() {
+ m_lastAssertionPassed = true;
+ ++m_totals.assertions.passed;
+ resetAssertionInfo();
+ }
+
+ bool RunContext::aborting() const {
+ return m_totals.assertions.failed == static_cast<std::size_t>(m_config->abortAfter());
+ }
+
+ void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {
+ auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
+ SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description);
+ m_reporter->sectionStarting(testCaseSection);
+ Counts prevAssertions = m_totals.assertions;
+ double duration = 0;
+ m_shouldReportUnexpected = true;
+ m_lastAssertionInfo = { "TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal };
+
+ seedRng(*m_config);
+
+ Timer timer;
+ try {
+ if (m_reporter->getPreferences().shouldRedirectStdOut) {
+ RedirectedStdOut redirectedStdOut;
+ RedirectedStdErr redirectedStdErr;
+ timer.start();
+ invokeActiveTestCase();
+ redirectedCout += redirectedStdOut.str();
+ redirectedCerr += redirectedStdErr.str();
+
+ } else {
+ timer.start();
+ invokeActiveTestCase();
+ }
+ duration = timer.getElapsedSeconds();
+ } catch (TestFailureException&) {
+ // This just means the test was aborted due to failure
+ } catch (...) {
+ // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
+ // are reported without translation at the point of origin.
+ if( m_shouldReportUnexpected ) {
+ AssertionReaction dummyReaction;
+ handleUnexpectedInflightException( m_lastAssertionInfo, translateActiveException(), dummyReaction );
+ }
+ }
+ Counts assertions = m_totals.assertions - prevAssertions;
+ bool missingAssertions = testForMissingAssertions(assertions);
+
+ m_testCaseTracker->close();
+ handleUnfinishedSections();
+ m_messages.clear();
+
+ SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
+ m_reporter->sectionEnded(testCaseSectionStats);
+ }
+
+ void RunContext::invokeActiveTestCase() {
+ FatalConditionHandler fatalConditionHandler; // Handle signals
+ m_activeTestCase->invoke();
+ fatalConditionHandler.reset();
+ }
+
+ void RunContext::handleUnfinishedSections() {
+ // If sections ended prematurely due to an exception we stored their
+ // infos here so we can tear them down outside the unwind process.
+ for (auto it = m_unfinishedSections.rbegin(),
+ itEnd = m_unfinishedSections.rend();
+ it != itEnd;
+ ++it)
+ sectionEnded(*it);
+ m_unfinishedSections.clear();
+ }
+
+ void RunContext::handleExpr(
+ AssertionInfo const& info,
+ ITransientExpression const& expr,
+ AssertionReaction& reaction
+ ) {
+ m_reporter->assertionStarting( info );
+
+ bool negated = isFalseTest( info.resultDisposition );
+ bool result = expr.getResult() != negated;
+
+ if( result ) {
+ if (!m_includeSuccessfulResults) {
+ assertionPassed();
+ }
+ else {
+ reportExpr(info, ResultWas::Ok, &expr, negated);
+ }
+ }
+ else {
+ reportExpr(info, ResultWas::ExpressionFailed, &expr, negated );
+ populateReaction( reaction );
+ }
+ }
+ void RunContext::reportExpr(
+ AssertionInfo const &info,
+ ResultWas::OfType resultType,
+ ITransientExpression const *expr,
+ bool negated ) {
+
+ m_lastAssertionInfo = info;
+ AssertionResultData data( resultType, LazyExpression( negated ) );
+
+ AssertionResult assertionResult{ info, data };
+ assertionResult.m_resultData.lazyExpression.m_transientExpression = expr;
+
+ assertionEnded( assertionResult );
+ }
+
+ void RunContext::handleMessage(
+ AssertionInfo const& info,
+ ResultWas::OfType resultType,
+ StringRef const& message,
+ AssertionReaction& reaction
+ ) {
+ m_reporter->assertionStarting( info );
+
+ m_lastAssertionInfo = info;
+
+ AssertionResultData data( resultType, LazyExpression( false ) );
+ data.message = message;
+ AssertionResult assertionResult{ m_lastAssertionInfo, data };
+ assertionEnded( assertionResult );
+ if( !assertionResult.isOk() )
+ populateReaction( reaction );
+ }
+ void RunContext::handleUnexpectedExceptionNotThrown(
+ AssertionInfo const& info,
+ AssertionReaction& reaction
+ ) {
+ handleNonExpr(info, Catch::ResultWas::DidntThrowException, reaction);
+ }
+
+ void RunContext::handleUnexpectedInflightException(
+ AssertionInfo const& info,
+ std::string const& message,
+ AssertionReaction& reaction
+ ) {
+ m_lastAssertionInfo = info;
+
+ AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
+ data.message = message;
+ AssertionResult assertionResult{ info, data };
+ assertionEnded( assertionResult );
+ populateReaction( reaction );
+ }
+
+ void RunContext::populateReaction( AssertionReaction& reaction ) {
+ reaction.shouldDebugBreak = m_config->shouldDebugBreak();
+ reaction.shouldThrow = aborting() || (m_lastAssertionInfo.resultDisposition & ResultDisposition::Normal);
+ }
+
+ void RunContext::handleIncomplete(
+ AssertionInfo const& info
+ ) {
+ m_lastAssertionInfo = info;
+
+ AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
+ data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
+ AssertionResult assertionResult{ info, data };
+ assertionEnded( assertionResult );
+ }
+ void RunContext::handleNonExpr(
+ AssertionInfo const &info,
+ ResultWas::OfType resultType,
+ AssertionReaction &reaction
+ ) {
+ m_lastAssertionInfo = info;
+
+ AssertionResultData data( resultType, LazyExpression( false ) );
+ AssertionResult assertionResult{ info, data };
+ assertionEnded( assertionResult );
+
+ if( !assertionResult.isOk() )
+ populateReaction( reaction );
+ }
+
+ IResultCapture& getResultCapture() {
+ if (auto* capture = getCurrentContext().getResultCapture())
+ return *capture;
+ else
+ CATCH_INTERNAL_ERROR("No result capture instance");
+ }
+}
+// end catch_run_context.cpp
+// start catch_section.cpp
+
+namespace Catch {
+
+ Section::Section( SectionInfo const& info )
+ : m_info( info ),
+ m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
+ {
+ m_timer.start();
+ }
+
+ Section::~Section() {
+ if( m_sectionIncluded ) {
+ SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
+ if( uncaught_exceptions() )
+ getResultCapture().sectionEndedEarly( endInfo );
+ else
+ getResultCapture().sectionEnded( endInfo );
+ }
+ }
+
+ // This indicates whether the section should be executed or not
+ Section::operator bool() const {
+ return m_sectionIncluded;
+ }
+
+} // end namespace Catch
+// end catch_section.cpp
+// start catch_section_info.cpp
+
+namespace Catch {
+
+ SectionInfo::SectionInfo
+ ( SourceLineInfo const& _lineInfo,
+ std::string const& _name,
+ std::string const& _description )
+ : name( _name ),
+ description( _description ),
+ lineInfo( _lineInfo )
+ {}
+
+ SectionEndInfo::SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds )
+ : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
+ {}
+
+} // end namespace Catch
+// end catch_section_info.cpp
+// start catch_session.cpp
+
+// start catch_session.h
+
+#include <memory>
+
+namespace Catch {
+
+ class Session : NonCopyable {
+ public:
+
+ Session();
+ ~Session() override;
+
+ void showHelp() const;
+ void libIdentify();
+
+ int applyCommandLine( int argc, char const * const * argv );
+
+ void useConfigData( ConfigData const& configData );
+
+ int run( int argc, char* argv[] );
+ #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
+ int run( int argc, wchar_t* const argv[] );
+ #endif
+ int run();
+
+ clara::Parser const& cli() const;
+ void cli( clara::Parser const& newParser );
+ ConfigData& configData();
+ Config& config();
+ private:
+ int runInternal();
+
+ clara::Parser m_cli;
+ ConfigData m_configData;
+ std::shared_ptr<Config> m_config;
+ bool m_startupExceptions = false;
+ };
+
+} // end namespace Catch
+
+// end catch_session.h
+// start catch_version.h
+
+#include <iosfwd>
+
+namespace Catch {
+
+ // Versioning information
+ struct Version {
+ Version( Version const& ) = delete;
+ Version& operator=( Version const& ) = delete;
+ Version( unsigned int _majorVersion,
+ unsigned int _minorVersion,
+ unsigned int _patchNumber,
+ char const * const _branchName,
+ unsigned int _buildNumber );
+
+ unsigned int const majorVersion;
+ unsigned int const minorVersion;
+ unsigned int const patchNumber;
+
+ // buildNumber is only used if branchName is not null
+ char const * const branchName;
+ unsigned int const buildNumber;
+
+ friend std::ostream& operator << ( std::ostream& os, Version const& version );
+ };
+
+ Version const& libraryVersion();
+}
+
+// end catch_version.h
+#include <cstdlib>
+#include <iomanip>
+
+namespace Catch {
+
+ namespace {
+ const int MaxExitCode = 255;
+
+ IStreamingReporterPtr createReporter(std::string const& reporterName, IConfigPtr const& config) {
+ auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config);
+ CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << "'");
+
+ return reporter;
+ }
+
+#ifndef CATCH_CONFIG_DEFAULT_REPORTER
+#define CATCH_CONFIG_DEFAULT_REPORTER "console"
+#endif
+
+ IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const& config) {
+ auto const& reporterNames = config->getReporterNames();
+ if (reporterNames.empty())
+ return createReporter(CATCH_CONFIG_DEFAULT_REPORTER, config);
+
+ IStreamingReporterPtr reporter;
+ for (auto const& name : reporterNames)
+ addReporter(reporter, createReporter(name, config));
+ return reporter;
+ }
+
+#undef CATCH_CONFIG_DEFAULT_REPORTER
+
+ void addListeners(IStreamingReporterPtr& reporters, IConfigPtr const& config) {
+ auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners();
+ for (auto const& listener : listeners)
+ addReporter(reporters, listener->create(Catch::ReporterConfig(config)));
+ }
+
+ Catch::Totals runTests(std::shared_ptr<Config> const& config) {
+ IStreamingReporterPtr reporter = makeReporter(config);
+ addListeners(reporter, config);
+
+ RunContext context(config, std::move(reporter));
+
+ Totals totals;
+
+ context.testGroupStarting(config->name(), 1, 1);
+
+ TestSpec testSpec = config->testSpec();
+
+ auto const& allTestCases = getAllTestCasesSorted(*config);
+ for (auto const& testCase : allTestCases) {
+ if (!context.aborting() && matchTest(testCase, testSpec, *config))
+ totals += context.runTest(testCase);
+ else
+ context.reporter().skipTest(testCase);
+ }
+
+ if (config->warnAboutNoTests() && totals.testCases.total() == 0) {
+ ReusableStringStream testConfig;
+
+ bool first = true;
+ for (const auto& input : config->getTestsOrTags()) {
+ if (!first) { testConfig << ' '; }
+ first = false;
+ testConfig << input;
+ }
+
+ context.reporter().noMatchingTestCases(testConfig.str());
+ totals.error = -1;
+ }
+
+ context.testGroupEnded(config->name(), totals, 1, 1);
+ return totals;
+ }
+
+ void applyFilenamesAsTags(Catch::IConfig const& config) {
+ auto& tests = const_cast<std::vector<TestCase>&>(getAllTestCasesSorted(config));
+ for (auto& testCase : tests) {
+ auto tags = testCase.tags;
+
+ std::string filename = testCase.lineInfo.file;
+ auto lastSlash = filename.find_last_of("\\/");
+ if (lastSlash != std::string::npos) {
+ filename.erase(0, lastSlash);
+ filename[0] = '#';
+ }
+
+ auto lastDot = filename.find_last_of('.');
+ if (lastDot != std::string::npos) {
+ filename.erase(lastDot);
+ }
+
+ tags.push_back(std::move(filename));
+ setTags(testCase, tags);
+ }
+ }
+
+ } // anon namespace
+
+ Session::Session() {
+ static bool alreadyInstantiated = false;
+ if( alreadyInstantiated ) {
+ try { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); }
+ catch(...) { getMutableRegistryHub().registerStartupException(); }
+ }
+
+ const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
+ if ( !exceptions.empty() ) {
+ m_startupExceptions = true;
+ Colour colourGuard( Colour::Red );
+ Catch::cerr() << "Errors occurred during startup!" << '\n';
+ // iterate over all exceptions and notify user
+ for ( const auto& ex_ptr : exceptions ) {
+ try {
+ std::rethrow_exception(ex_ptr);
+ } catch ( std::exception const& ex ) {
+ Catch::cerr() << Column( ex.what() ).indent(2) << '\n';
+ }
+ }
+ }
+
+ alreadyInstantiated = true;
+ m_cli = makeCommandLineParser( m_configData );
+ }
+ Session::~Session() {
+ Catch::cleanUp();
+ }
+
+ void Session::showHelp() const {
+ Catch::cout()
+ << "\nCatch v" << libraryVersion() << "\n"
+ << m_cli << std::endl
+ << "For more detailed usage please see the project docs\n" << std::endl;
+ }
+ void Session::libIdentify() {
+ Catch::cout()
+ << std::left << std::setw(16) << "description: " << "A Catch test executable\n"
+ << std::left << std::setw(16) << "category: " << "testframework\n"
+ << std::left << std::setw(16) << "framework: " << "Catch Test\n"
+ << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
+ }
+
+ int Session::applyCommandLine( int argc, char const * const * argv ) {
+ if( m_startupExceptions )
+ return 1;
+
+ auto result = m_cli.parse( clara::Args( argc, argv ) );
+ if( !result ) {
+ Catch::cerr()
+ << Colour( Colour::Red )
+ << "\nError(s) in input:\n"
+ << Column( result.errorMessage() ).indent( 2 )
+ << "\n\n";
+ Catch::cerr() << "Run with -? for usage\n" << std::endl;
+ return MaxExitCode;
+ }
+
+ if( m_configData.showHelp )
+ showHelp();
+ if( m_configData.libIdentify )
+ libIdentify();
+ m_config.reset();
+ return 0;
+ }
+
+ void Session::useConfigData( ConfigData const& configData ) {
+ m_configData = configData;
+ m_config.reset();
+ }
+
+ int Session::run( int argc, char* argv[] ) {
+ if( m_startupExceptions )
+ return 1;
+ int returnCode = applyCommandLine( argc, argv );
+ if( returnCode == 0 )
+ returnCode = run();
+ return returnCode;
+ }
+
+#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
+ int Session::run( int argc, wchar_t* const argv[] ) {
+
+ char **utf8Argv = new char *[ argc ];
+
+ for ( int i = 0; i < argc; ++i ) {
+ int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL );
+
+ utf8Argv[ i ] = new char[ bufSize ];
+
+ WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL );
+ }
+
+ int returnCode = run( argc, utf8Argv );
+
+ for ( int i = 0; i < argc; ++i )
+ delete [] utf8Argv[ i ];
+
+ delete [] utf8Argv;
+
+ return returnCode;
+ }
+#endif
+ int Session::run() {
+ if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) {
+ Catch::cout() << "...waiting for enter/ return before starting" << std::endl;
+ static_cast<void>(std::getchar());
+ }
+ int exitCode = runInternal();
+ if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) {
+ Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl;
+ static_cast<void>(std::getchar());
+ }
+ return exitCode;
+ }
+
+ clara::Parser const& Session::cli() const {
+ return m_cli;
+ }
+ void Session::cli( clara::Parser const& newParser ) {
+ m_cli = newParser;
+ }
+ ConfigData& Session::configData() {
+ return m_configData;
+ }
+ Config& Session::config() {
+ if( !m_config )
+ m_config = std::make_shared<Config>( m_configData );
+ return *m_config;
+ }
+
+ int Session::runInternal() {
+ if( m_startupExceptions )
+ return 1;
+
+ if( m_configData.showHelp || m_configData.libIdentify )
+ return 0;
+
+ try
+ {
+ config(); // Force config to be constructed
+
+ seedRng( *m_config );
+
+ if( m_configData.filenamesAsTags )
+ applyFilenamesAsTags( *m_config );
+
+ // Handle list request
+ if( Option<std::size_t> listed = list( config() ) )
+ return static_cast<int>( *listed );
+
+ auto totals = runTests( m_config );
+ // Note that on unices only the lower 8 bits are usually used, clamping
+ // the return value to 255 prevents false negative when some multiple
+ // of 256 tests has failed
+ return (std::min) (MaxExitCode, (std::max) (totals.error, static_cast<int>(totals.assertions.failed)));
+ }
+ catch( std::exception& ex ) {
+ Catch::cerr() << ex.what() << std::endl;
+ return MaxExitCode;
+ }
+ }
+
+} // end namespace Catch
+// end catch_session.cpp
+// start catch_startup_exception_registry.cpp
+
+namespace Catch {
+ void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
+ try {
+ m_exceptions.push_back(exception);
+ }
+ catch(...) {
+ // If we run out of memory during start-up there's really not a lot more we can do about it
+ std::terminate();
+ }
+ }
+
+ std::vector<std::exception_ptr> const& StartupExceptionRegistry::getExceptions() const noexcept {
+ return m_exceptions;
+ }
+
+} // end namespace Catch
+// end catch_startup_exception_registry.cpp
+// start catch_stream.cpp
+
+#include <cstdio>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <vector>
+#include <memory>
+
+#if defined(__clang__)
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wexit-time-destructors"
+#endif
+
+namespace Catch {
+
+ Catch::IStream::~IStream() = default;
+
+ namespace detail { namespace {
+ template<typename WriterF, std::size_t bufferSize=256>
+ class StreamBufImpl : public std::streambuf {
+ char data[bufferSize];
+ WriterF m_writer;
+
+ public:
+ StreamBufImpl() {
+ setp( data, data + sizeof(data) );
+ }
+
+ ~StreamBufImpl() noexcept {
+ StreamBufImpl::sync();
+ }
+
+ private:
+ int overflow( int c ) override {
+ sync();
+
+ if( c != EOF ) {
+ if( pbase() == epptr() )
+ m_writer( std::string( 1, static_cast<char>( c ) ) );
+ else
+ sputc( static_cast<char>( c ) );
+ }
+ return 0;
+ }
+
+ int sync() override {
+ if( pbase() != pptr() ) {
+ m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
+ setp( pbase(), epptr() );
+ }
+ return 0;
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ struct OutputDebugWriter {
+
+ void operator()( std::string const&str ) {
+ writeToDebugConsole( str );
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ class FileStream : public IStream {
+ mutable std::ofstream m_ofs;
+ public:
+ FileStream( StringRef filename ) {
+ m_ofs.open( filename.c_str() );
+ CATCH_ENFORCE( !m_ofs.fail(), "Unable to open file: '" << filename << "'" );
+ }
+ ~FileStream() override = default;
+ public: // IStream
+ std::ostream& stream() const override {
+ return m_ofs;
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ class CoutStream : public IStream {
+ mutable std::ostream m_os;
+ public:
+ // Store the streambuf from cout up-front because
+ // cout may get redirected when running tests
+ CoutStream() : m_os( Catch::cout().rdbuf() ) {}
+ ~CoutStream() override = default;
+
+ public: // IStream
+ std::ostream& stream() const override { return m_os; }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ class DebugOutStream : public IStream {
+ std::unique_ptr<StreamBufImpl<OutputDebugWriter>> m_streamBuf;
+ mutable std::ostream m_os;
+ public:
+ DebugOutStream()
+ : m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
+ m_os( m_streamBuf.get() )
+ {}
+
+ ~DebugOutStream() override = default;
+
+ public: // IStream
+ std::ostream& stream() const override { return m_os; }
+ };
+
+ }} // namespace anon::detail
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ auto makeStream( StringRef const &filename ) -> IStream const* {
+ if( filename.empty() )
+ return new detail::CoutStream();
+ else if( filename[0] == '%' ) {
+ if( filename == "%debug" )
+ return new detail::DebugOutStream();
+ else
+ CATCH_ERROR( "Unrecognised stream: '" << filename << "'" );
+ }
+ else
+ return new detail::FileStream( filename );
+ }
+
+ // This class encapsulates the idea of a pool of ostringstreams that can be reused.
+ struct StringStreams {
+ std::vector<std::unique_ptr<std::ostringstream>> m_streams;
+ std::vector<std::size_t> m_unused;
+ std::ostringstream m_referenceStream; // Used for copy state/ flags from
+ static StringStreams* s_instance;
+
+ auto add() -> std::size_t {
+ if( m_unused.empty() ) {
+ m_streams.push_back( std::unique_ptr<std::ostringstream>( new std::ostringstream ) );
+ return m_streams.size()-1;
+ }
+ else {
+ auto index = m_unused.back();
+ m_unused.pop_back();
+ return index;
+ }
+ }
+
+ void release( std::size_t index ) {
+ m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state
+ m_unused.push_back(index);
+ }
+
+ // !TBD: put in TLS
+ static auto instance() -> StringStreams& {
+ if( !s_instance )
+ s_instance = new StringStreams();
+ return *s_instance;
+ }
+ static void cleanup() {
+ delete s_instance;
+ s_instance = nullptr;
+ }
+ };
+
+ StringStreams* StringStreams::s_instance = nullptr;
+
+ void ReusableStringStream::cleanup() {
+ StringStreams::cleanup();
+ }
+
+ ReusableStringStream::ReusableStringStream()
+ : m_index( StringStreams::instance().add() ),
+ m_oss( StringStreams::instance().m_streams[m_index].get() )
+ {}
+
+ ReusableStringStream::~ReusableStringStream() {
+ static_cast<std::ostringstream*>( m_oss )->str("");
+ m_oss->clear();
+ StringStreams::instance().release( m_index );
+ }
+
+ auto ReusableStringStream::str() const -> std::string {
+ return static_cast<std::ostringstream*>( m_oss )->str();
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+
+#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
+ std::ostream& cout() { return std::cout; }
+ std::ostream& cerr() { return std::cerr; }
+ std::ostream& clog() { return std::clog; }
+#endif
+}
+
+#if defined(__clang__)
+# pragma clang diagnostic pop
+#endif
+// end catch_stream.cpp
+// start catch_string_manip.cpp
+
+#include <algorithm>
+#include <ostream>
+#include <cstring>
+#include <cctype>
+
+namespace Catch {
+
+ bool startsWith( std::string const& s, std::string const& prefix ) {
+ return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
+ }
+ bool startsWith( std::string const& s, char prefix ) {
+ return !s.empty() && s[0] == prefix;
+ }
+ bool endsWith( std::string const& s, std::string const& suffix ) {
+ return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
+ }
+ bool endsWith( std::string const& s, char suffix ) {
+ return !s.empty() && s[s.size()-1] == suffix;
+ }
+ bool contains( std::string const& s, std::string const& infix ) {
+ return s.find( infix ) != std::string::npos;
+ }
+ char toLowerCh(char c) {
+ return static_cast<char>( std::tolower( c ) );
+ }
+ void toLowerInPlace( std::string& s ) {
+ std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
+ }
+ std::string toLower( std::string const& s ) {
+ std::string lc = s;
+ toLowerInPlace( lc );
+ return lc;
+ }
+ std::string trim( std::string const& str ) {
+ static char const* whitespaceChars = "\n\r\t ";
+ std::string::size_type start = str.find_first_not_of( whitespaceChars );
+ std::string::size_type end = str.find_last_not_of( whitespaceChars );
+
+ return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();
+ }
+
+ bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
+ bool replaced = false;
+ std::size_t i = str.find( replaceThis );
+ while( i != std::string::npos ) {
+ replaced = true;
+ str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
+ if( i < str.size()-withThis.size() )
+ i = str.find( replaceThis, i+withThis.size() );
+ else
+ i = std::string::npos;
+ }
+ return replaced;
+ }
+
+ pluralise::pluralise( std::size_t count, std::string const& label )
+ : m_count( count ),
+ m_label( label )
+ {}
+
+ std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
+ os << pluraliser.m_count << ' ' << pluraliser.m_label;
+ if( pluraliser.m_count != 1 )
+ os << 's';
+ return os;
+ }
+
+}
+// end catch_string_manip.cpp
+// start catch_stringref.cpp
+
+#if defined(__clang__)
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wexit-time-destructors"
+#endif
+
+#include <ostream>
+#include <cstring>
+#include <cstdint>
+
+namespace {
+ const uint32_t byte_2_lead = 0xC0;
+ const uint32_t byte_3_lead = 0xE0;
+ const uint32_t byte_4_lead = 0xF0;
+}
+
+namespace Catch {
+ StringRef::StringRef( char const* rawChars ) noexcept
+ : StringRef( rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars) ) )
+ {}
+
+ StringRef::operator std::string() const {
+ return std::string( m_start, m_size );
+ }
+
+ void StringRef::swap( StringRef& other ) noexcept {
+ std::swap( m_start, other.m_start );
+ std::swap( m_size, other.m_size );
+ std::swap( m_data, other.m_data );
+ }
+
+ auto StringRef::c_str() const -> char const* {
+ if( isSubstring() )
+ const_cast<StringRef*>( this )->takeOwnership();
+ return m_start;
+ }
+ auto StringRef::currentData() const noexcept -> char const* {
+ return m_start;
+ }
+
+ auto StringRef::isOwned() const noexcept -> bool {
+ return m_data != nullptr;
+ }
+ auto StringRef::isSubstring() const noexcept -> bool {
+ return m_start[m_size] != '\0';
+ }
+
+ void StringRef::takeOwnership() {
+ if( !isOwned() ) {
+ m_data = new char[m_size+1];
+ memcpy( m_data, m_start, m_size );
+ m_data[m_size] = '\0';
+ m_start = m_data;
+ }
+ }
+ auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef {
+ if( start < m_size )
+ return StringRef( m_start+start, size );
+ else
+ return StringRef();
+ }
+ auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool {
+ return
+ size() == other.size() &&
+ (std::strncmp( m_start, other.m_start, size() ) == 0);
+ }
+ auto StringRef::operator != ( StringRef const& other ) const noexcept -> bool {
+ return !operator==( other );
+ }
+
+ auto StringRef::operator[](size_type index) const noexcept -> char {
+ return m_start[index];
+ }
+
+ auto StringRef::numberOfCharacters() const noexcept -> size_type {
+ size_type noChars = m_size;
+ // Make adjustments for uft encodings
+ for( size_type i=0; i < m_size; ++i ) {
+ char c = m_start[i];
+ if( ( c & byte_2_lead ) == byte_2_lead ) {
+ noChars--;
+ if (( c & byte_3_lead ) == byte_3_lead )
+ noChars--;
+ if( ( c & byte_4_lead ) == byte_4_lead )
+ noChars--;
+ }
+ }
+ return noChars;
+ }
+
+ auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string {
+ std::string str;
+ str.reserve( lhs.size() + rhs.size() );
+ str += lhs;
+ str += rhs;
+ return str;
+ }
+ auto operator + ( StringRef const& lhs, const char* rhs ) -> std::string {
+ return std::string( lhs ) + std::string( rhs );
+ }
+ auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string {
+ return std::string( lhs ) + std::string( rhs );
+ }
+
+ auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& {
+ return os.write(str.currentData(), str.size());
+ }
+
+ auto operator+=( std::string& lhs, StringRef const& rhs ) -> std::string& {
+ lhs.append(rhs.currentData(), rhs.size());
+ return lhs;
+ }
+
+} // namespace Catch
+
+#if defined(__clang__)
+# pragma clang diagnostic pop
+#endif
+// end catch_stringref.cpp
+// start catch_tag_alias.cpp
+
+namespace Catch {
+ TagAlias::TagAlias(std::string const & _tag, SourceLineInfo _lineInfo): tag(_tag), lineInfo(_lineInfo) {}
+}
+// end catch_tag_alias.cpp
+// start catch_tag_alias_autoregistrar.cpp
+
+namespace Catch {
+
+ RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) {
+ try {
+ getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);
+ } catch (...) {
+ // Do not throw when constructing global objects, instead register the exception to be processed later
+ getMutableRegistryHub().registerStartupException();
+ }
+ }
+
+}
+// end catch_tag_alias_autoregistrar.cpp
+// start catch_tag_alias_registry.cpp
+
+#include <sstream>
+
+namespace Catch {
+
+ TagAliasRegistry::~TagAliasRegistry() {}
+
+ TagAlias const* TagAliasRegistry::find( std::string const& alias ) const {
+ auto it = m_registry.find( alias );
+ if( it != m_registry.end() )
+ return &(it->second);
+ else
+ return nullptr;
+ }
+
+ std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
+ std::string expandedTestSpec = unexpandedTestSpec;
+ for( auto const& registryKvp : m_registry ) {
+ std::size_t pos = expandedTestSpec.find( registryKvp.first );
+ if( pos != std::string::npos ) {
+ expandedTestSpec = expandedTestSpec.substr( 0, pos ) +
+ registryKvp.second.tag +
+ expandedTestSpec.substr( pos + registryKvp.first.size() );
+ }
+ }
+ return expandedTestSpec;
+ }
+
+ void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) {
+ CATCH_ENFORCE( startsWith(alias, "[@") && endsWith(alias, ']'),
+ "error: tag alias, '" << alias << "' is not of the form [@alias name].\n" << lineInfo );
+
+ CATCH_ENFORCE( m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second,
+ "error: tag alias, '" << alias << "' already registered.\n"
+ << "\tFirst seen at: " << find(alias)->lineInfo << "\n"
+ << "\tRedefined at: " << lineInfo );
+ }
+
+ ITagAliasRegistry::~ITagAliasRegistry() {}
+
+ ITagAliasRegistry const& ITagAliasRegistry::get() {
+ return getRegistryHub().getTagAliasRegistry();
+ }
+
+} // end namespace Catch
+// end catch_tag_alias_registry.cpp
+// start catch_test_case_info.cpp
+
+#include <cctype>
+#include <exception>
+#include <algorithm>
+#include <sstream>
+
+namespace Catch {
+
+ TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
+ if( startsWith( tag, '.' ) ||
+ tag == "!hide" )
+ return TestCaseInfo::IsHidden;
+ else if( tag == "!throws" )
+ return TestCaseInfo::Throws;
+ else if( tag == "!shouldfail" )
+ return TestCaseInfo::ShouldFail;
+ else if( tag == "!mayfail" )
+ return TestCaseInfo::MayFail;
+ else if( tag == "!nonportable" )
+ return TestCaseInfo::NonPortable;
+ else if( tag == "!benchmark" )
+ return static_cast<TestCaseInfo::SpecialProperties>( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden );
+ else
+ return TestCaseInfo::None;
+ }
+ bool isReservedTag( std::string const& tag ) {
+ return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( tag[0] );
+ }
+ void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
+ CATCH_ENFORCE( !isReservedTag(tag),
+ "Tag name: [" << tag << "] is not allowed.\n"
+ << "Tag names starting with non alpha-numeric characters are reserved\n"
+ << _lineInfo );
+ }
+
+ TestCase makeTestCase( ITestInvoker* _testCase,
+ std::string const& _className,
+ NameAndTags const& nameAndTags,
+ SourceLineInfo const& _lineInfo )
+ {
+ bool isHidden = false;
+
+ // Parse out tags
+ std::vector<std::string> tags;
+ std::string desc, tag;
+ bool inTag = false;
+ std::string _descOrTags = nameAndTags.tags;
+ for (char c : _descOrTags) {
+ if( !inTag ) {
+ if( c == '[' )
+ inTag = true;
+ else
+ desc += c;
+ }
+ else {
+ if( c == ']' ) {
+ TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
+ if( ( prop & TestCaseInfo::IsHidden ) != 0 )
+ isHidden = true;
+ else if( prop == TestCaseInfo::None )
+ enforceNotReservedTag( tag, _lineInfo );
+
+ tags.push_back( tag );
+ tag.clear();
+ inTag = false;
+ }
+ else
+ tag += c;
+ }
+ }
+ if( isHidden ) {
+ tags.push_back( "." );
+ }
+
+ TestCaseInfo info( nameAndTags.name, _className, desc, tags, _lineInfo );
+ return TestCase( _testCase, std::move(info) );
+ }
+
+ void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags ) {
+ std::sort(begin(tags), end(tags));
+ tags.erase(std::unique(begin(tags), end(tags)), end(tags));
+ testCaseInfo.lcaseTags.clear();
+
+ for( auto const& tag : tags ) {
+ std::string lcaseTag = toLower( tag );
+ testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
+ testCaseInfo.lcaseTags.push_back( lcaseTag );
+ }
+ testCaseInfo.tags = std::move(tags);
+ }
+
+ TestCaseInfo::TestCaseInfo( std::string const& _name,
+ std::string const& _className,
+ std::string const& _description,
+ std::vector<std::string> const& _tags,
+ SourceLineInfo const& _lineInfo )
+ : name( _name ),
+ className( _className ),
+ description( _description ),
+ lineInfo( _lineInfo ),
+ properties( None )
+ {
+ setTags( *this, _tags );
+ }
+
+ bool TestCaseInfo::isHidden() const {
+ return ( properties & IsHidden ) != 0;
+ }
+ bool TestCaseInfo::throws() const {
+ return ( properties & Throws ) != 0;
+ }
+ bool TestCaseInfo::okToFail() const {
+ return ( properties & (ShouldFail | MayFail ) ) != 0;
+ }
+ bool TestCaseInfo::expectedToFail() const {
+ return ( properties & (ShouldFail ) ) != 0;
+ }
+
+ std::string TestCaseInfo::tagsAsString() const {
+ std::string ret;
+ // '[' and ']' per tag
+ std::size_t full_size = 2 * tags.size();
+ for (const auto& tag : tags) {
+ full_size += tag.size();
+ }
+ ret.reserve(full_size);
+ for (const auto& tag : tags) {
+ ret.push_back('[');
+ ret.append(tag);
+ ret.push_back(']');
+ }
+
+ return ret;
+ }
+
+ TestCase::TestCase( ITestInvoker* testCase, TestCaseInfo&& info ) : TestCaseInfo( std::move(info) ), test( testCase ) {}
+
+ TestCase TestCase::withName( std::string const& _newName ) const {
+ TestCase other( *this );
+ other.name = _newName;
+ return other;
+ }
+
+ void TestCase::invoke() const {
+ test->invoke();
+ }
+
+ bool TestCase::operator == ( TestCase const& other ) const {
+ return test.get() == other.test.get() &&
+ name == other.name &&
+ className == other.className;
+ }
+
+ bool TestCase::operator < ( TestCase const& other ) const {
+ return name < other.name;
+ }
+
+ TestCaseInfo const& TestCase::getTestCaseInfo() const
+ {
+ return *this;
+ }
+
+} // end namespace Catch
+// end catch_test_case_info.cpp
+// start catch_test_case_registry_impl.cpp
+
+#include <sstream>
+
+namespace Catch {
+
+ std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
+
+ std::vector<TestCase> sorted = unsortedTestCases;
+
+ switch( config.runOrder() ) {
+ case RunTests::InLexicographicalOrder:
+ std::sort( sorted.begin(), sorted.end() );
+ break;
+ case RunTests::InRandomOrder:
+ seedRng( config );
+ RandomNumberGenerator::shuffle( sorted );
+ break;
+ case RunTests::InDeclarationOrder:
+ // already in declaration order
+ break;
+ }
+ return sorted;
+ }
+ bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
+ return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() );
+ }
+
+ void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
+ std::set<TestCase> seenFunctions;
+ for( auto const& function : functions ) {
+ auto prev = seenFunctions.insert( function );
+ CATCH_ENFORCE( prev.second,
+ "error: TEST_CASE( \"" << function.name << "\" ) already defined.\n"
+ << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
+ << "\tRedefined at " << function.getTestCaseInfo().lineInfo );
+ }
+ }
+
+ std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
+ std::vector<TestCase> filtered;
+ filtered.reserve( testCases.size() );
+ for( auto const& testCase : testCases )
+ if( matchTest( testCase, testSpec, config ) )
+ filtered.push_back( testCase );
+ return filtered;
+ }
+ std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
+ return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
+ }
+
+ void TestRegistry::registerTest( TestCase const& testCase ) {
+ std::string name = testCase.getTestCaseInfo().name;
+ if( name.empty() ) {
+ ReusableStringStream rss;
+ rss << "Anonymous test case " << ++m_unnamedCount;
+ return registerTest( testCase.withName( rss.str() ) );
+ }
+ m_functions.push_back( testCase );
+ }
+
+ std::vector<TestCase> const& TestRegistry::getAllTests() const {
+ return m_functions;
+ }
+ std::vector<TestCase> const& TestRegistry::getAllTestsSorted( IConfig const& config ) const {
+ if( m_sortedFunctions.empty() )
+ enforceNoDuplicateTestCases( m_functions );
+
+ if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
+ m_sortedFunctions = sortTests( config, m_functions );
+ m_currentSortOrder = config.runOrder();
+ }
+ return m_sortedFunctions;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ TestInvokerAsFunction::TestInvokerAsFunction( void(*testAsFunction)() ) noexcept : m_testAsFunction( testAsFunction ) {}
+
+ void TestInvokerAsFunction::invoke() const {
+ m_testAsFunction();
+ }
+
+ std::string extractClassName( StringRef const& classOrQualifiedMethodName ) {
+ std::string className = classOrQualifiedMethodName;
+ if( startsWith( className, '&' ) )
+ {
+ std::size_t lastColons = className.rfind( "::" );
+ std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
+ if( penultimateColons == std::string::npos )
+ penultimateColons = 1;
+ className = className.substr( penultimateColons, lastColons-penultimateColons );
+ }
+ return className;
+ }
+
+} // end namespace Catch
+// end catch_test_case_registry_impl.cpp
+// start catch_test_case_tracker.cpp
+
+#include <algorithm>
+#include <assert.h>
+#include <stdexcept>
+#include <memory>
+#include <sstream>
+
+#if defined(__clang__)
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wexit-time-destructors"
+#endif
+
+namespace Catch {
+namespace TestCaseTracking {
+
+ NameAndLocation::NameAndLocation( std::string const& _name, SourceLineInfo const& _location )
+ : name( _name ),
+ location( _location )
+ {}
+
+ ITracker::~ITracker() = default;
+
+ TrackerContext& TrackerContext::instance() {
+ static TrackerContext s_instance;
+ return s_instance;
+ }
+
+ ITracker& TrackerContext::startRun() {
+ m_rootTracker = std::make_shared<SectionTracker>( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, nullptr );
+ m_currentTracker = nullptr;
+ m_runState = Executing;
+ return *m_rootTracker;
+ }
+
+ void TrackerContext::endRun() {
+ m_rootTracker.reset();
+ m_currentTracker = nullptr;
+ m_runState = NotStarted;
+ }
+
+ void TrackerContext::startCycle() {
+ m_currentTracker = m_rootTracker.get();
+ m_runState = Executing;
+ }
+ void TrackerContext::completeCycle() {
+ m_runState = CompletedCycle;
+ }
+
+ bool TrackerContext::completedCycle() const {
+ return m_runState == CompletedCycle;
+ }
+ ITracker& TrackerContext::currentTracker() {
+ return *m_currentTracker;
+ }
+ void TrackerContext::setCurrentTracker( ITracker* tracker ) {
+ m_currentTracker = tracker;
+ }
+
+ TrackerBase::TrackerHasName::TrackerHasName( NameAndLocation const& nameAndLocation ) : m_nameAndLocation( nameAndLocation ) {}
+ bool TrackerBase::TrackerHasName::operator ()( ITrackerPtr const& tracker ) const {
+ return
+ tracker->nameAndLocation().name == m_nameAndLocation.name &&
+ tracker->nameAndLocation().location == m_nameAndLocation.location;
+ }
+
+ TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
+ : m_nameAndLocation( nameAndLocation ),
+ m_ctx( ctx ),
+ m_parent( parent )
+ {}
+
+ NameAndLocation const& TrackerBase::nameAndLocation() const {
+ return m_nameAndLocation;
+ }
+ bool TrackerBase::isComplete() const {
+ return m_runState == CompletedSuccessfully || m_runState == Failed;
+ }
+ bool TrackerBase::isSuccessfullyCompleted() const {
+ return m_runState == CompletedSuccessfully;
+ }
+ bool TrackerBase::isOpen() const {
+ return m_runState != NotStarted && !isComplete();
+ }
+ bool TrackerBase::hasChildren() const {
+ return !m_children.empty();
+ }
+
+ void TrackerBase::addChild( ITrackerPtr const& child ) {
+ m_children.push_back( child );
+ }
+
+ ITrackerPtr TrackerBase::findChild( NameAndLocation const& nameAndLocation ) {
+ auto it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( nameAndLocation ) );
+ return( it != m_children.end() )
+ ? *it
+ : nullptr;
+ }
+ ITracker& TrackerBase::parent() {
+ assert( m_parent ); // Should always be non-null except for root
+ return *m_parent;
+ }
+
+ void TrackerBase::openChild() {
+ if( m_runState != ExecutingChildren ) {
+ m_runState = ExecutingChildren;
+ if( m_parent )
+ m_parent->openChild();
+ }
+ }
+
+ bool TrackerBase::isSectionTracker() const { return false; }
+ bool TrackerBase::isIndexTracker() const { return false; }
+
+ void TrackerBase::open() {
+ m_runState = Executing;
+ moveToThis();
+ if( m_parent )
+ m_parent->openChild();
+ }
+
+ void TrackerBase::close() {
+
+ // Close any still open children (e.g. generators)
+ while( &m_ctx.currentTracker() != this )
+ m_ctx.currentTracker().close();
+
+ switch( m_runState ) {
+ case NeedsAnotherRun:
+ break;
+
+ case Executing:
+ m_runState = CompletedSuccessfully;
+ break;
+ case ExecutingChildren:
+ if( m_children.empty() || m_children.back()->isComplete() )
+ m_runState = CompletedSuccessfully;
+ break;
+
+ case NotStarted:
+ case CompletedSuccessfully:
+ case Failed:
+ CATCH_INTERNAL_ERROR( "Illogical state: " << m_runState );
+
+ default:
+ CATCH_INTERNAL_ERROR( "Unknown state: " << m_runState );
+ }
+ moveToParent();
+ m_ctx.completeCycle();
+ }
+ void TrackerBase::fail() {
+ m_runState = Failed;
+ if( m_parent )
+ m_parent->markAsNeedingAnotherRun();
+ moveToParent();
+ m_ctx.completeCycle();
+ }
+ void TrackerBase::markAsNeedingAnotherRun() {
+ m_runState = NeedsAnotherRun;
+ }
+
+ void TrackerBase::moveToParent() {
+ assert( m_parent );
+ m_ctx.setCurrentTracker( m_parent );
+ }
+ void TrackerBase::moveToThis() {
+ m_ctx.setCurrentTracker( this );
+ }
+
+ SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
+ : TrackerBase( nameAndLocation, ctx, parent )
+ {
+ if( parent ) {
+ while( !parent->isSectionTracker() )
+ parent = &parent->parent();
+
+ SectionTracker& parentSection = static_cast<SectionTracker&>( *parent );
+ addNextFilters( parentSection.m_filters );
+ }
+ }
+
+ bool SectionTracker::isSectionTracker() const { return true; }
+
+ SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) {
+ std::shared_ptr<SectionTracker> section;
+
+ ITracker& currentTracker = ctx.currentTracker();
+ if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
+ assert( childTracker );
+ assert( childTracker->isSectionTracker() );
+ section = std::static_pointer_cast<SectionTracker>( childTracker );
+ }
+ else {
+ section = std::make_shared<SectionTracker>( nameAndLocation, ctx, &currentTracker );
+ currentTracker.addChild( section );
+ }
+ if( !ctx.completedCycle() )
+ section->tryOpen();
+ return *section;
+ }
+
+ void SectionTracker::tryOpen() {
+ if( !isComplete() && (m_filters.empty() || m_filters[0].empty() || m_filters[0] == m_nameAndLocation.name ) )
+ open();
+ }
+
+ void SectionTracker::addInitialFilters( std::vector<std::string> const& filters ) {
+ if( !filters.empty() ) {
+ m_filters.push_back(""); // Root - should never be consulted
+ m_filters.push_back(""); // Test Case - not a section filter
+ m_filters.insert( m_filters.end(), filters.begin(), filters.end() );
+ }
+ }
+ void SectionTracker::addNextFilters( std::vector<std::string> const& filters ) {
+ if( filters.size() > 1 )
+ m_filters.insert( m_filters.end(), ++filters.begin(), filters.end() );
+ }
+
+ IndexTracker::IndexTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size )
+ : TrackerBase( nameAndLocation, ctx, parent ),
+ m_size( size )
+ {}
+
+ bool IndexTracker::isIndexTracker() const { return true; }
+
+ IndexTracker& IndexTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size ) {
+ std::shared_ptr<IndexTracker> tracker;
+
+ ITracker& currentTracker = ctx.currentTracker();
+ if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
+ assert( childTracker );
+ assert( childTracker->isIndexTracker() );
+ tracker = std::static_pointer_cast<IndexTracker>( childTracker );
+ }
+ else {
+ tracker = std::make_shared<IndexTracker>( nameAndLocation, ctx, &currentTracker, size );
+ currentTracker.addChild( tracker );
+ }
+
+ if( !ctx.completedCycle() && !tracker->isComplete() ) {
+ if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )
+ tracker->moveNext();
+ tracker->open();
+ }
+
+ return *tracker;
+ }
+
+ int IndexTracker::index() const { return m_index; }
+
+ void IndexTracker::moveNext() {
+ m_index++;
+ m_children.clear();
+ }
+
+ void IndexTracker::close() {
+ TrackerBase::close();
+ if( m_runState == CompletedSuccessfully && m_index < m_size-1 )
+ m_runState = Executing;
+ }
+
+} // namespace TestCaseTracking
+
+using TestCaseTracking::ITracker;
+using TestCaseTracking::TrackerContext;
+using TestCaseTracking::SectionTracker;
+using TestCaseTracking::IndexTracker;
+
+} // namespace Catch
+
+#if defined(__clang__)
+# pragma clang diagnostic pop
+#endif
+// end catch_test_case_tracker.cpp
+// start catch_test_registry.cpp
+
+namespace Catch {
+
+ auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker* {
+ return new(std::nothrow) TestInvokerAsFunction( testAsFunction );
+ }
+
+ NameAndTags::NameAndTags( StringRef const& name_ , StringRef const& tags_ ) noexcept : name( name_ ), tags( tags_ ) {}
+
+ AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept {
+ try {
+ getMutableRegistryHub()
+ .registerTest(
+ makeTestCase(
+ invoker,
+ extractClassName( classOrMethod ),
+ nameAndTags,
+ lineInfo));
+ } catch (...) {
+ // Do not throw when constructing global objects, instead register the exception to be processed later
+ getMutableRegistryHub().registerStartupException();
+ }
+ }
+
+ AutoReg::~AutoReg() = default;
+}
+// end catch_test_registry.cpp
+// start catch_test_spec.cpp
+
+#include <algorithm>
+#include <string>
+#include <vector>
+#include <memory>
+
+namespace Catch {
+
+ TestSpec::Pattern::~Pattern() = default;
+ TestSpec::NamePattern::~NamePattern() = default;
+ TestSpec::TagPattern::~TagPattern() = default;
+ TestSpec::ExcludedPattern::~ExcludedPattern() = default;
+
+ TestSpec::NamePattern::NamePattern( std::string const& name )
+ : m_wildcardPattern( toLower( name ), CaseSensitive::No )
+ {}
+ bool TestSpec::NamePattern::matches( TestCaseInfo const& testCase ) const {
+ return m_wildcardPattern.matches( toLower( testCase.name ) );
+ }
+
+ TestSpec::TagPattern::TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
+ bool TestSpec::TagPattern::matches( TestCaseInfo const& testCase ) const {
+ return std::find(begin(testCase.lcaseTags),
+ end(testCase.lcaseTags),
+ m_tag) != end(testCase.lcaseTags);
+ }
+
+ TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
+ bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
+
+ bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const {
+ // All patterns in a filter must match for the filter to be a match
+ for( auto const& pattern : m_patterns ) {
+ if( !pattern->matches( testCase ) )
+ return false;
+ }
+ return true;
+ }
+
+ bool TestSpec::hasFilters() const {
+ return !m_filters.empty();
+ }
+ bool TestSpec::matches( TestCaseInfo const& testCase ) const {
+ // A TestSpec matches if any filter matches
+ for( auto const& filter : m_filters )
+ if( filter.matches( testCase ) )
+ return true;
+ return false;
+ }
+}
+// end catch_test_spec.cpp
+// start catch_test_spec_parser.cpp
+
+namespace Catch {
+
+ TestSpecParser::TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
+
+ TestSpecParser& TestSpecParser::parse( std::string const& arg ) {
+ m_mode = None;
+ m_exclusion = false;
+ m_start = std::string::npos;
+ m_arg = m_tagAliases->expandAliases( arg );
+ m_escapeChars.clear();
+ for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
+ visitChar( m_arg[m_pos] );
+ if( m_mode == Name )
+ addPattern<TestSpec::NamePattern>();
+ return *this;
+ }
+ TestSpec TestSpecParser::testSpec() {
+ addFilter();
+ return m_testSpec;
+ }
+
+ void TestSpecParser::visitChar( char c ) {
+ if( m_mode == None ) {
+ switch( c ) {
+ case ' ': return;
+ case '~': m_exclusion = true; return;
+ case '[': return startNewMode( Tag, ++m_pos );
+ case '"': return startNewMode( QuotedName, ++m_pos );
+ case '\\': return escape();
+ default: startNewMode( Name, m_pos ); break;
+ }
+ }
+ if( m_mode == Name ) {
+ if( c == ',' ) {
+ addPattern<TestSpec::NamePattern>();
+ addFilter();
+ }
+ else if( c == '[' ) {
+ if( subString() == "exclude:" )
+ m_exclusion = true;
+ else
+ addPattern<TestSpec::NamePattern>();
+ startNewMode( Tag, ++m_pos );
+ }
+ else if( c == '\\' )
+ escape();
+ }
+ else if( m_mode == EscapedName )
+ m_mode = Name;
+ else if( m_mode == QuotedName && c == '"' )
+ addPattern<TestSpec::NamePattern>();
+ else if( m_mode == Tag && c == ']' )
+ addPattern<TestSpec::TagPattern>();
+ }
+ void TestSpecParser::startNewMode( Mode mode, std::size_t start ) {
+ m_mode = mode;
+ m_start = start;
+ }
+ void TestSpecParser::escape() {
+ if( m_mode == None )
+ m_start = m_pos;
+ m_mode = EscapedName;
+ m_escapeChars.push_back( m_pos );
+ }
+ std::string TestSpecParser::subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
+
+ void TestSpecParser::addFilter() {
+ if( !m_currentFilter.m_patterns.empty() ) {
+ m_testSpec.m_filters.push_back( m_currentFilter );
+ m_currentFilter = TestSpec::Filter();
+ }
+ }
+
+ TestSpec parseTestSpec( std::string const& arg ) {
+ return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
+ }
+
+} // namespace Catch
+// end catch_test_spec_parser.cpp
+// start catch_timer.cpp
+
+#include <chrono>
+
+static const uint64_t nanosecondsInSecond = 1000000000;
+
+namespace Catch {
+
+ auto getCurrentNanosecondsSinceEpoch() -> uint64_t {
+ return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
+ }
+
+ auto estimateClockResolution() -> uint64_t {
+ uint64_t sum = 0;
+ static const uint64_t iterations = 1000000;
+
+ auto startTime = getCurrentNanosecondsSinceEpoch();
+
+ for( std::size_t i = 0; i < iterations; ++i ) {
+
+ uint64_t ticks;
+ uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
+ do {
+ ticks = getCurrentNanosecondsSinceEpoch();
+ } while( ticks == baseTicks );
+
+ auto delta = ticks - baseTicks;
+ sum += delta;
+
+ // If we have been calibrating for over 3 seconds -- the clock
+ // is terrible and we should move on.
+ // TBD: How to signal that the measured resolution is probably wrong?
+ if (ticks > startTime + 3 * nanosecondsInSecond) {
+ return sum / i;
+ }
+ }
+
+ // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
+ // - and potentially do more iterations if there's a high variance.
+ return sum/iterations;
+ }
+ auto getEstimatedClockResolution() -> uint64_t {
+ static auto s_resolution = estimateClockResolution();
+ return s_resolution;
+ }
+
+ void Timer::start() {
+ m_nanoseconds = getCurrentNanosecondsSinceEpoch();
+ }
+ auto Timer::getElapsedNanoseconds() const -> uint64_t {
+ return getCurrentNanosecondsSinceEpoch() - m_nanoseconds;
+ }
+ auto Timer::getElapsedMicroseconds() const -> uint64_t {
+ return getElapsedNanoseconds()/1000;
+ }
+ auto Timer::getElapsedMilliseconds() const -> unsigned int {
+ return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
+ }
+ auto Timer::getElapsedSeconds() const -> double {
+ return getElapsedMicroseconds()/1000000.0;
+ }
+
+} // namespace Catch
+// end catch_timer.cpp
+// start catch_tostring.cpp
+
+#if defined(__clang__)
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wexit-time-destructors"
+# pragma clang diagnostic ignored "-Wglobal-constructors"
+#endif
+
+// Enable specific decls locally
+#if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
+#define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
+#endif
+
+#include <cmath>
+#include <iomanip>
+
+namespace Catch {
+
+namespace Detail {
+
+ const std::string unprintableString = "{?}";
+
+ namespace {
+ const int hexThreshold = 255;
+
+ struct Endianness {
+ enum Arch { Big, Little };
+
+ static Arch which() {
+ union _{
+ int asInt;
+ char asChar[sizeof (int)];
+ } u;
+
+ u.asInt = 1;
+ return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
+ }
+ };
+ }
+
+ std::string rawMemoryToString( const void *object, std::size_t size ) {
+ // Reverse order for little endian architectures
+ int i = 0, end = static_cast<int>( size ), inc = 1;
+ if( Endianness::which() == Endianness::Little ) {
+ i = end-1;
+ end = inc = -1;
+ }
+
+ unsigned char const *bytes = static_cast<unsigned char const *>(object);
+ ReusableStringStream rss;
+ rss << "0x" << std::setfill('0') << std::hex;
+ for( ; i != end; i += inc )
+ rss << std::setw(2) << static_cast<unsigned>(bytes[i]);
+ return rss.str();
+ }
+}
+
+template<typename T>
+std::string fpToString( T value, int precision ) {
+ if (std::isnan(value)) {
+ return "nan";
+ }
+
+ ReusableStringStream rss;
+ rss << std::setprecision( precision )
+ << std::fixed
+ << value;
+ std::string d = rss.str();
+ std::size_t i = d.find_last_not_of( '0' );
+ if( i != std::string::npos && i != d.size()-1 ) {
+ if( d[i] == '.' )
+ i++;
+ d = d.substr( 0, i+1 );
+ }
+ return d;
+}
+
+//// ======================================================= ////
+//
+// Out-of-line defs for full specialization of StringMaker
+//
+//// ======================================================= ////
+
+std::string StringMaker<std::string>::convert(const std::string& str) {
+ if (!getCurrentContext().getConfig()->showInvisibles()) {
+ return '"' + str + '"';
+ }
+
+ std::string s("\"");
+ for (char c : str) {
+ switch (c) {
+ case '\n':
+ s.append("\\n");
+ break;
+ case '\t':
+ s.append("\\t");
+ break;
+ default:
+ s.push_back(c);
+ break;
+ }
+ }
+ s.append("\"");
+ return s;
+}
+
+#ifdef CATCH_CONFIG_WCHAR
+std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {
+ std::string s;
+ s.reserve(wstr.size());
+ for (auto c : wstr) {
+ s += (c <= 0xff) ? static_cast<char>(c) : '?';
+ }
+ return ::Catch::Detail::stringify(s);
+}
+#endif
+
+std::string StringMaker<char const*>::convert(char const* str) {
+ if (str) {
+ return ::Catch::Detail::stringify(std::string{ str });
+ } else {
+ return{ "{null string}" };
+ }
+}
+std::string StringMaker<char*>::convert(char* str) {
+ if (str) {
+ return ::Catch::Detail::stringify(std::string{ str });
+ } else {
+ return{ "{null string}" };
+ }
+}
+#ifdef CATCH_CONFIG_WCHAR
+std::string StringMaker<wchar_t const*>::convert(wchar_t const * str) {
+ if (str) {
+ return ::Catch::Detail::stringify(std::wstring{ str });
+ } else {
+ return{ "{null string}" };
+ }
+}
+std::string StringMaker<wchar_t *>::convert(wchar_t * str) {
+ if (str) {
+ return ::Catch::Detail::stringify(std::wstring{ str });
+ } else {
+ return{ "{null string}" };
+ }
+}
+#endif
+
+std::string StringMaker<int>::convert(int value) {
+ return ::Catch::Detail::stringify(static_cast<long long>(value));
+}
+std::string StringMaker<long>::convert(long value) {
+ return ::Catch::Detail::stringify(static_cast<long long>(value));
+}
+std::string StringMaker<long long>::convert(long long value) {
+ ReusableStringStream rss;
+ rss << value;
+ if (value > Detail::hexThreshold) {
+ rss << " (0x" << std::hex << value << ')';
+ }
+ return rss.str();
+}
+
+std::string StringMaker<unsigned int>::convert(unsigned int value) {
+ return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
+}
+std::string StringMaker<unsigned long>::convert(unsigned long value) {
+ return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
+}
+std::string StringMaker<unsigned long long>::convert(unsigned long long value) {
+ ReusableStringStream rss;
+ rss << value;
+ if (value > Detail::hexThreshold) {
+ rss << " (0x" << std::hex << value << ')';
+ }
+ return rss.str();
+}
+
+std::string StringMaker<bool>::convert(bool b) {
+ return b ? "true" : "false";
+}
+
+std::string StringMaker<char>::convert(char value) {
+ if (value == '\r') {
+ return "'\\r'";
+ } else if (value == '\f') {
+ return "'\\f'";
+ } else if (value == '\n') {
+ return "'\\n'";
+ } else if (value == '\t') {
+ return "'\\t'";
+ } else if ('\0' <= value && value < ' ') {
+ return ::Catch::Detail::stringify(static_cast<unsigned int>(value));
+ } else {
+ char chstr[] = "' '";
+ chstr[1] = value;
+ return chstr;
+ }
+}
+std::string StringMaker<signed char>::convert(signed char c) {
+ return ::Catch::Detail::stringify(static_cast<char>(c));
+}
+std::string StringMaker<unsigned char>::convert(unsigned char c) {
+ return ::Catch::Detail::stringify(static_cast<char>(c));
+}
+
+std::string StringMaker<std::nullptr_t>::convert(std::nullptr_t) {
+ return "nullptr";
+}
+
+std::string StringMaker<float>::convert(float value) {
+ return fpToString(value, 5) + 'f';
+}
+std::string StringMaker<double>::convert(double value) {
+ return fpToString(value, 10);
+}
+
+std::string ratio_string<std::atto>::symbol() { return "a"; }
+std::string ratio_string<std::femto>::symbol() { return "f"; }
+std::string ratio_string<std::pico>::symbol() { return "p"; }
+std::string ratio_string<std::nano>::symbol() { return "n"; }
+std::string ratio_string<std::micro>::symbol() { return "u"; }
+std::string ratio_string<std::milli>::symbol() { return "m"; }
+
+} // end namespace Catch
+
+#if defined(__clang__)
+# pragma clang diagnostic pop
+#endif
+
+// end catch_tostring.cpp
+// start catch_totals.cpp
+
+namespace Catch {
+
+ Counts Counts::operator - ( Counts const& other ) const {
+ Counts diff;
+ diff.passed = passed - other.passed;
+ diff.failed = failed - other.failed;
+ diff.failedButOk = failedButOk - other.failedButOk;
+ return diff;
+ }
+
+ Counts& Counts::operator += ( Counts const& other ) {
+ passed += other.passed;
+ failed += other.failed;
+ failedButOk += other.failedButOk;
+ return *this;
+ }
+
+ std::size_t Counts::total() const {
+ return passed + failed + failedButOk;
+ }
+ bool Counts::allPassed() const {
+ return failed == 0 && failedButOk == 0;
+ }
+ bool Counts::allOk() const {
+ return failed == 0;
+ }
+
+ Totals Totals::operator - ( Totals const& other ) const {
+ Totals diff;
+ diff.assertions = assertions - other.assertions;
+ diff.testCases = testCases - other.testCases;
+ return diff;
+ }
+
+ Totals& Totals::operator += ( Totals const& other ) {
+ assertions += other.assertions;
+ testCases += other.testCases;
+ return *this;
+ }
+
+ Totals Totals::delta( Totals const& prevTotals ) const {
+ Totals diff = *this - prevTotals;
+ if( diff.assertions.failed > 0 )
+ ++diff.testCases.failed;
+ else if( diff.assertions.failedButOk > 0 )
+ ++diff.testCases.failedButOk;
+ else
+ ++diff.testCases.passed;
+ return diff;
+ }
+
+}
+// end catch_totals.cpp
+// start catch_uncaught_exceptions.cpp
+
+#include <exception>
+
+namespace Catch {
+ bool uncaught_exceptions() {
+#if defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
+ return std::uncaught_exceptions() > 0;
+#else
+ return std::uncaught_exception();
+#endif
+ }
+} // end namespace Catch
+// end catch_uncaught_exceptions.cpp
+// start catch_version.cpp
+
+#include <ostream>
+
+namespace Catch {
+
+ Version::Version
+ ( unsigned int _majorVersion,
+ unsigned int _minorVersion,
+ unsigned int _patchNumber,
+ char const * const _branchName,
+ unsigned int _buildNumber )
+ : majorVersion( _majorVersion ),
+ minorVersion( _minorVersion ),
+ patchNumber( _patchNumber ),
+ branchName( _branchName ),
+ buildNumber( _buildNumber )
+ {}
+
+ std::ostream& operator << ( std::ostream& os, Version const& version ) {
+ os << version.majorVersion << '.'
+ << version.minorVersion << '.'
+ << version.patchNumber;
+ // branchName is never null -> 0th char is \0 if it is empty
+ if (version.branchName[0]) {
+ os << '-' << version.branchName
+ << '.' << version.buildNumber;
+ }
+ return os;
+ }
+
+ Version const& libraryVersion() {
+ static Version version( 2, 2, 2, "", 0 );
+ return version;
+ }
+
+}
+// end catch_version.cpp
+// start catch_wildcard_pattern.cpp
+
+#include <sstream>
+
+namespace Catch {
+
+ WildcardPattern::WildcardPattern( std::string const& pattern,
+ CaseSensitive::Choice caseSensitivity )
+ : m_caseSensitivity( caseSensitivity ),
+ m_pattern( adjustCase( pattern ) )
+ {
+ if( startsWith( m_pattern, '*' ) ) {
+ m_pattern = m_pattern.substr( 1 );
+ m_wildcard = WildcardAtStart;
+ }
+ if( endsWith( m_pattern, '*' ) ) {
+ m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
+ m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
+ }
+ }
+
+ bool WildcardPattern::matches( std::string const& str ) const {
+ switch( m_wildcard ) {
+ case NoWildcard:
+ return m_pattern == adjustCase( str );
+ case WildcardAtStart:
+ return endsWith( adjustCase( str ), m_pattern );
+ case WildcardAtEnd:
+ return startsWith( adjustCase( str ), m_pattern );
+ case WildcardAtBothEnds:
+ return contains( adjustCase( str ), m_pattern );
+ default:
+ CATCH_INTERNAL_ERROR( "Unknown enum" );
+ }
+ }
+
+ std::string WildcardPattern::adjustCase( std::string const& str ) const {
+ return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str;
+ }
+}
+// end catch_wildcard_pattern.cpp
+// start catch_xmlwriter.cpp
+
+#include <iomanip>
+
+using uchar = unsigned char;
+
+namespace Catch {
+
+namespace {
+
+ size_t trailingBytes(unsigned char c) {
+ if ((c & 0xE0) == 0xC0) {
+ return 2;
+ }
+ if ((c & 0xF0) == 0xE0) {
+ return 3;
+ }
+ if ((c & 0xF8) == 0xF0) {
+ return 4;
+ }
+ CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
+ }
+
+ uint32_t headerValue(unsigned char c) {
+ if ((c & 0xE0) == 0xC0) {
+ return c & 0x1F;
+ }
+ if ((c & 0xF0) == 0xE0) {
+ return c & 0x0F;
+ }
+ if ((c & 0xF8) == 0xF0) {
+ return c & 0x07;
+ }
+ CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
+ }
+
+ void hexEscapeChar(std::ostream& os, unsigned char c) {
+ os << "\\x"
+ << std::uppercase << std::hex << std::setfill('0') << std::setw(2)
+ << static_cast<int>(c);
+ }
+
+} // anonymous namespace
+
+ XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat )
+ : m_str( str ),
+ m_forWhat( forWhat )
+ {}
+
+ void XmlEncode::encodeTo( std::ostream& os ) const {
+ // Apostrophe escaping not necessary if we always use " to write attributes
+ // (see: http://www.w3.org/TR/xml/#syntax)
+
+ for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {
+ uchar c = m_str[idx];
+ switch (c) {
+ case '<': os << "&lt;"; break;
+ case '&': os << "&amp;"; break;
+
+ case '>':
+ // See: http://www.w3.org/TR/xml/#syntax
+ if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')
+ os << "&gt;";
+ else
+ os << c;
+ break;
+
+ case '\"':
+ if (m_forWhat == ForAttributes)
+ os << "&quot;";
+ else
+ os << c;
+ break;
+
+ default:
+ // Check for control characters and invalid utf-8
+
+ // Escape control characters in standard ascii
+ // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
+ if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {
+ hexEscapeChar(os, c);
+ break;
+ }
+
+ // Plain ASCII: Write it to stream
+ if (c < 0x7F) {
+ os << c;
+ break;
+ }
+
+ // UTF-8 territory
+ // Check if the encoding is valid and if it is not, hex escape bytes.
+ // Important: We do not check the exact decoded values for validity, only the encoding format
+ // First check that this bytes is a valid lead byte:
+ // This means that it is not encoded as 1111 1XXX
+ // Or as 10XX XXXX
+ if (c < 0xC0 ||
+ c >= 0xF8) {
+ hexEscapeChar(os, c);
+ break;
+ }
+
+ auto encBytes = trailingBytes(c);
+ // Are there enough bytes left to avoid accessing out-of-bounds memory?
+ if (idx + encBytes - 1 >= m_str.size()) {
+ hexEscapeChar(os, c);
+ break;
+ }
+ // The header is valid, check data
+ // The next encBytes bytes must together be a valid utf-8
+ // This means: bitpattern 10XX XXXX and the extracted value is sane (ish)
+ bool valid = true;
+ uint32_t value = headerValue(c);
+ for (std::size_t n = 1; n < encBytes; ++n) {
+ uchar nc = m_str[idx + n];
+ valid &= ((nc & 0xC0) == 0x80);
+ value = (value << 6) | (nc & 0x3F);
+ }
+
+ if (
+ // Wrong bit pattern of following bytes
+ (!valid) ||
+ // Overlong encodings
+ (value < 0x80) ||
+ (0x80 <= value && value < 0x800 && encBytes > 2) ||
+ (0x800 < value && value < 0x10000 && encBytes > 3) ||
+ // Encoded value out of range
+ (value >= 0x110000)
+ ) {
+ hexEscapeChar(os, c);
+ break;
+ }
+
+ // If we got here, this is in fact a valid(ish) utf-8 sequence
+ for (std::size_t n = 0; n < encBytes; ++n) {
+ os << m_str[idx + n];
+ }
+ idx += encBytes - 1;
+ break;
+ }
+ }
+ }
+
+ std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
+ xmlEncode.encodeTo( os );
+ return os;
+ }
+
+ XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer )
+ : m_writer( writer )
+ {}
+
+ XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept
+ : m_writer( other.m_writer ){
+ other.m_writer = nullptr;
+ }
+ XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept {
+ if ( m_writer ) {
+ m_writer->endElement();
+ }
+ m_writer = other.m_writer;
+ other.m_writer = nullptr;
+ return *this;
+ }
+
+ XmlWriter::ScopedElement::~ScopedElement() {
+ if( m_writer )
+ m_writer->endElement();
+ }
+
+ XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, bool indent ) {
+ m_writer->writeText( text, indent );
+ return *this;
+ }
+
+ XmlWriter::XmlWriter( std::ostream& os ) : m_os( os )
+ {
+ writeDeclaration();
+ }
+
+ XmlWriter::~XmlWriter() {
+ while( !m_tags.empty() )
+ endElement();
+ }
+
+ XmlWriter& XmlWriter::startElement( std::string const& name ) {
+ ensureTagClosed();
+ newlineIfNecessary();
+ m_os << m_indent << '<' << name;
+ m_tags.push_back( name );
+ m_indent += " ";
+ m_tagIsOpen = true;
+ return *this;
+ }
+
+ XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name ) {
+ ScopedElement scoped( this );
+ startElement( name );
+ return scoped;
+ }
+
+ XmlWriter& XmlWriter::endElement() {
+ newlineIfNecessary();
+ m_indent = m_indent.substr( 0, m_indent.size()-2 );
+ if( m_tagIsOpen ) {
+ m_os << "/>";
+ m_tagIsOpen = false;
+ }
+ else {
+ m_os << m_indent << "</" << m_tags.back() << ">";
+ }
+ m_os << std::endl;
+ m_tags.pop_back();
+ return *this;
+ }
+
+ XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) {
+ if( !name.empty() && !attribute.empty() )
+ m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
+ return *this;
+ }
+
+ XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) {
+ m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"';
+ return *this;
+ }
+
+ XmlWriter& XmlWriter::writeText( std::string const& text, bool indent ) {
+ if( !text.empty() ){
+ bool tagWasOpen = m_tagIsOpen;
+ ensureTagClosed();
+ if( tagWasOpen && indent )
+ m_os << m_indent;
+ m_os << XmlEncode( text );
+ m_needsNewline = true;
+ }
+ return *this;
+ }
+
+ XmlWriter& XmlWriter::writeComment( std::string const& text ) {
+ ensureTagClosed();
+ m_os << m_indent << "<!--" << text << "-->";
+ m_needsNewline = true;
+ return *this;
+ }
+
+ void XmlWriter::writeStylesheetRef( std::string const& url ) {
+ m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n";
+ }
+
+ XmlWriter& XmlWriter::writeBlankLine() {
+ ensureTagClosed();
+ m_os << '\n';
+ return *this;
+ }
+
+ void XmlWriter::ensureTagClosed() {
+ if( m_tagIsOpen ) {
+ m_os << ">" << std::endl;
+ m_tagIsOpen = false;
+ }
+ }
+
+ void XmlWriter::writeDeclaration() {
+ m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+ }
+
+ void XmlWriter::newlineIfNecessary() {
+ if( m_needsNewline ) {
+ m_os << std::endl;
+ m_needsNewline = false;
+ }
+ }
+}
+// end catch_xmlwriter.cpp
+// start catch_reporter_bases.cpp
+
+#include <cstring>
+#include <cfloat>
+#include <cstdio>
+#include <assert.h>
+#include <memory>
+
+namespace Catch {
+ void prepareExpandedExpression(AssertionResult& result) {
+ result.getExpandedExpression();
+ }
+
+ // Because formatting using c++ streams is stateful, drop down to C is required
+ // Alternatively we could use stringstream, but its performance is... not good.
+ std::string getFormattedDuration( double duration ) {
+ // Max exponent + 1 is required to represent the whole part
+ // + 1 for decimal point
+ // + 3 for the 3 decimal places
+ // + 1 for null terminator
+ const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
+ char buffer[maxDoubleSize];
+
+ // Save previous errno, to prevent sprintf from overwriting it
+ ErrnoGuard guard;
+#ifdef _MSC_VER
+ sprintf_s(buffer, "%.3f", duration);
+#else
+ sprintf(buffer, "%.3f", duration);
+#endif
+ return std::string(buffer);
+ }
+
+ TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config)
+ :StreamingReporterBase(_config) {}
+
+ void TestEventListenerBase::assertionStarting(AssertionInfo const &) {}
+
+ bool TestEventListenerBase::assertionEnded(AssertionStats const &) {
+ return false;
+ }
+
+} // end namespace Catch
+// end catch_reporter_bases.cpp
+// start catch_reporter_compact.cpp
+
+namespace {
+
+#ifdef CATCH_PLATFORM_MAC
+ const char* failedString() { return "FAILED"; }
+ const char* passedString() { return "PASSED"; }
+#else
+ const char* failedString() { return "failed"; }
+ const char* passedString() { return "passed"; }
+#endif
+
+ // Colour::LightGrey
+ Catch::Colour::Code dimColour() { return Catch::Colour::FileName; }
+
+ std::string bothOrAll( std::size_t count ) {
+ return count == 1 ? std::string() :
+ count == 2 ? "both " : "all " ;
+ }
+
+} // anon namespace
+
+namespace Catch {
+namespace {
+// Colour, message variants:
+// - white: No tests ran.
+// - red: Failed [both/all] N test cases, failed [both/all] M assertions.
+// - white: Passed [both/all] N test cases (no assertions).
+// - red: Failed N tests cases, failed M assertions.
+// - green: Passed [both/all] N tests cases with M assertions.
+void printTotals(std::ostream& out, const Totals& totals) {
+ if (totals.testCases.total() == 0) {
+ out << "No tests ran.";
+ } else if (totals.testCases.failed == totals.testCases.total()) {
+ Colour colour(Colour::ResultError);
+ const std::string qualify_assertions_failed =
+ totals.assertions.failed == totals.assertions.total() ?
+ bothOrAll(totals.assertions.failed) : std::string();
+ out <<
+ "Failed " << bothOrAll(totals.testCases.failed)
+ << pluralise(totals.testCases.failed, "test case") << ", "
+ "failed " << qualify_assertions_failed <<
+ pluralise(totals.assertions.failed, "assertion") << '.';
+ } else if (totals.assertions.total() == 0) {
+ out <<
+ "Passed " << bothOrAll(totals.testCases.total())
+ << pluralise(totals.testCases.total(), "test case")
+ << " (no assertions).";
+ } else if (totals.assertions.failed) {
+ Colour colour(Colour::ResultError);
+ out <<
+ "Failed " << pluralise(totals.testCases.failed, "test case") << ", "
+ "failed " << pluralise(totals.assertions.failed, "assertion") << '.';
+ } else {
+ Colour colour(Colour::ResultSuccess);
+ out <<
+ "Passed " << bothOrAll(totals.testCases.passed)
+ << pluralise(totals.testCases.passed, "test case") <<
+ " with " << pluralise(totals.assertions.passed, "assertion") << '.';
+ }
+}
+
+// Implementation of CompactReporter formatting
+class AssertionPrinter {
+public:
+ AssertionPrinter& operator= (AssertionPrinter const&) = delete;
+ AssertionPrinter(AssertionPrinter const&) = delete;
+ AssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
+ : stream(_stream)
+ , result(_stats.assertionResult)
+ , messages(_stats.infoMessages)
+ , itMessage(_stats.infoMessages.begin())
+ , printInfoMessages(_printInfoMessages) {}
+
+ void print() {
+ printSourceInfo();
+
+ itMessage = messages.begin();
+
+ switch (result.getResultType()) {
+ case ResultWas::Ok:
+ printResultType(Colour::ResultSuccess, passedString());
+ printOriginalExpression();
+ printReconstructedExpression();
+ if (!result.hasExpression())
+ printRemainingMessages(Colour::None);
+ else
+ printRemainingMessages();
+ break;
+ case ResultWas::ExpressionFailed:
+ if (result.isOk())
+ printResultType(Colour::ResultSuccess, failedString() + std::string(" - but was ok"));
+ else
+ printResultType(Colour::Error, failedString());
+ printOriginalExpression();
+ printReconstructedExpression();
+ printRemainingMessages();
+ break;
+ case ResultWas::ThrewException:
+ printResultType(Colour::Error, failedString());
+ printIssue("unexpected exception with message:");
+ printMessage();
+ printExpressionWas();
+ printRemainingMessages();
+ break;
+ case ResultWas::FatalErrorCondition:
+ printResultType(Colour::Error, failedString());
+ printIssue("fatal error condition with message:");
+ printMessage();
+ printExpressionWas();
+ printRemainingMessages();
+ break;
+ case ResultWas::DidntThrowException:
+ printResultType(Colour::Error, failedString());
+ printIssue("expected exception, got none");
+ printExpressionWas();
+ printRemainingMessages();
+ break;
+ case ResultWas::Info:
+ printResultType(Colour::None, "info");
+ printMessage();
+ printRemainingMessages();
+ break;
+ case ResultWas::Warning:
+ printResultType(Colour::None, "warning");
+ printMessage();
+ printRemainingMessages();
+ break;
+ case ResultWas::ExplicitFailure:
+ printResultType(Colour::Error, failedString());
+ printIssue("explicitly");
+ printRemainingMessages(Colour::None);
+ break;
+ // These cases are here to prevent compiler warnings
+ case ResultWas::Unknown:
+ case ResultWas::FailureBit:
+ case ResultWas::Exception:
+ printResultType(Colour::Error, "** internal error **");
+ break;
+ }
+ }
+
+private:
+ void printSourceInfo() const {
+ Colour colourGuard(Colour::FileName);
+ stream << result.getSourceInfo() << ':';
+ }
+
+ void printResultType(Colour::Code colour, std::string const& passOrFail) const {
+ if (!passOrFail.empty()) {
+ {
+ Colour colourGuard(colour);
+ stream << ' ' << passOrFail;
+ }
+ stream << ':';
+ }
+ }
+
+ void printIssue(std::string const& issue) const {
+ stream << ' ' << issue;
+ }
+
+ void printExpressionWas() {
+ if (result.hasExpression()) {
+ stream << ';';
+ {
+ Colour colour(dimColour());
+ stream << " expression was:";
+ }
+ printOriginalExpression();
+ }
+ }
+
+ void printOriginalExpression() const {
+ if (result.hasExpression()) {
+ stream << ' ' << result.getExpression();
+ }
+ }
+
+ void printReconstructedExpression() const {
+ if (result.hasExpandedExpression()) {
+ {
+ Colour colour(dimColour());
+ stream << " for: ";
+ }
+ stream << result.getExpandedExpression();
+ }
+ }
+
+ void printMessage() {
+ if (itMessage != messages.end()) {
+ stream << " '" << itMessage->message << '\'';
+ ++itMessage;
+ }
+ }
+
+ void printRemainingMessages(Colour::Code colour = dimColour()) {
+ if (itMessage == messages.end())
+ return;
+
+ // using messages.end() directly yields (or auto) compilation error:
+ std::vector<MessageInfo>::const_iterator itEnd = messages.end();
+ const std::size_t N = static_cast<std::size_t>(std::distance(itMessage, itEnd));
+
+ {
+ Colour colourGuard(colour);
+ stream << " with " << pluralise(N, "message") << ':';
+ }
+
+ for (; itMessage != itEnd; ) {
+ // If this assertion is a warning ignore any INFO messages
+ if (printInfoMessages || itMessage->type != ResultWas::Info) {
+ stream << " '" << itMessage->message << '\'';
+ if (++itMessage != itEnd) {
+ Colour colourGuard(dimColour());
+ stream << " and";
+ }
+ }
+ }
+ }
+
+private:
+ std::ostream& stream;
+ AssertionResult const& result;
+ std::vector<MessageInfo> messages;
+ std::vector<MessageInfo>::const_iterator itMessage;
+ bool printInfoMessages;
+};
+
+} // anon namespace
+
+ std::string CompactReporter::getDescription() {
+ return "Reports test results on a single line, suitable for IDEs";
+ }
+
+ ReporterPreferences CompactReporter::getPreferences() const {
+ ReporterPreferences prefs;
+ prefs.shouldRedirectStdOut = false;
+ return prefs;
+ }
+
+ void CompactReporter::noMatchingTestCases( std::string const& spec ) {
+ stream << "No test cases matched '" << spec << '\'' << std::endl;
+ }
+
+ void CompactReporter::assertionStarting( AssertionInfo const& ) {}
+
+ bool CompactReporter::assertionEnded( AssertionStats const& _assertionStats ) {
+ AssertionResult const& result = _assertionStats.assertionResult;
+
+ bool printInfoMessages = true;
+
+ // Drop out if result was successful and we're not printing those
+ if( !m_config->includeSuccessfulResults() && result.isOk() ) {
+ if( result.getResultType() != ResultWas::Warning )
+ return false;
+ printInfoMessages = false;
+ }
+
+ AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
+ printer.print();
+
+ stream << std::endl;
+ return true;
+ }
+
+ void CompactReporter::sectionEnded(SectionStats const& _sectionStats) {
+ if (m_config->showDurations() == ShowDurations::Always) {
+ stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
+ }
+ }
+
+ void CompactReporter::testRunEnded( TestRunStats const& _testRunStats ) {
+ printTotals( stream, _testRunStats.totals );
+ stream << '\n' << std::endl;
+ StreamingReporterBase::testRunEnded( _testRunStats );
+ }
+
+ CompactReporter::~CompactReporter() {}
+
+ CATCH_REGISTER_REPORTER( "compact", CompactReporter )
+
+} // end namespace Catch
+// end catch_reporter_compact.cpp
+// start catch_reporter_console.cpp
+
+#include <cfloat>
+#include <cstdio>
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
+ // Note that 4062 (not all labels are handled
+ // and default is missing) is enabled
+#endif
+
+namespace Catch {
+
+namespace {
+
+// Formatter impl for ConsoleReporter
+class ConsoleAssertionPrinter {
+public:
+ ConsoleAssertionPrinter& operator= (ConsoleAssertionPrinter const&) = delete;
+ ConsoleAssertionPrinter(ConsoleAssertionPrinter const&) = delete;
+ ConsoleAssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
+ : stream(_stream),
+ stats(_stats),
+ result(_stats.assertionResult),
+ colour(Colour::None),
+ message(result.getMessage()),
+ messages(_stats.infoMessages),
+ printInfoMessages(_printInfoMessages) {
+ switch (result.getResultType()) {
+ case ResultWas::Ok:
+ colour = Colour::Success;
+ passOrFail = "PASSED";
+ //if( result.hasMessage() )
+ if (_stats.infoMessages.size() == 1)
+ messageLabel = "with message";
+ if (_stats.infoMessages.size() > 1)
+ messageLabel = "with messages";
+ break;
+ case ResultWas::ExpressionFailed:
+ if (result.isOk()) {
+ colour = Colour::Success;
+ passOrFail = "FAILED - but was ok";
+ } else {
+ colour = Colour::Error;
+ passOrFail = "FAILED";
+ }
+ if (_stats.infoMessages.size() == 1)
+ messageLabel = "with message";
+ if (_stats.infoMessages.size() > 1)
+ messageLabel = "with messages";
+ break;
+ case ResultWas::ThrewException:
+ colour = Colour::Error;
+ passOrFail = "FAILED";
+ messageLabel = "due to unexpected exception with ";
+ if (_stats.infoMessages.size() == 1)
+ messageLabel += "message";
+ if (_stats.infoMessages.size() > 1)
+ messageLabel += "messages";
+ break;
+ case ResultWas::FatalErrorCondition:
+ colour = Colour::Error;
+ passOrFail = "FAILED";
+ messageLabel = "due to a fatal error condition";
+ break;
+ case ResultWas::DidntThrowException:
+ colour = Colour::Error;
+ passOrFail = "FAILED";
+ messageLabel = "because no exception was thrown where one was expected";
+ break;
+ case ResultWas::Info:
+ messageLabel = "info";
+ break;
+ case ResultWas::Warning:
+ messageLabel = "warning";
+ break;
+ case ResultWas::ExplicitFailure:
+ passOrFail = "FAILED";
+ colour = Colour::Error;
+ if (_stats.infoMessages.size() == 1)
+ messageLabel = "explicitly with message";
+ if (_stats.infoMessages.size() > 1)
+ messageLabel = "explicitly with messages";
+ break;
+ // These cases are here to prevent compiler warnings
+ case ResultWas::Unknown:
+ case ResultWas::FailureBit:
+ case ResultWas::Exception:
+ passOrFail = "** internal error **";
+ colour = Colour::Error;
+ break;
+ }
+ }
+
+ void print() const {
+ printSourceInfo();
+ if (stats.totals.assertions.total() > 0) {
+ if (result.isOk())
+ stream << '\n';
+ printResultType();
+ printOriginalExpression();
+ printReconstructedExpression();
+ } else {
+ stream << '\n';
+ }
+ printMessage();
+ }
+
+private:
+ void printResultType() const {
+ if (!passOrFail.empty()) {
+ Colour colourGuard(colour);
+ stream << passOrFail << ":\n";
+ }
+ }
+ void printOriginalExpression() const {
+ if (result.hasExpression()) {
+ Colour colourGuard(Colour::OriginalExpression);
+ stream << " ";
+ stream << result.getExpressionInMacro();
+ stream << '\n';
+ }
+ }
+ void printReconstructedExpression() const {
+ if (result.hasExpandedExpression()) {
+ stream << "with expansion:\n";
+ Colour colourGuard(Colour::ReconstructedExpression);
+ stream << Column(result.getExpandedExpression()).indent(2) << '\n';
+ }
+ }
+ void printMessage() const {
+ if (!messageLabel.empty())
+ stream << messageLabel << ':' << '\n';
+ for (auto const& msg : messages) {
+ // If this assertion is a warning ignore any INFO messages
+ if (printInfoMessages || msg.type != ResultWas::Info)
+ stream << Column(msg.message).indent(2) << '\n';
+ }
+ }
+ void printSourceInfo() const {
+ Colour colourGuard(Colour::FileName);
+ stream << result.getSourceInfo() << ": ";
+ }
+
+ std::ostream& stream;
+ AssertionStats const& stats;
+ AssertionResult const& result;
+ Colour::Code colour;
+ std::string passOrFail;
+ std::string messageLabel;
+ std::string message;
+ std::vector<MessageInfo> messages;
+ bool printInfoMessages;
+};
+
+std::size_t makeRatio(std::size_t number, std::size_t total) {
+ std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0;
+ return (ratio == 0 && number > 0) ? 1 : ratio;
+}
+
+std::size_t& findMax(std::size_t& i, std::size_t& j, std::size_t& k) {
+ if (i > j && i > k)
+ return i;
+ else if (j > k)
+ return j;
+ else
+ return k;
+}
+
+struct ColumnInfo {
+ enum Justification { Left, Right };
+ std::string name;
+ int width;
+ Justification justification;
+};
+struct ColumnBreak {};
+struct RowBreak {};
+
+class Duration {
+ enum class Unit {
+ Auto,
+ Nanoseconds,
+ Microseconds,
+ Milliseconds,
+ Seconds,
+ Minutes
+ };
+ static const uint64_t s_nanosecondsInAMicrosecond = 1000;
+ static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond;
+ static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond;
+ static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond;
+
+ uint64_t m_inNanoseconds;
+ Unit m_units;
+
+public:
+ explicit Duration(uint64_t inNanoseconds, Unit units = Unit::Auto)
+ : m_inNanoseconds(inNanoseconds),
+ m_units(units) {
+ if (m_units == Unit::Auto) {
+ if (m_inNanoseconds < s_nanosecondsInAMicrosecond)
+ m_units = Unit::Nanoseconds;
+ else if (m_inNanoseconds < s_nanosecondsInAMillisecond)
+ m_units = Unit::Microseconds;
+ else if (m_inNanoseconds < s_nanosecondsInASecond)
+ m_units = Unit::Milliseconds;
+ else if (m_inNanoseconds < s_nanosecondsInAMinute)
+ m_units = Unit::Seconds;
+ else
+ m_units = Unit::Minutes;
+ }
+
+ }
+
+ auto value() const -> double {
+ switch (m_units) {
+ case Unit::Microseconds:
+ return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMicrosecond);
+ case Unit::Milliseconds:
+ return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMillisecond);
+ case Unit::Seconds:
+ return m_inNanoseconds / static_cast<double>(s_nanosecondsInASecond);
+ case Unit::Minutes:
+ return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMinute);
+ default:
+ return static_cast<double>(m_inNanoseconds);
+ }
+ }
+ auto unitsAsString() const -> std::string {
+ switch (m_units) {
+ case Unit::Nanoseconds:
+ return "ns";
+ case Unit::Microseconds:
+ return "µs";
+ case Unit::Milliseconds:
+ return "ms";
+ case Unit::Seconds:
+ return "s";
+ case Unit::Minutes:
+ return "m";
+ default:
+ return "** internal error **";
+ }
+
+ }
+ friend auto operator << (std::ostream& os, Duration const& duration) -> std::ostream& {
+ return os << duration.value() << " " << duration.unitsAsString();
+ }
+};
+} // end anon namespace
+
+class TablePrinter {
+ std::ostream& m_os;
+ std::vector<ColumnInfo> m_columnInfos;
+ std::ostringstream m_oss;
+ int m_currentColumn = -1;
+ bool m_isOpen = false;
+
+public:
+ TablePrinter( std::ostream& os, std::vector<ColumnInfo> columnInfos )
+ : m_os( os ),
+ m_columnInfos( std::move( columnInfos ) ) {}
+
+ auto columnInfos() const -> std::vector<ColumnInfo> const& {
+ return m_columnInfos;
+ }
+
+ void open() {
+ if (!m_isOpen) {
+ m_isOpen = true;
+ *this << RowBreak();
+ for (auto const& info : m_columnInfos)
+ *this << info.name << ColumnBreak();
+ *this << RowBreak();
+ m_os << Catch::getLineOfChars<'-'>() << "\n";
+ }
+ }
+ void close() {
+ if (m_isOpen) {
+ *this << RowBreak();
+ m_os << std::endl;
+ m_isOpen = false;
+ }
+ }
+
+ template<typename T>
+ friend TablePrinter& operator << (TablePrinter& tp, T const& value) {
+ tp.m_oss << value;
+ return tp;
+ }
+
+ friend TablePrinter& operator << (TablePrinter& tp, ColumnBreak) {
+ auto colStr = tp.m_oss.str();
+ // This takes account of utf8 encodings
+ auto strSize = Catch::StringRef(colStr).numberOfCharacters();
+ tp.m_oss.str("");
+ tp.open();
+ if (tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size() - 1)) {
+ tp.m_currentColumn = -1;
+ tp.m_os << "\n";
+ }
+ tp.m_currentColumn++;
+
+ auto colInfo = tp.m_columnInfos[tp.m_currentColumn];
+ auto padding = (strSize + 2 < static_cast<std::size_t>(colInfo.width))
+ ? std::string(colInfo.width - (strSize + 2), ' ')
+ : std::string();
+ if (colInfo.justification == ColumnInfo::Left)
+ tp.m_os << colStr << padding << " ";
+ else
+ tp.m_os << padding << colStr << " ";
+ return tp;
+ }
+
+ friend TablePrinter& operator << (TablePrinter& tp, RowBreak) {
+ if (tp.m_currentColumn > 0) {
+ tp.m_os << "\n";
+ tp.m_currentColumn = -1;
+ }
+ return tp;
+ }
+};
+
+ConsoleReporter::ConsoleReporter(ReporterConfig const& config)
+ : StreamingReporterBase(config),
+ m_tablePrinter(new TablePrinter(config.stream(),
+ {
+ { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 32, ColumnInfo::Left },
+ { "iters", 8, ColumnInfo::Right },
+ { "elapsed ns", 14, ColumnInfo::Right },
+ { "average", 14, ColumnInfo::Right }
+ })) {}
+ConsoleReporter::~ConsoleReporter() = default;
+
+std::string ConsoleReporter::getDescription() {
+ return "Reports test results as plain lines of text";
+}
+
+void ConsoleReporter::noMatchingTestCases(std::string const& spec) {
+ stream << "No test cases matched '" << spec << '\'' << std::endl;
+}
+
+void ConsoleReporter::assertionStarting(AssertionInfo const&) {}
+
+bool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) {
+ AssertionResult const& result = _assertionStats.assertionResult;
+
+ bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
+
+ // Drop out if result was successful but we're not printing them.
+ if (!includeResults && result.getResultType() != ResultWas::Warning)
+ return false;
+
+ lazyPrint();
+
+ ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults);
+ printer.print();
+ stream << std::endl;
+ return true;
+}
+
+void ConsoleReporter::sectionStarting(SectionInfo const& _sectionInfo) {
+ m_headerPrinted = false;
+ StreamingReporterBase::sectionStarting(_sectionInfo);
+}
+void ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) {
+ m_tablePrinter->close();
+ if (_sectionStats.missingAssertions) {
+ lazyPrint();
+ Colour colour(Colour::ResultError);
+ if (m_sectionStack.size() > 1)
+ stream << "\nNo assertions in section";
+ else
+ stream << "\nNo assertions in test case";
+ stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
+ }
+ if (m_config->showDurations() == ShowDurations::Always) {
+ stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
+ }
+ if (m_headerPrinted) {
+ m_headerPrinted = false;
+ }
+ StreamingReporterBase::sectionEnded(_sectionStats);
+}
+
+void ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) {
+ lazyPrintWithoutClosingBenchmarkTable();
+
+ auto nameCol = Column( info.name ).width( static_cast<std::size_t>( m_tablePrinter->columnInfos()[0].width - 2 ) );
+
+ bool firstLine = true;
+ for (auto line : nameCol) {
+ if (!firstLine)
+ (*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak();
+ else
+ firstLine = false;
+
+ (*m_tablePrinter) << line << ColumnBreak();
+ }
+}
+void ConsoleReporter::benchmarkEnded(BenchmarkStats const& stats) {
+ Duration average(stats.elapsedTimeInNanoseconds / stats.iterations);
+ (*m_tablePrinter)
+ << stats.iterations << ColumnBreak()
+ << stats.elapsedTimeInNanoseconds << ColumnBreak()
+ << average << ColumnBreak();
+}
+
+void ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats) {
+ m_tablePrinter->close();
+ StreamingReporterBase::testCaseEnded(_testCaseStats);
+ m_headerPrinted = false;
+}
+void ConsoleReporter::testGroupEnded(TestGroupStats const& _testGroupStats) {
+ if (currentGroupInfo.used) {
+ printSummaryDivider();
+ stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
+ printTotals(_testGroupStats.totals);
+ stream << '\n' << std::endl;
+ }
+ StreamingReporterBase::testGroupEnded(_testGroupStats);
+}
+void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {
+ printTotalsDivider(_testRunStats.totals);
+ printTotals(_testRunStats.totals);
+ stream << std::endl;
+ StreamingReporterBase::testRunEnded(_testRunStats);
+}
+
+void ConsoleReporter::lazyPrint() {
+
+ m_tablePrinter->close();
+ lazyPrintWithoutClosingBenchmarkTable();
+}
+
+void ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() {
+
+ if (!currentTestRunInfo.used)
+ lazyPrintRunInfo();
+ if (!currentGroupInfo.used)
+ lazyPrintGroupInfo();
+
+ if (!m_headerPrinted) {
+ printTestCaseAndSectionHeader();
+ m_headerPrinted = true;
+ }
+}
+void ConsoleReporter::lazyPrintRunInfo() {
+ stream << '\n' << getLineOfChars<'~'>() << '\n';
+ Colour colour(Colour::SecondaryText);
+ stream << currentTestRunInfo->name
+ << " is a Catch v" << libraryVersion() << " host application.\n"
+ << "Run with -? for options\n\n";
+
+ if (m_config->rngSeed() != 0)
+ stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
+
+ currentTestRunInfo.used = true;
+}
+void ConsoleReporter::lazyPrintGroupInfo() {
+ if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) {
+ printClosedHeader("Group: " + currentGroupInfo->name);
+ currentGroupInfo.used = true;
+ }
+}
+void ConsoleReporter::printTestCaseAndSectionHeader() {
+ assert(!m_sectionStack.empty());
+ printOpenHeader(currentTestCaseInfo->name);
+
+ if (m_sectionStack.size() > 1) {
+ Colour colourGuard(Colour::Headers);
+
+ auto
+ it = m_sectionStack.begin() + 1, // Skip first section (test case)
+ itEnd = m_sectionStack.end();
+ for (; it != itEnd; ++it)
+ printHeaderString(it->name, 2);
+ }
+
+ SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
+
+ if (!lineInfo.empty()) {
+ stream << getLineOfChars<'-'>() << '\n';
+ Colour colourGuard(Colour::FileName);
+ stream << lineInfo << '\n';
+ }
+ stream << getLineOfChars<'.'>() << '\n' << std::endl;
+}
+
+void ConsoleReporter::printClosedHeader(std::string const& _name) {
+ printOpenHeader(_name);
+ stream << getLineOfChars<'.'>() << '\n';
+}
+void ConsoleReporter::printOpenHeader(std::string const& _name) {
+ stream << getLineOfChars<'-'>() << '\n';
+ {
+ Colour colourGuard(Colour::Headers);
+ printHeaderString(_name);
+ }
+}
+
+// if string has a : in first line will set indent to follow it on
+// subsequent lines
+void ConsoleReporter::printHeaderString(std::string const& _string, std::size_t indent) {
+ std::size_t i = _string.find(": ");
+ if (i != std::string::npos)
+ i += 2;
+ else
+ i = 0;
+ stream << Column(_string).indent(indent + i).initialIndent(indent) << '\n';
+}
+
+struct SummaryColumn {
+
+ SummaryColumn( std::string _label, Colour::Code _colour )
+ : label( std::move( _label ) ),
+ colour( _colour ) {}
+ SummaryColumn addRow( std::size_t count ) {
+ ReusableStringStream rss;
+ rss << count;
+ std::string row = rss.str();
+ for (auto& oldRow : rows) {
+ while (oldRow.size() < row.size())
+ oldRow = ' ' + oldRow;
+ while (oldRow.size() > row.size())
+ row = ' ' + row;
+ }
+ rows.push_back(row);
+ return *this;
+ }
+
+ std::string label;
+ Colour::Code colour;
+ std::vector<std::string> rows;
+
+};
+
+void ConsoleReporter::printTotals( Totals const& totals ) {
+ if (totals.testCases.total() == 0) {
+ stream << Colour(Colour::Warning) << "No tests ran\n";
+ } else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) {
+ stream << Colour(Colour::ResultSuccess) << "All tests passed";
+ stream << " ("
+ << pluralise(totals.assertions.passed, "assertion") << " in "
+ << pluralise(totals.testCases.passed, "test case") << ')'
+ << '\n';
+ } else {
+
+ std::vector<SummaryColumn> columns;
+ columns.push_back(SummaryColumn("", Colour::None)
+ .addRow(totals.testCases.total())
+ .addRow(totals.assertions.total()));
+ columns.push_back(SummaryColumn("passed", Colour::Success)
+ .addRow(totals.testCases.passed)
+ .addRow(totals.assertions.passed));
+ columns.push_back(SummaryColumn("failed", Colour::ResultError)
+ .addRow(totals.testCases.failed)
+ .addRow(totals.assertions.failed));
+ columns.push_back(SummaryColumn("failed as expected", Colour::ResultExpectedFailure)
+ .addRow(totals.testCases.failedButOk)
+ .addRow(totals.assertions.failedButOk));
+
+ printSummaryRow("test cases", columns, 0);
+ printSummaryRow("assertions", columns, 1);
+ }
+}
+void ConsoleReporter::printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row) {
+ for (auto col : cols) {
+ std::string value = col.rows[row];
+ if (col.label.empty()) {
+ stream << label << ": ";
+ if (value != "0")
+ stream << value;
+ else
+ stream << Colour(Colour::Warning) << "- none -";
+ } else if (value != "0") {
+ stream << Colour(Colour::LightGrey) << " | ";
+ stream << Colour(col.colour)
+ << value << ' ' << col.label;
+ }
+ }
+ stream << '\n';
+}
+
+void ConsoleReporter::printTotalsDivider(Totals const& totals) {
+ if (totals.testCases.total() > 0) {
+ std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total());
+ std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total());
+ std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total());
+ while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1)
+ findMax(failedRatio, failedButOkRatio, passedRatio)++;
+ while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1)
+ findMax(failedRatio, failedButOkRatio, passedRatio)--;
+
+ stream << Colour(Colour::Error) << std::string(failedRatio, '=');
+ stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '=');
+ if (totals.testCases.allPassed())
+ stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '=');
+ else
+ stream << Colour(Colour::Success) << std::string(passedRatio, '=');
+ } else {
+ stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '=');
+ }
+ stream << '\n';
+}
+void ConsoleReporter::printSummaryDivider() {
+ stream << getLineOfChars<'-'>() << '\n';
+}
+
+CATCH_REGISTER_REPORTER("console", ConsoleReporter)
+
+} // end namespace Catch
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+// end catch_reporter_console.cpp
+// start catch_reporter_junit.cpp
+
+#include <assert.h>
+#include <sstream>
+#include <ctime>
+#include <algorithm>
+
+namespace Catch {
+
+ namespace {
+ std::string getCurrentTimestamp() {
+ // Beware, this is not reentrant because of backward compatibility issues
+ // Also, UTC only, again because of backward compatibility (%z is C++11)
+ time_t rawtime;
+ std::time(&rawtime);
+ auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
+
+#ifdef _MSC_VER
+ std::tm timeInfo = {};
+ gmtime_s(&timeInfo, &rawtime);
+#else
+ std::tm* timeInfo;
+ timeInfo = std::gmtime(&rawtime);
+#endif
+
+ char timeStamp[timeStampSize];
+ const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
+
+#ifdef _MSC_VER
+ std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
+#else
+ std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
+#endif
+ return std::string(timeStamp);
+ }
+
+ std::string fileNameTag(const std::vector<std::string> &tags) {
+ auto it = std::find_if(begin(tags),
+ end(tags),
+ [] (std::string const& tag) {return tag.front() == '#'; });
+ if (it != tags.end())
+ return it->substr(1);
+ return std::string();
+ }
+ } // anonymous namespace
+
+ JunitReporter::JunitReporter( ReporterConfig const& _config )
+ : CumulativeReporterBase( _config ),
+ xml( _config.stream() )
+ {
+ m_reporterPrefs.shouldRedirectStdOut = true;
+ }
+
+ JunitReporter::~JunitReporter() {}
+
+ std::string JunitReporter::getDescription() {
+ return "Reports test results in an XML format that looks like Ant's junitreport target";
+ }
+
+ void JunitReporter::noMatchingTestCases( std::string const& /*spec*/ ) {}
+
+ void JunitReporter::testRunStarting( TestRunInfo const& runInfo ) {
+ CumulativeReporterBase::testRunStarting( runInfo );
+ xml.startElement( "testsuites" );
+ }
+
+ void JunitReporter::testGroupStarting( GroupInfo const& groupInfo ) {
+ suiteTimer.start();
+ stdOutForSuite.clear();
+ stdErrForSuite.clear();
+ unexpectedExceptions = 0;
+ CumulativeReporterBase::testGroupStarting( groupInfo );
+ }
+
+ void JunitReporter::testCaseStarting( TestCaseInfo const& testCaseInfo ) {
+ m_okToFail = testCaseInfo.okToFail();
+ }
+
+ bool JunitReporter::assertionEnded( AssertionStats const& assertionStats ) {
+ if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail )
+ unexpectedExceptions++;
+ return CumulativeReporterBase::assertionEnded( assertionStats );
+ }
+
+ void JunitReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
+ stdOutForSuite += testCaseStats.stdOut;
+ stdErrForSuite += testCaseStats.stdErr;
+ CumulativeReporterBase::testCaseEnded( testCaseStats );
+ }
+
+ void JunitReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
+ double suiteTime = suiteTimer.getElapsedSeconds();
+ CumulativeReporterBase::testGroupEnded( testGroupStats );
+ writeGroup( *m_testGroups.back(), suiteTime );
+ }
+
+ void JunitReporter::testRunEndedCumulative() {
+ xml.endElement();
+ }
+
+ void JunitReporter::writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
+ XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
+ TestGroupStats const& stats = groupNode.value;
+ xml.writeAttribute( "name", stats.groupInfo.name );
+ xml.writeAttribute( "errors", unexpectedExceptions );
+ xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
+ xml.writeAttribute( "tests", stats.totals.assertions.total() );
+ xml.writeAttribute( "hostname", "tbd" ); // !TBD
+ if( m_config->showDurations() == ShowDurations::Never )
+ xml.writeAttribute( "time", "" );
+ else
+ xml.writeAttribute( "time", suiteTime );
+ xml.writeAttribute( "timestamp", getCurrentTimestamp() );
+
+ // Write test cases
+ for( auto const& child : groupNode.children )
+ writeTestCase( *child );
+
+ xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite ), false );
+ xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite ), false );
+ }
+
+ void JunitReporter::writeTestCase( TestCaseNode const& testCaseNode ) {
+ TestCaseStats const& stats = testCaseNode.value;
+
+ // All test cases have exactly one section - which represents the
+ // test case itself. That section may have 0-n nested sections
+ assert( testCaseNode.children.size() == 1 );
+ SectionNode const& rootSection = *testCaseNode.children.front();
+
+ std::string className = stats.testInfo.className;
+
+ if( className.empty() ) {
+ className = fileNameTag(stats.testInfo.tags);
+ if ( className.empty() )
+ className = "global";
+ }
+
+ if ( !m_config->name().empty() )
+ className = m_config->name() + "." + className;
+
+ writeSection( className, "", rootSection );
+ }
+
+ void JunitReporter::writeSection( std::string const& className,
+ std::string const& rootName,
+ SectionNode const& sectionNode ) {
+ std::string name = trim( sectionNode.stats.sectionInfo.name );
+ if( !rootName.empty() )
+ name = rootName + '/' + name;
+
+ if( !sectionNode.assertions.empty() ||
+ !sectionNode.stdOut.empty() ||
+ !sectionNode.stdErr.empty() ) {
+ XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
+ if( className.empty() ) {
+ xml.writeAttribute( "classname", name );
+ xml.writeAttribute( "name", "root" );
+ }
+ else {
+ xml.writeAttribute( "classname", className );
+ xml.writeAttribute( "name", name );
+ }
+ xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) );
+
+ writeAssertions( sectionNode );
+
+ if( !sectionNode.stdOut.empty() )
+ xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
+ if( !sectionNode.stdErr.empty() )
+ xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
+ }
+ for( auto const& childNode : sectionNode.childSections )
+ if( className.empty() )
+ writeSection( name, "", *childNode );
+ else
+ writeSection( className, name, *childNode );
+ }
+
+ void JunitReporter::writeAssertions( SectionNode const& sectionNode ) {
+ for( auto const& assertion : sectionNode.assertions )
+ writeAssertion( assertion );
+ }
+
+ void JunitReporter::writeAssertion( AssertionStats const& stats ) {
+ AssertionResult const& result = stats.assertionResult;
+ if( !result.isOk() ) {
+ std::string elementName;
+ switch( result.getResultType() ) {
+ case ResultWas::ThrewException:
+ case ResultWas::FatalErrorCondition:
+ elementName = "error";
+ break;
+ case ResultWas::ExplicitFailure:
+ elementName = "failure";
+ break;
+ case ResultWas::ExpressionFailed:
+ elementName = "failure";
+ break;
+ case ResultWas::DidntThrowException:
+ elementName = "failure";
+ break;
+
+ // We should never see these here:
+ case ResultWas::Info:
+ case ResultWas::Warning:
+ case ResultWas::Ok:
+ case ResultWas::Unknown:
+ case ResultWas::FailureBit:
+ case ResultWas::Exception:
+ elementName = "internalError";
+ break;
+ }
+
+ XmlWriter::ScopedElement e = xml.scopedElement( elementName );
+
+ xml.writeAttribute( "message", result.getExpandedExpression() );
+ xml.writeAttribute( "type", result.getTestMacroName() );
+
+ ReusableStringStream rss;
+ if( !result.getMessage().empty() )
+ rss << result.getMessage() << '\n';
+ for( auto const& msg : stats.infoMessages )
+ if( msg.type == ResultWas::Info )
+ rss << msg.message << '\n';
+
+ rss << "at " << result.getSourceInfo();
+ xml.writeText( rss.str(), false );
+ }
+ }
+
+ CATCH_REGISTER_REPORTER( "junit", JunitReporter )
+
+} // end namespace Catch
+// end catch_reporter_junit.cpp
+// start catch_reporter_multi.cpp
+
+namespace Catch {
+
+ void MultipleReporters::add( IStreamingReporterPtr&& reporter ) {
+ m_reporters.push_back( std::move( reporter ) );
+ }
+
+ ReporterPreferences MultipleReporters::getPreferences() const {
+ return m_reporters[0]->getPreferences();
+ }
+
+ std::set<Verbosity> MultipleReporters::getSupportedVerbosities() {
+ return std::set<Verbosity>{ };
+ }
+
+ void MultipleReporters::noMatchingTestCases( std::string const& spec ) {
+ for( auto const& reporter : m_reporters )
+ reporter->noMatchingTestCases( spec );
+ }
+
+ void MultipleReporters::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) {
+ for( auto const& reporter : m_reporters )
+ reporter->benchmarkStarting( benchmarkInfo );
+ }
+ void MultipleReporters::benchmarkEnded( BenchmarkStats const& benchmarkStats ) {
+ for( auto const& reporter : m_reporters )
+ reporter->benchmarkEnded( benchmarkStats );
+ }
+
+ void MultipleReporters::testRunStarting( TestRunInfo const& testRunInfo ) {
+ for( auto const& reporter : m_reporters )
+ reporter->testRunStarting( testRunInfo );
+ }
+
+ void MultipleReporters::testGroupStarting( GroupInfo const& groupInfo ) {
+ for( auto const& reporter : m_reporters )
+ reporter->testGroupStarting( groupInfo );
+ }
+
+ void MultipleReporters::testCaseStarting( TestCaseInfo const& testInfo ) {
+ for( auto const& reporter : m_reporters )
+ reporter->testCaseStarting( testInfo );
+ }
+
+ void MultipleReporters::sectionStarting( SectionInfo const& sectionInfo ) {
+ for( auto const& reporter : m_reporters )
+ reporter->sectionStarting( sectionInfo );
+ }
+
+ void MultipleReporters::assertionStarting( AssertionInfo const& assertionInfo ) {
+ for( auto const& reporter : m_reporters )
+ reporter->assertionStarting( assertionInfo );
+ }
+
+ // The return value indicates if the messages buffer should be cleared:
+ bool MultipleReporters::assertionEnded( AssertionStats const& assertionStats ) {
+ bool clearBuffer = false;
+ for( auto const& reporter : m_reporters )
+ clearBuffer |= reporter->assertionEnded( assertionStats );
+ return clearBuffer;
+ }
+
+ void MultipleReporters::sectionEnded( SectionStats const& sectionStats ) {
+ for( auto const& reporter : m_reporters )
+ reporter->sectionEnded( sectionStats );
+ }
+
+ void MultipleReporters::testCaseEnded( TestCaseStats const& testCaseStats ) {
+ for( auto const& reporter : m_reporters )
+ reporter->testCaseEnded( testCaseStats );
+ }
+
+ void MultipleReporters::testGroupEnded( TestGroupStats const& testGroupStats ) {
+ for( auto const& reporter : m_reporters )
+ reporter->testGroupEnded( testGroupStats );
+ }
+
+ void MultipleReporters::testRunEnded( TestRunStats const& testRunStats ) {
+ for( auto const& reporter : m_reporters )
+ reporter->testRunEnded( testRunStats );
+ }
+
+ void MultipleReporters::skipTest( TestCaseInfo const& testInfo ) {
+ for( auto const& reporter : m_reporters )
+ reporter->skipTest( testInfo );
+ }
+
+ bool MultipleReporters::isMulti() const {
+ return true;
+ }
+
+} // end namespace Catch
+// end catch_reporter_multi.cpp
+// start catch_reporter_xml.cpp
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
+ // Note that 4062 (not all labels are handled
+ // and default is missing) is enabled
+#endif
+
+namespace Catch {
+ XmlReporter::XmlReporter( ReporterConfig const& _config )
+ : StreamingReporterBase( _config ),
+ m_xml(_config.stream())
+ {
+ m_reporterPrefs.shouldRedirectStdOut = true;
+ }
+
+ XmlReporter::~XmlReporter() = default;
+
+ std::string XmlReporter::getDescription() {
+ return "Reports test results as an XML document";
+ }
+
+ std::string XmlReporter::getStylesheetRef() const {
+ return std::string();
+ }
+
+ void XmlReporter::writeSourceInfo( SourceLineInfo const& sourceInfo ) {
+ m_xml
+ .writeAttribute( "filename", sourceInfo.file )
+ .writeAttribute( "line", sourceInfo.line );
+ }
+
+ void XmlReporter::noMatchingTestCases( std::string const& s ) {
+ StreamingReporterBase::noMatchingTestCases( s );
+ }
+
+ void XmlReporter::testRunStarting( TestRunInfo const& testInfo ) {
+ StreamingReporterBase::testRunStarting( testInfo );
+ std::string stylesheetRef = getStylesheetRef();
+ if( !stylesheetRef.empty() )
+ m_xml.writeStylesheetRef( stylesheetRef );
+ m_xml.startElement( "Catch" );
+ if( !m_config->name().empty() )
+ m_xml.writeAttribute( "name", m_config->name() );
+ }
+
+ void XmlReporter::testGroupStarting( GroupInfo const& groupInfo ) {
+ StreamingReporterBase::testGroupStarting( groupInfo );
+ m_xml.startElement( "Group" )
+ .writeAttribute( "name", groupInfo.name );
+ }
+
+ void XmlReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
+ StreamingReporterBase::testCaseStarting(testInfo);
+ m_xml.startElement( "TestCase" )
+ .writeAttribute( "name", trim( testInfo.name ) )
+ .writeAttribute( "description", testInfo.description )
+ .writeAttribute( "tags", testInfo.tagsAsString() );
+
+ writeSourceInfo( testInfo.lineInfo );
+
+ if ( m_config->showDurations() == ShowDurations::Always )
+ m_testCaseTimer.start();
+ m_xml.ensureTagClosed();
+ }
+
+ void XmlReporter::sectionStarting( SectionInfo const& sectionInfo ) {
+ StreamingReporterBase::sectionStarting( sectionInfo );
+ if( m_sectionDepth++ > 0 ) {
+ m_xml.startElement( "Section" )
+ .writeAttribute( "name", trim( sectionInfo.name ) )
+ .writeAttribute( "description", sectionInfo.description );
+ writeSourceInfo( sectionInfo.lineInfo );
+ m_xml.ensureTagClosed();
+ }
+ }
+
+ void XmlReporter::assertionStarting( AssertionInfo const& ) { }
+
+ bool XmlReporter::assertionEnded( AssertionStats const& assertionStats ) {
+
+ AssertionResult const& result = assertionStats.assertionResult;
+
+ bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
+
+ if( includeResults || result.getResultType() == ResultWas::Warning ) {
+ // Print any info messages in <Info> tags.
+ for( auto const& msg : assertionStats.infoMessages ) {
+ if( msg.type == ResultWas::Info && includeResults ) {
+ m_xml.scopedElement( "Info" )
+ .writeText( msg.message );
+ } else if ( msg.type == ResultWas::Warning ) {
+ m_xml.scopedElement( "Warning" )
+ .writeText( msg.message );
+ }
+ }
+ }
+
+ // Drop out if result was successful but we're not printing them.
+ if( !includeResults && result.getResultType() != ResultWas::Warning )
+ return true;
+
+ // Print the expression if there is one.
+ if( result.hasExpression() ) {
+ m_xml.startElement( "Expression" )
+ .writeAttribute( "success", result.succeeded() )
+ .writeAttribute( "type", result.getTestMacroName() );
+
+ writeSourceInfo( result.getSourceInfo() );
+
+ m_xml.scopedElement( "Original" )
+ .writeText( result.getExpression() );
+ m_xml.scopedElement( "Expanded" )
+ .writeText( result.getExpandedExpression() );
+ }
+
+ // And... Print a result applicable to each result type.
+ switch( result.getResultType() ) {
+ case ResultWas::ThrewException:
+ m_xml.startElement( "Exception" );
+ writeSourceInfo( result.getSourceInfo() );
+ m_xml.writeText( result.getMessage() );
+ m_xml.endElement();
+ break;
+ case ResultWas::FatalErrorCondition:
+ m_xml.startElement( "FatalErrorCondition" );
+ writeSourceInfo( result.getSourceInfo() );
+ m_xml.writeText( result.getMessage() );
+ m_xml.endElement();
+ break;
+ case ResultWas::Info:
+ m_xml.scopedElement( "Info" )
+ .writeText( result.getMessage() );
+ break;
+ case ResultWas::Warning:
+ // Warning will already have been written
+ break;
+ case ResultWas::ExplicitFailure:
+ m_xml.startElement( "Failure" );
+ writeSourceInfo( result.getSourceInfo() );
+ m_xml.writeText( result.getMessage() );
+ m_xml.endElement();
+ break;
+ default:
+ break;
+ }
+
+ if( result.hasExpression() )
+ m_xml.endElement();
+
+ return true;
+ }
+
+ void XmlReporter::sectionEnded( SectionStats const& sectionStats ) {
+ StreamingReporterBase::sectionEnded( sectionStats );
+ if( --m_sectionDepth > 0 ) {
+ XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
+ e.writeAttribute( "successes", sectionStats.assertions.passed );
+ e.writeAttribute( "failures", sectionStats.assertions.failed );
+ e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
+
+ if ( m_config->showDurations() == ShowDurations::Always )
+ e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
+
+ m_xml.endElement();
+ }
+ }
+
+ void XmlReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
+ StreamingReporterBase::testCaseEnded( testCaseStats );
+ XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
+ e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
+
+ if ( m_config->showDurations() == ShowDurations::Always )
+ e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
+
+ if( !testCaseStats.stdOut.empty() )
+ m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), false );
+ if( !testCaseStats.stdErr.empty() )
+ m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), false );
+
+ m_xml.endElement();
+ }
+
+ void XmlReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
+ StreamingReporterBase::testGroupEnded( testGroupStats );
+ // TODO: Check testGroupStats.aborting and act accordingly.
+ m_xml.scopedElement( "OverallResults" )
+ .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
+ .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
+ .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
+ m_xml.endElement();
+ }
+
+ void XmlReporter::testRunEnded( TestRunStats const& testRunStats ) {
+ StreamingReporterBase::testRunEnded( testRunStats );
+ m_xml.scopedElement( "OverallResults" )
+ .writeAttribute( "successes", testRunStats.totals.assertions.passed )
+ .writeAttribute( "failures", testRunStats.totals.assertions.failed )
+ .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
+ m_xml.endElement();
+ }
+
+ CATCH_REGISTER_REPORTER( "xml", XmlReporter )
+
+} // end namespace Catch
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+// end catch_reporter_xml.cpp
+
+namespace Catch {
+ LeakDetector leakDetector;
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+// end catch_impl.hpp
+#endif
+
+#ifdef CATCH_CONFIG_MAIN
+// start catch_default_main.hpp
+
+#ifndef __OBJC__
+
+#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
+// Standard C/C++ Win32 Unicode wmain entry point
+extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
+#else
+// Standard C/C++ main entry point
+int main (int argc, char * argv[]) {
+#endif
+
+ return Catch::Session().run( argc, argv );
+}
+
+#else // __OBJC__
+
+// Objective-C entry point
+int main (int argc, char * const argv[]) {
+#if !CATCH_ARC_ENABLED
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+#endif
+
+ Catch::registerTestMethods();
+ int result = Catch::Session().run( argc, (char**)argv );
+
+#if !CATCH_ARC_ENABLED
+ [pool drain];
+#endif
+
+ return result;
+}
+
+#endif // __OBJC__
+
+// end catch_default_main.hpp
+#endif
+
+#if !defined(CATCH_CONFIG_IMPL_ONLY)
+
+#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
+# undef CLARA_CONFIG_MAIN
+#endif
+
+#if !defined(CATCH_CONFIG_DISABLE)
+//////
+// If this config identifier is defined then all CATCH macros are prefixed with CATCH_
+#ifdef CATCH_CONFIG_PREFIX_ALL
+
+#define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
+#define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
+
+#define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", __VA_ARGS__ )
+#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
+#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
+#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
+#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
+#endif// CATCH_CONFIG_DISABLE_MATCHERS
+#define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
+
+#define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+#define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
+#define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+#define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+#define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
+
+#define CATCH_CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", __VA_ARGS__ )
+#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
+#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
+#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
+#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
+#endif // CATCH_CONFIG_DISABLE_MATCHERS
+#define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+
+#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
+#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
+
+#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
+#endif // CATCH_CONFIG_DISABLE_MATCHERS
+
+#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
+#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
+#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << ::Catch::Detail::stringify(msg) )
+
+#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
+#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
+#define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
+#define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
+#define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
+#define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+#define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+
+#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
+
+// "BDD-style" convenience wrappers
+#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
+#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
+#define CATCH_GIVEN( desc ) CATCH_SECTION( std::string( "Given: ") + desc )
+#define CATCH_WHEN( desc ) CATCH_SECTION( std::string( " When: ") + desc )
+#define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( " And: ") + desc )
+#define CATCH_THEN( desc ) CATCH_SECTION( std::string( " Then: ") + desc )
+#define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( " And: ") + desc )
+
+// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
+#else
+
+#define REQUIRE( ... ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
+#define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
+
+#define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
+#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
+#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
+#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
+#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
+#endif // CATCH_CONFIG_DISABLE_MATCHERS
+#define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
+
+#define CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+#define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
+#define CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+#define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+#define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
+
+#define CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
+#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
+#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
+#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
+#endif // CATCH_CONFIG_DISABLE_MATCHERS
+#define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+
+#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
+#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
+
+#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
+#endif // CATCH_CONFIG_DISABLE_MATCHERS
+
+#define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
+#define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
+#define CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << ::Catch::Detail::stringify(msg) )
+
+#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
+#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
+#define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
+#define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
+#define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
+#define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+#define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
+
+#endif
+
+#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
+
+// "BDD-style" convenience wrappers
+#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
+#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
+
+#define GIVEN( desc ) SECTION( std::string(" Given: ") + desc )
+#define WHEN( desc ) SECTION( std::string(" When: ") + desc )
+#define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc )
+#define THEN( desc ) SECTION( std::string(" Then: ") + desc )
+#define AND_THEN( desc ) SECTION( std::string(" And: ") + desc )
+
+using Catch::Detail::Approx;
+
+#else
+//////
+// If this config identifier is defined then all CATCH macros are prefixed with CATCH_
+#ifdef CATCH_CONFIG_PREFIX_ALL
+
+#define CATCH_REQUIRE( ... ) (void)(0)
+#define CATCH_REQUIRE_FALSE( ... ) (void)(0)
+
+#define CATCH_REQUIRE_THROWS( ... ) (void)(0)
+#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
+#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
+#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
+#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
+#endif// CATCH_CONFIG_DISABLE_MATCHERS
+#define CATCH_REQUIRE_NOTHROW( ... ) (void)(0)
+
+#define CATCH_CHECK( ... ) (void)(0)
+#define CATCH_CHECK_FALSE( ... ) (void)(0)
+#define CATCH_CHECKED_IF( ... ) if (__VA_ARGS__)
+#define CATCH_CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
+#define CATCH_CHECK_NOFAIL( ... ) (void)(0)
+
+#define CATCH_CHECK_THROWS( ... ) (void)(0)
+#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
+#define CATCH_CHECK_THROWS_WITH( expr, matcher ) (void)(0)
+#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
+#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
+#endif // CATCH_CONFIG_DISABLE_MATCHERS
+#define CATCH_CHECK_NOTHROW( ... ) (void)(0)
+
+#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
+#define CATCH_CHECK_THAT( arg, matcher ) (void)(0)
+
+#define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)
+#endif // CATCH_CONFIG_DISABLE_MATCHERS
+
+#define CATCH_INFO( msg ) (void)(0)
+#define CATCH_WARN( msg ) (void)(0)
+#define CATCH_CAPTURE( msg ) (void)(0)
+
+#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
+#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
+#define CATCH_METHOD_AS_TEST_CASE( method, ... )
+#define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
+#define CATCH_SECTION( ... )
+#define CATCH_FAIL( ... ) (void)(0)
+#define CATCH_FAIL_CHECK( ... ) (void)(0)
+#define CATCH_SUCCEED( ... ) (void)(0)
+
+#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
+
+// "BDD-style" convenience wrappers
+#define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
+#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
+#define CATCH_GIVEN( desc )
+#define CATCH_WHEN( desc )
+#define CATCH_AND_WHEN( desc )
+#define CATCH_THEN( desc )
+#define CATCH_AND_THEN( desc )
+
+// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
+#else
+
+#define REQUIRE( ... ) (void)(0)
+#define REQUIRE_FALSE( ... ) (void)(0)
+
+#define REQUIRE_THROWS( ... ) (void)(0)
+#define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
+#define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
+#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
+#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
+#endif // CATCH_CONFIG_DISABLE_MATCHERS
+#define REQUIRE_NOTHROW( ... ) (void)(0)
+
+#define CHECK( ... ) (void)(0)
+#define CHECK_FALSE( ... ) (void)(0)
+#define CHECKED_IF( ... ) if (__VA_ARGS__)
+#define CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
+#define CHECK_NOFAIL( ... ) (void)(0)
+
+#define CHECK_THROWS( ... ) (void)(0)
+#define CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
+#define CHECK_THROWS_WITH( expr, matcher ) (void)(0)
+#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
+#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
+#endif // CATCH_CONFIG_DISABLE_MATCHERS
+#define CHECK_NOTHROW( ... ) (void)(0)
+
+#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
+#define CHECK_THAT( arg, matcher ) (void)(0)
+
+#define REQUIRE_THAT( arg, matcher ) (void)(0)
+#endif // CATCH_CONFIG_DISABLE_MATCHERS
+
+#define INFO( msg ) (void)(0)
+#define WARN( msg ) (void)(0)
+#define CAPTURE( msg ) (void)(0)
+
+#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
+#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
+#define METHOD_AS_TEST_CASE( method, ... )
+#define REGISTER_TEST_CASE( Function, ... ) (void)(0)
+#define SECTION( ... )
+#define FAIL( ... ) (void)(0)
+#define FAIL_CHECK( ... ) (void)(0)
+#define SUCCEED( ... ) (void)(0)
+#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
+
+#endif
+
+#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
+
+// "BDD-style" convenience wrappers
+#define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) )
+#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
+
+#define GIVEN( desc )
+#define WHEN( desc )
+#define AND_WHEN( desc )
+#define THEN( desc )
+#define AND_THEN( desc )
+
+using Catch::Detail::Approx;
+
+#endif
+
+#endif // ! CATCH_CONFIG_IMPL_ONLY
+
+// start catch_reenable_warnings.h
+
+
+#ifdef __clang__
+# ifdef __ICC // icpc defines the __clang__ macro
+# pragma warning(pop)
+# else
+# pragma clang diagnostic pop
+# endif
+#elif defined __GNUC__
+# pragma GCC diagnostic pop
+#endif
+
+// end catch_reenable_warnings.h
+// end catch.hpp
+#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
+
diff --git a/test/common/catch_main.cpp b/test/common/catch_main.cpp
new file mode 100644
index 0000000..3c3c6f2
--- /dev/null
+++ b/test/common/catch_main.cpp
@@ -0,0 +1,2 @@
+#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file
+#include <catch.hpp>
diff --git a/utils/adlmidi-2/9x15.hpp b/utils/adlmidi-2/9x15.hpp
index e535d49..76e0660 100644
--- a/utils/adlmidi-2/9x15.hpp
+++ b/utils/adlmidi-2/9x15.hpp
@@ -160,8 +160,8 @@ struct font9x15: public UIfontBase
virtual unsigned GetIndex(char32_t c) const { return ns_font9x15::unicode_to_bitmap_index[c]; }
};
-static UIfontBase* Getfont9x15()
-{
- static font9x15 f;
- return &f;
-}
+//static UIfontBase* Getfont9x15()
+//{
+// static font9x15 f;
+// return &f;
+//}
diff --git a/utils/adlmidi-2/midiplay.cc b/utils/adlmidi-2/midiplay.cc
index b670083..74806eb 100644
--- a/utils/adlmidi-2/midiplay.cc
+++ b/utils/adlmidi-2/midiplay.cc
@@ -1593,6 +1593,7 @@ int main(int argc, char **argv)
UI.Color(7);
std::fflush(stderr);
std::printf(
+ "\n\n"
"Usage: adlmidi <midifilename> [ <options> ] [ <banknumber> [ <numcards> [ <numfourops>] ] ]\n"
" adlmidi <midifilename> -1 To enter instrument tester\n"
" -p Enables adlib percussion instrument mode (use with CMF files)\n"
@@ -1758,7 +1759,7 @@ int main(int argc, char **argv)
if(argc >= 3)
{
- if(is_number(argv[2]))
+ if(is_number(argv[2]) || !strcmp(argv[2], "-1"))
{
int bankno = std::atoi(argv[2]);
if(bankno == -1)
diff --git a/utils/adlmidi-2/puzzlegame.cc b/utils/adlmidi-2/puzzlegame.cc
index e9d2b9b..f8fa57c 100644
--- a/utils/adlmidi-2/puzzlegame.cc
+++ b/utils/adlmidi-2/puzzlegame.cc
@@ -4,6 +4,8 @@
#include "input.hpp"
#include "puzzlegame.hpp"
+char ADLMIDI_PuzzleGame::peeked_input = 0;
+
unsigned long ADLMIDI_PuzzleGame::TimerRead()
{
static std::chrono::time_point<std::chrono::system_clock> begin = std::chrono::system_clock::now();
diff --git a/utils/adlmidi-2/puzzlegame.hpp b/utils/adlmidi-2/puzzlegame.hpp
index 03ad921..a35f1cb 100755
--- a/utils/adlmidi-2/puzzlegame.hpp
+++ b/utils/adlmidi-2/puzzlegame.hpp
@@ -36,7 +36,7 @@ namespace ADLMIDI_PuzzleGame
void Sound(unsigned/*freq*/, unsigned/*duration*/);
void PutCell(int x, int y, unsigned cell);
void ScreenPutString(const char* str, unsigned attr, unsigned column, unsigned row);
- static char peeked_input = 0;
+ extern char peeked_input;
bool kbhit();
char getch();
diff --git a/utils/dumpbank/dumpbank.cpp b/utils/dumpbank/dumpbank.cpp
index 84283e7..d2df74a 100644
--- a/utils/dumpbank/dumpbank.cpp
+++ b/utils/dumpbank/dumpbank.cpp
@@ -190,5 +190,12 @@ static void LoadBNK(const char* fn)
int main(int argc, const char* const* argv)
{
+ if(argc < 2)
+ {
+ std::printf("Usage: \n"
+ " %s filename.bnk\n"
+ "\n", argv[0]);
+ return 1;
+ }
LoadBNK(argv[1]);
}
diff --git a/utils/dumpmiles/dumpmiles.cpp b/utils/dumpmiles/dumpmiles.cpp
index 0c2d51b..a1a3816 100644
--- a/utils/dumpmiles/dumpmiles.cpp
+++ b/utils/dumpmiles/dumpmiles.cpp
@@ -49,5 +49,14 @@ static void LoadMiles(const char* fn)
int main(int argc, const char* const* argv)
{
+ if(argc < 2)
+ {
+ std::printf("Usage: \n"
+ " %s filename.opl\n"
+ "or:\n"
+ " %s filename.opl\n"
+ "\n", argv[0], argv[0]);
+ return 1;
+ }
LoadMiles(argv[1]);
}
diff --git a/utils/gen_adldata/file_formats/load_ail.h b/utils/gen_adldata/file_formats/load_ail.h
index a10ff92..e63b1d7 100644
--- a/utils/gen_adldata/file_formats/load_ail.h
+++ b/utils/gen_adldata/file_formats/load_ail.h
@@ -89,6 +89,7 @@ static bool LoadMiles(const char *fn, unsigned bank, const char *prefix)
struct ins tmp2;
tmp2.notenum = gmno < 128 ? 0 : (unsigned char)notenum;
tmp2.pseudo4op = false;
+ tmp2.real4op = (inscount > 1);
tmp2.voice2_fine_tune = 0.0;
std::string name;
if(midi_index >= 0) name = std::string(1, '\377') + MidiInsName[midi_index];
diff --git a/utils/gen_adldata/file_formats/load_bisqwit.h b/utils/gen_adldata/file_formats/load_bisqwit.h
index 015b0eb..f5f73dc 100644
--- a/utils/gen_adldata/file_formats/load_bisqwit.h
+++ b/utils/gen_adldata/file_formats/load_bisqwit.h
@@ -44,6 +44,7 @@ static bool LoadBisqwit(const char *fn, unsigned bank, const char *prefix)
(gmno < 128 ? 'M' : 'P'), gmno & 127);
tmp[1].diff = (tmp[0] != tmp[1]);
+ tmp2.real4op = tmp[1].diff;
size_t resno = InsertIns(tmp[0], tmp[1], tmp2, name, name2, (tmp[0] == tmp[1]));
SetBank(bank, gmno, resno);
}
diff --git a/utils/gen_adldata/file_formats/load_bnk.h b/utils/gen_adldata/file_formats/load_bnk.h
index a41185a..aa7701f 100644
--- a/utils/gen_adldata/file_formats/load_bnk.h
+++ b/utils/gen_adldata/file_formats/load_bnk.h
@@ -69,7 +69,8 @@ static bool LoadBNK(const char *fn, unsigned bank, const char *prefix, bool is_f
if(name[2] == 'O'
|| name[2] == 'S')
{
- gmno = 128 + std::stoi(name.substr(3));
+ std::string n = name.substr(3);
+ gmno = 128 + std::atoi(n.c_str());
}
}
@@ -107,6 +108,7 @@ static bool LoadBNK(const char *fn, unsigned bank, const char *prefix, bool is_f
ins tmp2;
tmp2.notenum = is_fat ? voice_num : (percussive ? usage_flag : 0);
tmp2.pseudo4op = false;
+ tmp2.real4op = false;
tmp2.voice2_fine_tune = 0.0;
if(is_fat) tmp.data[10] ^= 1;
diff --git a/utils/gen_adldata/file_formats/load_bnk2.h b/utils/gen_adldata/file_formats/load_bnk2.h
index 1f3d4a1..4772da5 100644
--- a/utils/gen_adldata/file_formats/load_bnk2.h
+++ b/utils/gen_adldata/file_formats/load_bnk2.h
@@ -3,6 +3,11 @@
#include "../progs_cache.h"
+inline int stdstoi(const std::string& str)
+{
+ return std::atoi(str.c_str());
+}
+
static bool LoadBNK2(const char *fn, unsigned bank, const char *prefix,
const std::string &melo_filter,
const std::string &perc_filter)
@@ -43,9 +48,9 @@ static bool LoadBNK2(const char *fn, unsigned bank, const char *prefix,
int gmno = 0;
if(name.substr(0, melo_filter.size()) == melo_filter)
- gmno = std::stoi(name.substr(melo_filter.size()));
+ gmno = stdstoi(name.substr(melo_filter.size()));
else if(name.substr(0, perc_filter.size()) == perc_filter)
- gmno = std::stoi(name.substr(perc_filter.size())) + 128;
+ gmno = stdstoi(name.substr(perc_filter.size())) + 128;
else
continue;
@@ -81,6 +86,7 @@ static bool LoadBNK2(const char *fn, unsigned bank, const char *prefix,
ins tmp2;
tmp2.notenum = (gmno & 128) ? 35 : 0;
tmp2.pseudo4op = false;
+ tmp2.real4op = false;
tmp2.voice2_fine_tune = 0.0;
if(xxP24NNN & 8)
diff --git a/utils/gen_adldata/file_formats/load_ea.h b/utils/gen_adldata/file_formats/load_ea.h
index 5e0baa4..79367d9 100644
--- a/utils/gen_adldata/file_formats/load_ea.h
+++ b/utils/gen_adldata/file_formats/load_ea.h
@@ -85,16 +85,17 @@ static bool LoadEA(const char *fn, unsigned bank, const char *prefix)
ins tmp2{};
tmp2.notenum = 0;
tmp2.pseudo4op = false;
+ tmp2.real4op = false;
std::string name;
char name2[512];
if(gmno < 20)
{
- std::snprintf(name2, 512, "%sM%u", prefix, gmno);
+ snprintf(name2, 512, "%sM%u", prefix, gmno);
}
else
{
- std::snprintf(name2, 512, "%sunk%04X", prefix, offset);
+ snprintf(name2, 512, "%sunk%04X", prefix, offset);
}
size_t resno = InsertIns(tmp, tmp2, std::string(1, '\377') + name, name2);
SetBank(bank, gmno, resno);
diff --git a/utils/gen_adldata/file_formats/load_ibk.h b/utils/gen_adldata/file_formats/load_ibk.h
index bc03962..12fa520 100644
--- a/utils/gen_adldata/file_formats/load_ibk.h
+++ b/utils/gen_adldata/file_formats/load_ibk.h
@@ -61,6 +61,7 @@ static bool LoadIBK(const char *fn, unsigned bank, const char *prefix, bool perc
struct ins tmp2;
tmp2.notenum = gmno < 128 ? 0 : 35;
tmp2.pseudo4op = false;
+ tmp2.real4op = false;
tmp2.voice2_fine_tune = 0.0;
size_t resno = InsertIns(tmp, tmp2, std::string(1, '\377') + name, name2);
diff --git a/utils/gen_adldata/file_formats/load_jv.h b/utils/gen_adldata/file_formats/load_jv.h
index b79832f..35caead 100644
--- a/utils/gen_adldata/file_formats/load_jv.h
+++ b/utils/gen_adldata/file_formats/load_jv.h
@@ -71,6 +71,7 @@ static bool LoadJunglevision(const char *fn, unsigned bank, const char *prefix)
struct ins tmp2;
tmp2.notenum = data[offset + 1];
tmp2.pseudo4op = false;
+ tmp2.real4op = (data[offset] != 0);
tmp2.voice2_fine_tune = 0.0;
while(tmp2.notenum && tmp2.notenum < 20)
diff --git a/utils/gen_adldata/file_formats/load_op2.h b/utils/gen_adldata/file_formats/load_op2.h
index 8b7fec6..48b7eae 100644
--- a/utils/gen_adldata/file_formats/load_op2.h
+++ b/utils/gen_adldata/file_formats/load_op2.h
@@ -82,7 +82,7 @@ static bool LoadDoom(const char *fn, unsigned bank, const char *prefix)
int gmno = int(a < 128 ? a : ((a | 128) + 35));
char name2[512];
- std::snprintf(name2, 512, "%s%c%u", prefix, (gmno < 128 ? 'M' : 'P'), gmno & 127);
+ snprintf(name2, 512, "%s%c%u", prefix, (gmno < 128 ? 'M' : 'P'), gmno & 127);
Doom_opl_instr &ins = *(Doom_opl_instr *) &data[offset2];
@@ -108,6 +108,7 @@ static bool LoadDoom(const char *fn, unsigned bank, const char *prefix)
struct ins tmp2;
tmp2.notenum = ins.note;
tmp2.pseudo4op = false;
+ tmp2.real4op = false;
tmp2.voice2_fine_tune = 0.0;
while(tmp2.notenum && tmp2.notenum < 20)
{
diff --git a/utils/gen_adldata/file_formats/load_tmb.h b/utils/gen_adldata/file_formats/load_tmb.h
index ab1ff37..5b38433 100644
--- a/utils/gen_adldata/file_formats/load_tmb.h
+++ b/utils/gen_adldata/file_formats/load_tmb.h
@@ -50,6 +50,7 @@ static bool LoadTMB(const char *fn, unsigned bank, const char *prefix)
struct ins tmp2;
tmp2.notenum = data[offset + 11];
tmp2.pseudo4op = false;
+ tmp2.real4op = false;
tmp2.voice2_fine_tune = 0.0;
std::string name;
diff --git a/utils/gen_adldata/file_formats/load_wopl.h b/utils/gen_adldata/file_formats/load_wopl.h
index 26a2611..fe4865d 100644
--- a/utils/gen_adldata/file_formats/load_wopl.h
+++ b/utils/gen_adldata/file_formats/load_wopl.h
@@ -57,8 +57,8 @@ static bool LoadWopl(const char *fn, unsigned bank, const char *prefix)
uint16_t pbanks_count = toUint16BE((const uint8_t *)data.data() + 0x0f);
AdlBankSetup setup;
- setup.deepTremolo = (data[0x11] >> 0) & 0x01;
- setup.deepVibrato = (data[0x11] >> 1) & 0x01;
+ setup.deepTremolo = (data[0x11] & 0x01) != 0;
+ setup.deepVibrato = (data[0x11] & 0x02) != 0;
setup.volumeModel = (int)data[0x12];
setup.adLibPercussions = false;
setup.scaleModulators = false;
@@ -169,6 +169,7 @@ static bool LoadWopl(const char *fn, unsigned bank, const char *prefix)
tmp2.notenum = is_percussion ? data[offset + 38] : 0;
bool real4op = (flags & (uint8_t)WOPL_Flags::Mode_4op) != 0;
tmp2.pseudo4op = (flags & (uint8_t)WOPL_Flags::Mode_DoubleVoice) != 0;
+ tmp2.real4op = real4op && !tmp2.pseudo4op;
tmp2.voice2_fine_tune = 0;
tmp[0].diff = false;
tmp[1].diff = real4op && !tmp2.pseudo4op;
@@ -207,9 +208,9 @@ static bool LoadWopl(const char *fn, unsigned bank, const char *prefix)
char name2[512];
std::memset(name2, 0, 512);
if(is_percussion)
- std::snprintf(name2, 512, "%sP%u", prefix, gmno & 127);
+ snprintf(name2, 512, "%sP%u", prefix, gmno & 127);
else
- std::snprintf(name2, 512, "%sM%u", prefix, i);
+ snprintf(name2, 512, "%sM%u", prefix, i);
if(!real4op && !tmp2.pseudo4op)
{
diff --git a/utils/gen_adldata/gen_adldata.cc b/utils/gen_adldata/gen_adldata.cc
index 7c8af8b..bc5c231 100644
--- a/utils/gen_adldata/gen_adldata.cc
+++ b/utils/gen_adldata/gen_adldata.cc
@@ -312,7 +312,7 @@ int main(int argc, char**argv)
i->first.data[10],
i->first.finetune);
- #ifdef ADLDATA_WITH_COMMENTS
+#ifdef ADLDATA_WITH_COMMENTS
std::string names;
for(std::set<std::string>::const_iterator
j = i->second.second.begin();
@@ -326,9 +326,9 @@ int main(int argc, char**argv)
names += *j;
}
std::fprintf(outFile, " }, // %u: %s\n", (unsigned)c, names.c_str());
- #else
+#else
std::fprintf(outFile, " },\n");
- #endif
+#endif
}
}
std::fprintf(outFile, "};\n");
@@ -341,6 +341,7 @@ int main(int argc, char**argv)
" unsigned char flags;\n"
" long ms_sound_kon; // Number of milliseconds it produces sound;\n"
" long ms_sound_koff;\n"
+ " double voice2_fine_tune;\n"
"} adlins[] =\n");*/
std::fprintf(outFile, "const struct adlinsdata adlins[%u] =\n", (unsigned)instab.size());
@@ -348,7 +349,7 @@ int main(int argc, char**argv)
MeasureThreaded measureCounter;
{
- std::printf("Beginning to generate measures data... (Hardware concurrency: %d)\n", std::thread::hardware_concurrency());
+ std::printf("Beginning to generate measures data... (hardware concurrency of %d)\n", std::thread::hardware_concurrency());
std::fflush(stdout);
measureCounter.LoadCache("fm_banks/adldata-cache.dat");
measureCounter.m_total = instab.size();
@@ -381,7 +382,7 @@ int main(int argc, char**argv)
//DurationInfo info = MeasureDurations(i->first);
MeasureThreaded::DurationInfoCache::iterator indo_i = measureCounter.m_durationInfo.find(i->first);
DurationInfo info = indo_i->second;
- #ifdef ADLDATA_WITH_COMMENTS
+#ifdef ADLDATA_WITH_COMMENTS
{
if(info.peak_amplitude_time == 0)
{
@@ -404,12 +405,14 @@ int main(int argc, char**argv)
info.keyoff_out_time / double(info.interval));
}
}
- #endif
+#endif
- unsigned flags = (i->first.pseudo4op ? 1 : 0) | (info.nosound ? 2 : 0);
+ unsigned flags = (i->first.pseudo4op ? ins::Flag_Pseudo4op : 0)|
+ (i->first.real4op ? ins::Flag_Real4op : 0) |
+ (info.nosound ? ins::Flag_NoSound : 0);
std::fprintf(outFile, " {");
- std::fprintf(outFile, "%4d,%4d,%3d, %d, %6" PRId64 ",%6" PRId64 ",%lf",
+ std::fprintf(outFile, "%4d,%4d,%3d, %d, %6" PRId64 ",%6" PRId64 ",%g",
(unsigned) i->first.insno1,
(unsigned) i->first.insno2,
(int)(i->first.notenum),
@@ -429,11 +432,11 @@ int main(int argc, char**argv)
else
names += *j;
}
- #ifdef ADLDATA_WITH_COMMENTS
+#ifdef ADLDATA_WITH_COMMENTS
std::fprintf(outFile, " }, // %u: %s\n\n", (unsigned)c, names.c_str());
- #else
+#else
std::fprintf(outFile, " },\n");
- #endif
+#endif
std::fflush(outFile);
adlins_flags.push_back(flags);
}
@@ -444,11 +447,11 @@ int main(int argc, char**argv)
std::fflush(stdout);
//fprintf(outFile, "static const unsigned short banks[][256] =\n");
- #ifdef HARD_BANKS
+#ifdef HARD_BANKS
const unsigned bankcount = sizeof(banknames) / sizeof(*banknames);
- #else
+#else
const size_t bankcount = banknames.size();
- #endif
+#endif
size_t nosound = InsertNoSoundIns();
@@ -486,25 +489,29 @@ int main(int argc, char**argv)
std::fprintf(outFile, "{\n");
for(unsigned bank = 0; bank < bankcount; ++bank)
{
- #ifdef ADLDATA_WITH_COMMENTS
+#ifdef ADLDATA_WITH_COMMENTS
std::fprintf(outFile, " { // bank %u, %s\n", bank, banknames[bank].c_str());
- #else
+#else
std::fprintf(outFile, " {\n");
#endif
+#ifdef ADLDATA_WITH_COMMENTS
bool redundant = true;
+#endif
for(unsigned p = 0; p < 256; ++p)
{
size_t v = bank_data[bank][p];
if(listed.find(v) == listed.end())
{
listed.insert(v);
+#ifdef ADLDATA_WITH_COMMENTS
redundant = false;
+#endif
}
std::fprintf(outFile, "%4d,", (unsigned int)v);
if(p % 16 == 15) fprintf(outFile, "\n");
}
std::fprintf(outFile, " },\n");
- #ifdef ADLDATA_WITH_COMMENTS
+#ifdef ADLDATA_WITH_COMMENTS
if(redundant)
{
std::fprintf(outFile, " // Bank %u defines nothing new.\n", bank);
@@ -523,7 +530,7 @@ int main(int argc, char**argv)
bank, refbank);
}
}
- #endif
+#endif
}
std::fprintf(outFile, "};\n\n");
diff --git a/utils/gen_adldata/ini/ini_processing.cpp b/utils/gen_adldata/ini/ini_processing.cpp
index 26da540..8a2807b 100644
--- a/utils/gen_adldata/ini/ini_processing.cpp
+++ b/utils/gen_adldata/ini/ini_processing.cpp
@@ -1,27 +1,26 @@
/*
-INI Processor - a small library which allows you parsing INI-files
-
-Copyright (c) 2015-2018 Vitaly Novichkov <admin@wohlnet.ru>
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation the
-rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-sell copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-
-*/
+ * INI Processor - a small library which allows you parsing INI-files
+ *
+ * Copyright (c) 2015-2018 Vitaly Novichkov <admin@wohlnet.ru>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
//#define USE_FILE_MAPPER
diff --git a/utils/gen_adldata/ini/ini_processing.h b/utils/gen_adldata/ini/ini_processing.h
index 8da4b7e..64777a5 100644
--- a/utils/gen_adldata/ini/ini_processing.h
+++ b/utils/gen_adldata/ini/ini_processing.h
@@ -1,26 +1,26 @@
/*
-INI Processor - a small library which allows you parsing INI-files
-
-Copyright (c) 2015-2018 Vitaly Novichkov <admin@wohlnet.ru>
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation the
-rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-sell copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-*/
+ * INI Processor - a small library which allows you parsing INI-files
+ *
+ * Copyright (c) 2015-2018 Vitaly Novichkov <admin@wohlnet.ru>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
#ifndef INIPROCESSING_H
#define INIPROCESSING_H
diff --git a/utils/gen_adldata/ini/ini_processing_variant.h b/utils/gen_adldata/ini/ini_processing_variant.h
index 41a96dd..d659aa9 100644
--- a/utils/gen_adldata/ini/ini_processing_variant.h
+++ b/utils/gen_adldata/ini/ini_processing_variant.h
@@ -1,31 +1,31 @@
/*
-INI Processor - a small library which allows you parsing INI-files
-
-Copyright (c) 2015-2018 Vitaly Novichkov <admin@wohlnet.ru>
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation the
-rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-sell copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-*/
+ * INI Processor - a small library which allows you parsing INI-files
+ *
+ * Copyright (c) 2015-2018 Vitaly Novichkov <admin@wohlnet.ru>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
/*
-A QVariant-like thing created just like a proxy between
-INI Processor and target value (to be compatible with QSettings)
-*/
+ * A QVariant-like thing created just like a proxy between
+ * INI Processor and target value (to be compatible with QSettings)
+ */
#ifndef INI_PROCESSING_VARIANT_H
#define INI_PROCESSING_VARIANT_H
diff --git a/utils/gen_adldata/measurer.cpp b/utils/gen_adldata/measurer.cpp
index 7a81379..7caf883 100644
--- a/utils/gen_adldata/measurer.cpp
+++ b/utils/gen_adldata/measurer.cpp
@@ -1,7 +1,9 @@
#include "measurer.h"
#include <cmath>
-#include "../../src/chips/opl_chip_base.h"
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
// Nuked OPL3 emulator, Most accurate, but requires the powerful CPU
#ifndef ADLMIDI_DISABLE_NUKED_EMULATOR
@@ -14,208 +16,367 @@
# include "../../src/chips/dosbox_opl3.h"
#endif
-DurationInfo MeasureDurations(const ins &in)
+template <class T>
+class AudioHistory
{
- std::vector<int16_t> stereoSampleBuf;
-#ifdef ADLMIDI_USE_DOSBOX_OPL
- std::vector<int32_t> stereoSampleBuf_32;
-#endif
- insdata id[2];
- bool found[2] = {false, false};
- for(InstrumentDataTab::const_iterator j = insdatatab.begin();
- j != insdatatab.end();
- ++j)
+ std::unique_ptr<T[]> m_data;
+ size_t m_index = 0; // points to the next write slot
+ size_t m_length = 0;
+ size_t m_capacity = 0;
+
+public:
+ size_t size() const { return m_length; }
+ size_t capacity() const { return m_capacity; }
+ const T *data() const { return &m_data[m_index + m_capacity - m_length]; }
+
+ void reset(size_t capacity)
{
- if(j->second.first == in.insno1)
- {
- id[0] = j->first;
- found[0] = true;
- if(found[1]) break;
- }
- if(j->second.first == in.insno2)
- {
- id[1] = j->first;
- found[1] = true;
- if(found[0]) break;
- }
+ m_data.reset(new T[2 * capacity]());
+ m_index = 0;
+ m_length = 0;
+ m_capacity = capacity;
}
- const unsigned rate = 22010;
- const unsigned interval = 150;
- const unsigned samples_per_interval = rate / interval;
- const int notenum =
- in.notenum < 20 ? (44 + in.notenum)
- : in.notenum >= 128 ? (44 + 128 - in.notenum)
- : in.notenum;
- OPLChipBase *opl;
+ void clear()
+ {
+ m_length = 0;
+ }
- //DosBoxOPL3 db; opl = &db;
- //NukedOPL3 nuke; opl = &nuke;
- NukedOPL3v174 nuke74; opl = &nuke74;
+ void add(const T &item)
+ {
+ T *data = m_data.get();
+ const size_t capacity = m_capacity;
+ size_t index = m_index;
+ data[index] = item;
+ data[index + capacity] = item;
+ m_index = (index + 1 != capacity) ? (index + 1) : 0;
+ size_t length = m_length + 1;
+ m_length = (length < capacity) ? length : capacity;
+ }
+};
-#define WRITE_REG(key, value) opl->writeReg((uint16_t)(key), (uint8_t)(value))
+static void HannWindow(double *w, unsigned n)
+{
+ for (unsigned i = 0; i < n; ++i)
+ w[i] = 0.5 * (1.0 - std::cos(2 * M_PI * i / (n - 1)));
+}
- static const short initdata[(2 + 3 + 2 + 2) * 2] =
+static double MeasureRMS(const double *signal, const double *window, unsigned length)
+{
+ double mean = 0;
+#pragma omp simd reduction(+: mean)
+ for(unsigned i = 0; i < length; ++i)
+ mean += window[i] * signal[i];
+ mean /= length;
+
+ double rms = 0;
+#pragma omp simd reduction(+: rms)
+ for(unsigned i = 0; i < length; ++i)
{
- 0x004, 96, 0x004, 128, // Pulse timer
- 0x105, 0, 0x105, 1, 0x105, 0, // Pulse OPL3 enable, leave disabled
- 0x001, 32, 0x0BD, 0 // Enable wave & melodic
- };
- opl->setRate(rate);
+ double diff = window[i] * signal[i] - mean;
+ rms += diff * diff;
+ }
+ rms = std::sqrt(rms / (length - 1));
- for(unsigned a = 0; a < 18; a += 2) WRITE_REG(initdata[a], initdata[a + 1]);
+ return rms;
+}
- const unsigned n_notes = in.insno1 == in.insno2 ? 1 : 2;
- unsigned x[2];
+static const unsigned g_outputRate = 49716;
- if(n_notes == 2 && !in.pseudo4op)
+struct TinySynth
+{
+ OPLChipBase *m_chip;
+ unsigned m_notesNum;
+ int m_notenum;
+ int8_t m_fineTune;
+ int16_t m_noteOffsets[2];
+ unsigned m_x[2];
+
+ void resetChip()
{
- WRITE_REG(0x105, 1);
- WRITE_REG(0x104, 1);
- }
+ static const short initdata[(2 + 3 + 2 + 2) * 2] =
+ {
+ 0x004, 96, 0x004, 128, // Pulse timer
+ 0x105, 0, 0x105, 1, 0x105, 0, // Pulse OPL3 enable, leave disabled
+ 0x001, 32, 0x0BD, 0 // Enable wave & melodic
+ };
- for(unsigned n = 0; n < n_notes; ++n)
- {
- static const unsigned char patchdata[11] =
- {0x20, 0x23, 0x60, 0x63, 0x80, 0x83, 0xE0, 0xE3, 0x40, 0x43, 0xC0};
- for(unsigned a = 0; a < 10; ++a) WRITE_REG(patchdata[a] + n * 8, id[n].data[a]);
- WRITE_REG(patchdata[10] + n * 8, id[n].data[10] | 0x30);
+ m_chip->setRate(g_outputRate);
+
+ for(unsigned a = 0; a < 18; a += 2)
+ m_chip->writeReg((uint16_t)initdata[a], (uint8_t)initdata[a + 1]);
}
- for(unsigned n = 0; n < n_notes; ++n)
+ void setInstrument(const ins &in)
{
- double hertz = 172.00093 * std::exp(0.057762265 * (notenum + id[n].finetune));
- if(hertz > 131071)
+ insdata rawData[2];
+ bool found[2] = {false, false};
+ for(InstrumentDataTab::const_iterator j = insdatatab.begin();
+ j != insdatatab.end();
+ ++j)
+ {
+ if(j->second.first == in.insno1)
+ {
+ rawData[0] = j->first;
+ found[0] = true;
+ if(found[1]) break;
+ }
+ if(j->second.first == in.insno2)
+ {
+ rawData[1] = j->first;
+ found[1] = true;
+ if(found[0]) break;
+ }
+ }
+
+ std::memset(m_x, 0, sizeof(m_x));
+ m_notenum = in.notenum >= 128 ? (in.notenum - 128) : in.notenum;
+ if(m_notenum == 0)
+ m_notenum = 25;
+ m_notesNum = in.insno1 == in.insno2 ? 1 : 2;
+ m_fineTune = 0;
+ m_noteOffsets[0] = rawData[0].finetune;
+ m_noteOffsets[1] = rawData[1].finetune;
+ if(in.pseudo4op)
+ m_fineTune = in.voice2_fine_tune;
+ if(in.real4op)
{
- std::fprintf(stderr, "MEASURER WARNING: Why does note %d + finetune %d produce hertz %g? \n",
- notenum, id[n].finetune, hertz);
- hertz = 131071;
+ m_chip->writeReg(0x105, 1);
+ m_chip->writeReg(0x104, 0xFF);
}
- x[n] = 0x2000;
- while(hertz >= 1023.5)
+
+ //For clearer measurement, disable tremolo and vibrato
+ rawData[0].data[0] &= 0x3F;
+ rawData[0].data[1] &= 0x3F;
+ rawData[1].data[0] &= 0x3F;
+ rawData[1].data[1] &= 0x3F;
+
+ for(unsigned n = 0; n < m_notesNum; ++n)
{
- hertz /= 2.0; // Calculate octave
- x[n] += 0x400;
+ static const unsigned char patchdata[11] =
+ {0x20, 0x23, 0x60, 0x63, 0x80, 0x83, 0xE0, 0xE3, 0x40, 0x43, 0xC0};
+ for(unsigned a = 0; a < 10; ++a)
+ m_chip->writeReg(patchdata[a] + n * 8, rawData[n].data[a]);
+ m_chip->writeReg(patchdata[10] + n * 8, rawData[n].data[10] | 0x30);
}
- x[n] += (unsigned int)(hertz + 0.5);
+ }
+
+ void noteOn()
+ {
+ std::memset(m_x, 0, sizeof(m_x));
+ for(unsigned n = 0; n < m_notesNum; ++n)
+ {
+ double hertz = 172.00093 * std::exp(0.057762265 * (m_notenum + m_noteOffsets[n]));
+ if(hertz > 131071)
+ {
+ std::fprintf(stdout, "%s:%d:0: warning: Why does note %d + note-offset %d produce hertz %g?\n", __FILE__, __LINE__,
+ m_notenum, m_noteOffsets[n], hertz);
+ std::fflush(stdout);
+ hertz = 131071;
+ }
+ m_x[n] = 0x2000;
+ while(hertz >= 1023.5)
+ {
+ hertz /= 2.0; // Calculate octave
+ m_x[n] += 0x400;
+ }
+ m_x[n] += (unsigned int)(hertz + 0.5);
- // Keyon the note
- WRITE_REG(0xA0 + n * 3, x[n] & 0xFF);
- WRITE_REG(0xB0 + n * 3, x[n] >> 8);
+ // Keyon the note
+ m_chip->writeReg(0xA0 + n * 3, m_x[n] & 0xFF);
+ m_chip->writeReg(0xB0 + n * 3, m_x[n] >> 8);
+ }
+ }
+
+ void noteOff()
+ {
+ // Keyoff the note
+ for(unsigned n = 0; n < m_notesNum; ++n)
+ m_chip->writeReg(0xB0 + n * 3, (m_x[n] >> 8) & 0xDF);
}
+ void generate(int16_t *output, size_t frames)
+ {
+ m_chip->generate(output, frames);
+ }
+};
+
+
+DurationInfo MeasureDurations(const ins &in, OPLChipBase *chip)
+{
+ AudioHistory<double> audioHistory;
+
+ const unsigned interval = 150;
+ const unsigned samples_per_interval = g_outputRate / interval;
+
+ const double historyLength = 0.1; // maximum duration to memorize (seconds)
+ audioHistory.reset(std::ceil(historyLength * g_outputRate));
+
+ std::unique_ptr<double[]> window;
+ window.reset(new double[audioHistory.capacity()]);
+ unsigned winsize = 0;
+
+ TinySynth synth;
+ synth.m_chip = chip;
+ synth.resetChip();
+ synth.setInstrument(in);
+ synth.noteOn();
+
+ /* For capturing */
const unsigned max_silent = 6;
const unsigned max_on = 40;
const unsigned max_off = 60;
+ unsigned max_period_on = max_on * interval;
+ unsigned max_period_off = max_off * interval;
+
+ const double min_coefficient_on = 0.008;
+ const double min_coefficient_off = 0.2;
+
+ unsigned windows_passed_on = 0;
+ unsigned windows_passed_off = 0;
+
+ /* For Analyze the results */
+ double begin_amplitude = 0;
+ double peak_amplitude_value = 0;
+ size_t peak_amplitude_time = 0;
+ size_t quarter_amplitude_time = max_period_on;
+ bool quarter_amplitude_time_found = false;
+ size_t keyoff_out_time = 0;
+ bool keyoff_out_time_found = false;
+
+ const size_t audioBufferLength = 256;
+ const size_t audioBufferSize = 2 * audioBufferLength;
+ int16_t audioBuffer[audioBufferSize];
+
// For up to 40 seconds, measure mean amplitude.
- std::vector<double> amplitudecurve_on;
double highest_sofar = 0;
short sound_min = 0, sound_max = 0;
- for(unsigned period = 0; period < max_on * interval; ++period)
+
+ for(unsigned period = 0; period < max_period_on; ++period, ++windows_passed_on)
{
- stereoSampleBuf.clear();
- stereoSampleBuf.resize(samples_per_interval * 2);
- opl->generate(stereoSampleBuf.data(), samples_per_interval);
+ for(unsigned i = 0; i < samples_per_interval;)
+ {
+ size_t blocksize = samples_per_interval - i;
+ blocksize = (blocksize < audioBufferLength) ? blocksize : audioBufferLength;
+ synth.generate(audioBuffer, blocksize);
+ for (unsigned j = 0; j < blocksize; ++j)
+ {
+ int16_t s = audioBuffer[2 * j];
+ audioHistory.add(s);
+ if(sound_min > s) sound_min = s;
+ if(sound_max < s) sound_max = s;
+ }
+ i += blocksize;
+ }
- double mean = 0.0;
- for(unsigned long c = 0; c < samples_per_interval; ++c)
+ if(winsize != audioHistory.size())
{
- short s = stereoSampleBuf[c * 2];
- mean += s;
- if(sound_min > s) sound_min = s;
- if(sound_max < s) sound_max = s;
+ winsize = audioHistory.size();
+ HannWindow(window.get(), winsize);
}
- mean /= samples_per_interval;
- double std_deviation = 0;
- for(unsigned long c = 0; c < samples_per_interval; ++c)
+
+ double rms = MeasureRMS(audioHistory.data(), window.get(), winsize);
+ /* ======== Peak time detection ======== */
+ if(period == 0)
+ {
+ begin_amplitude = rms;
+ peak_amplitude_value = rms;
+ peak_amplitude_time = 0;
+ }
+ else if(rms > peak_amplitude_value)
{
- double diff = (stereoSampleBuf[c * 2] - mean);
- std_deviation += diff * diff;
+ peak_amplitude_value = rms;
+ peak_amplitude_time = period;
+ // In next step, update the quater amplitude time
+ quarter_amplitude_time_found = false;
}
- std_deviation = std::sqrt(std_deviation / samples_per_interval);
- amplitudecurve_on.push_back(std_deviation);
- if(std_deviation > highest_sofar)
- highest_sofar = std_deviation;
+ else if(!quarter_amplitude_time_found && (rms <= peak_amplitude_value * min_coefficient_on))
+ {
+ quarter_amplitude_time = period;
+ quarter_amplitude_time_found = true;
+ }
+ /* ======== Peak time detection =END==== */
+ if(rms > highest_sofar)
+ highest_sofar = rms;
if((period > max_silent * interval) &&
- ((std_deviation < highest_sofar * 0.2)||
- (sound_min >= -1 && sound_max <= 1))
+ ( (rms < highest_sofar * min_coefficient_on) || (sound_min >= -1 && sound_max <= 1) )
)
break;
}
- // Keyoff the note
- for(unsigned n = 0; n < n_notes; ++n)
- WRITE_REG(0xB0 + n * 3, (x[n] >> 8) & 0xDF);
+ if(!quarter_amplitude_time_found)
+ quarter_amplitude_time = windows_passed_on;
- // Now, for up to 60 seconds, measure mean amplitude.
- std::vector<double> amplitudecurve_off;
- for(unsigned period = 0; period < max_off * interval; ++period)
+ if(windows_passed_on >= max_period_on)
{
- stereoSampleBuf.clear();
- stereoSampleBuf.resize(samples_per_interval * 2);
- opl->generate(stereoSampleBuf.data(), samples_per_interval);
-
- double mean = 0.0;
- for(unsigned long c = 0; c < samples_per_interval; ++c)
- {
- short s = stereoSampleBuf[c * 2];
- mean += s;
- if(sound_min > s) sound_min = s;
- if(sound_max < s) sound_max = s;
- }
- mean /= samples_per_interval;
- double std_deviation = 0;
- for(unsigned long c = 0; c < samples_per_interval; ++c)
+ // Just Keyoff the note
+ synth.noteOff();
+ }
+ else
+ {
+ // Reset the emulator and re-run the "ON" simulation until reaching the peak time
+ synth.resetChip();
+ synth.setInstrument(in);
+ synth.noteOn();
+
+ audioHistory.reset(std::ceil(historyLength * g_outputRate));
+ for(unsigned period = 0;
+ (period < peak_amplitude_time) && (period < max_period_on);
+ ++period)
{
- double diff = (stereoSampleBuf[c * 2] - mean);
- std_deviation += diff * diff;
+ for(unsigned i = 0; i < samples_per_interval;)
+ {
+ size_t blocksize = samples_per_interval - i;
+ blocksize = (blocksize < audioBufferLength) ? blocksize : audioBufferLength;
+ synth.generate(audioBuffer, blocksize);
+ for (unsigned j = 0; j < blocksize; ++j)
+ audioHistory.add(audioBuffer[2 * j]);
+ i += blocksize;
+ }
}
- std_deviation = std::sqrt(std_deviation / samples_per_interval);
- amplitudecurve_off.push_back(std_deviation);
-
- if(std_deviation < highest_sofar * 0.2)
- break;
-
- if((period > max_silent * interval) && (sound_min >= -1 && sound_max <= 1))
- break;
+ synth.noteOff();
}
- /* Analyze the results */
- double begin_amplitude = amplitudecurve_on[0];
- double peak_amplitude_value = begin_amplitude;
- size_t peak_amplitude_time = 0;
- size_t quarter_amplitude_time = amplitudecurve_on.size();
- size_t keyoff_out_time = 0;
-
- for(size_t a = 1; a < amplitudecurve_on.size(); ++a)
+ // Now, for up to 60 seconds, measure mean amplitude.
+ for(unsigned period = 0; period < max_period_off; ++period, ++windows_passed_off)
{
- if(amplitudecurve_on[a] > peak_amplitude_value)
+ for(unsigned i = 0; i < samples_per_interval;)
{
- peak_amplitude_value = amplitudecurve_on[a];
- peak_amplitude_time = a;
+ size_t blocksize = samples_per_interval - i;
+ blocksize = (blocksize < 256) ? blocksize : 256;
+ synth.generate(audioBuffer, blocksize);
+ for (unsigned j = 0; j < blocksize; ++j)
+ {
+ int16_t s = audioBuffer[2 * j];
+ audioHistory.add(s);
+ if(sound_min > s) sound_min = s;
+ if(sound_max < s) sound_max = s;
+ }
+ i += blocksize;
}
- }
- for(size_t a = peak_amplitude_time; a < amplitudecurve_on.size(); ++a)
- {
- if(amplitudecurve_on[a] <= peak_amplitude_value * 0.2)
+
+ if(winsize != audioHistory.size())
{
- quarter_amplitude_time = a;
- break;
+ winsize = audioHistory.size();
+ HannWindow(window.get(), winsize);
}
- }
- for(size_t a = 0; a < amplitudecurve_off.size(); ++a)
- {
- if(amplitudecurve_off[a] <= peak_amplitude_value * 0.2)
+
+ double rms = MeasureRMS(audioHistory.data(), window.get(), winsize);
+ /* ======== Find Key Off time ======== */
+ if(!keyoff_out_time_found && (rms <= peak_amplitude_value * min_coefficient_off))
{
- keyoff_out_time = a;
- break;
+ keyoff_out_time = period;
+ keyoff_out_time_found = true;
}
- }
+ /* ======== Find Key Off time ==END=== */
+ if(rms < highest_sofar * min_coefficient_off)
+ break;
- if(keyoff_out_time == 0 && amplitudecurve_on.back() < peak_amplitude_value * 0.2)
- keyoff_out_time = quarter_amplitude_time;
+ if((period > max_silent * interval) && (sound_min >= -1 && sound_max <= 1))
+ break;
+ }
DurationInfo result;
result.peak_amplitude_time = peak_amplitude_time;
@@ -227,11 +388,10 @@ DurationInfo MeasureDurations(const ins &in)
result.ms_sound_kon = (int64_t)(quarter_amplitude_time * 1000.0 / interval);
result.ms_sound_koff = (int64_t)(keyoff_out_time * 1000.0 / interval);
result.nosound = (peak_amplitude_value < 0.5) || ((sound_min >= -1) && (sound_max <= 1));
+
return result;
}
-static const char* spinner = "-\\|/";
-
void MeasureThreaded::LoadCache(const char *fileName)
{
FILE *in = std::fopen(fileName, "rb");
@@ -290,6 +450,8 @@ void MeasureThreaded::LoadCache(const char *fileName)
inst.insno2 = inval;
if(std::fread(&inst.notenum, 1, 1, in) != 1)
break;
+ if(std::fread(&inst.real4op, 1, 1, in) != 1)
+ break;
if(std::fread(&inst.pseudo4op, 1, 1, in) != 1)
break;
if(std::fread(&inst.voice2_fine_tune, sizeof(double), 1, in) != 1)
@@ -418,6 +580,7 @@ void MeasureThreaded::SaveCache(const char *fileName)
outval = in.insno2;
fwrite(&outval, 1, sizeof(uint64_t), out);
fwrite(&in.notenum, 1, 1, out);
+ fwrite(&in.real4op, 1, 1, out);
fwrite(&in.pseudo4op, 1, 1, out);
fwrite(&in.voice2_fine_tune, sizeof(double), 1, out);
@@ -458,9 +621,13 @@ void MeasureThreaded::SaveCache(const char *fileName)
std::fclose(out);
}
+#ifdef ADL_GENDATA_PRINT_PROGRESS
+
+static const char* spinner = "-\\|/";
+
void MeasureThreaded::printProgress()
{
- std::printf("Calculating measures... [%c %3u%% (%4u/%4u) Threads %3u, Matches %u] \r",
+ std::printf("Calculating measures... [%c %3u%% {%4u/%4u} Threads %3u, Matches %u] \r",
spinner[m_done.load() % 4],
(unsigned int)(((double)m_done.load() / (double)(m_total)) * 100),
(unsigned int)m_done.load(),
@@ -470,6 +637,12 @@ void MeasureThreaded::printProgress()
);
std::fflush(stdout);
}
+#else
+void MeasureThreaded::printProgress()
+{
+ //Do nothing
+}
+#endif
void MeasureThreaded::printFinal()
{
@@ -501,14 +674,18 @@ void MeasureThreaded::run(InstrumentsData::const_iterator i)
dd->myself = this;
dd->start();
m_threads.push_back(dd);
+#ifdef ADL_GENDATA_PRINT_PROGRESS
printProgress();
+#endif
}
void MeasureThreaded::waitAll()
{
for(auto &th : m_threads)
{
+#ifdef ADL_GENDATA_PRINT_PROGRESS
printProgress();
+#endif
delete th;
}
m_threads.clear();
@@ -524,6 +701,7 @@ void MeasureThreaded::destData::callback(void *myself)
{
destData *s = reinterpret_cast<destData *>(myself);
DurationInfo info;
+ DosBoxOPL3 dosbox;
DurationInfoCache::iterator cachedEntry = s->myself->m_durationInfo.find(s->i->first);
if(cachedEntry != s->myself->m_durationInfo.end())
@@ -532,7 +710,7 @@ void MeasureThreaded::destData::callback(void *myself)
goto endWork;
}
- info = MeasureDurations(s->i->first);
+ info = MeasureDurations(s->i->first, &dosbox);
s->myself->m_durationInfo_mx.lock();
s->myself->m_durationInfo.insert({s->i->first, info});
s->myself->m_durationInfo_mx.unlock();
diff --git a/utils/gen_adldata/measurer.h b/utils/gen_adldata/measurer.h
index b9ae3c6..63475ca 100644
--- a/utils/gen_adldata/measurer.h
+++ b/utils/gen_adldata/measurer.h
@@ -100,6 +100,7 @@ struct MeasureThreaded
void waitAll();
};
-extern DurationInfo MeasureDurations(const ins &in);
+class OPLChipBase;
+extern DurationInfo MeasureDurations(const ins &in, OPLChipBase *chip);
#endif // MEASURER_H
diff --git a/utils/gen_adldata/progs_cache.cpp b/utils/gen_adldata/progs_cache.cpp
index a59e7b7..81bba4c 100644
--- a/utils/gen_adldata/progs_cache.cpp
+++ b/utils/gen_adldata/progs_cache.cpp
@@ -112,7 +112,7 @@ size_t InsertNoSoundIns()
{
// { 0x0F70700,0x0F70710, 0xFF,0xFF, 0x0,+0 },
insdata tmp1 = MakeNoSoundIns();
- struct ins tmp2 = { 0, 0, 0, false, 0.0 };
+ struct ins tmp2 = { 0, 0, 0, false, false, 0.0 };
return InsertIns(tmp1, tmp1, tmp2, "nosound", "");
}
diff --git a/utils/gen_adldata/progs_cache.h b/utils/gen_adldata/progs_cache.h
index 7b4cd39..5a916f5 100644
--- a/utils/gen_adldata/progs_cache.h
+++ b/utils/gen_adldata/progs_cache.h
@@ -49,9 +49,11 @@ inline bool equal_approx(double const a, double const b)
struct ins
{
+ enum { Flag_Pseudo4op = 0x01, Flag_NoSound = 0x02, Flag_Real4op = 0x04 };
size_t insno1, insno2;
unsigned char notenum;
bool pseudo4op;
+ bool real4op;
double voice2_fine_tune;
bool operator==(const ins &b) const
@@ -60,6 +62,7 @@ struct ins
&& insno1 == b.insno1
&& insno2 == b.insno2
&& pseudo4op == b.pseudo4op
+ && real4op == b.real4op
&& equal_approx(voice2_fine_tune, b.voice2_fine_tune);
}
bool operator< (const ins &b) const
@@ -68,6 +71,7 @@ struct ins
if(insno2 != b.insno2) return insno2 < b.insno2;
if(notenum != b.notenum) return notenum < b.notenum;
if(pseudo4op != b.pseudo4op) return pseudo4op < b.pseudo4op;
+ if(real4op != b.real4op) return real4op < b.real4op;
if(!equal_approx(voice2_fine_tune, b.voice2_fine_tune)) return voice2_fine_tune < b.voice2_fine_tune;
return 0;
}
diff --git a/utils/midiplay/adlmidiplay.cpp b/utils/midiplay/adlmidiplay.cpp
index a591626..8bffc50 100644
--- a/utils/midiplay/adlmidiplay.cpp
+++ b/utils/midiplay/adlmidiplay.cpp
@@ -320,6 +320,8 @@ int main(int argc, char **argv)
#endif
#ifndef HARDWARE_OPL3
int emulator = ADLMIDI_EMU_NUKED;
+ #endif
+ #if !defined(HARDWARE_OPL3) && !defined(OUTPUT_WAVE_ONLY)
g_audioFormat.type = ADLMIDI_SampleType_S16;
g_audioFormat.containerSize = sizeof(Sint16);
g_audioFormat.sampleOffset = sizeof(Sint16) * 2;
@@ -334,7 +336,7 @@ int main(int argc, char **argv)
else if(!std::strcmp("-v", argv[2]))
adl_setHVibrato(myDevice, 1);//Force turn on deep vibrato
- #ifndef OUTPUT_WAVE_ONLY
+ #if !defined(OUTPUT_WAVE_ONLY) && !defined(HARDWARE_OPL3)
else if(!std::strcmp("-w", argv[2]))
{
//Current Wave output implementation allows only SINT16 output
@@ -402,6 +404,7 @@ int main(int argc, char **argv)
adl_switchEmulator(myDevice, emulator);
#endif
+ std::fprintf(stdout, " - Library version %s\n", adl_linkedLibraryVersion());
#ifdef HARDWARE_OPL3
std::fprintf(stdout, " - Hardware OPL3 chip in use\n");
#else
diff --git a/utils/vlc_codec/libadlmidi.c b/utils/vlc_codec/libadlmidi.c
index 5f85a4d..aedd718 100644
--- a/utils/vlc_codec/libadlmidi.c
+++ b/utils/vlc_codec/libadlmidi.c
@@ -18,14 +18,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
-//#ifdef HAVE_CONFIG_H
-//# include "config.h"
-//#endif
-
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_codec.h>
#include <vlc_dialog.h>
+#include <libvlc_version.h>
#include <unistd.h>
@@ -43,18 +40,20 @@
#define SOUNDFONT_LONGTEXT N_( \
"Custom bank file to use for software synthesis." )
-//#define CHORUS_TEXT N_("Chorus")
+#if 0 /* Old code */
+#define CHORUS_TEXT N_("Chorus")
-//#define GAIN_TEXT N_("Synthesis gain")
-//#define GAIN_LONGTEXT N_("This gain is applied to synthesis output. " \
-// "High values may cause saturation when many notes are played at a time." )
+#define GAIN_TEXT N_("Synthesis gain")
+#define GAIN_LONGTEXT N_("This gain is applied to synthesis output. " \
+ "High values may cause saturation when many notes are played at a time." )
-//#define POLYPHONY_TEXT N_("Polyphony")
-//#define POLYPHONY_LONGTEXT N_( \
-// "The polyphony defines how many voices can be played at a time. " \
-// "Larger values require more processing power.")
+#define POLYPHONY_TEXT N_("Polyphony")
+#define POLYPHONY_LONGTEXT N_( \
+ "The polyphony defines how many voices can be played at a time. " \
+ "Larger values require more processing power.")
-//#define REVERB_TEXT N_("Reverb")
+#define REVERB_TEXT N_("Reverb")
+#endif
#define SAMPLE_RATE_TEXT N_("Sample rate")
@@ -67,7 +66,11 @@ static void Close (vlc_object_t *);
vlc_module_begin ()
set_description (N_("ADLMIDI OPL3 Synth MIDI synthesizer"))
+#if (LIBVLC_VERSION_MAJOR >= 3)
+ set_capability ("audio decoder", 150)
+#else
set_capability ("decoder", 150)
+#endif
set_shortname (N_("ADLMIDI"))
set_category (CAT_INPUT)
set_subcategory (SUBCAT_INPUT_ACODEC)
@@ -105,7 +108,11 @@ static const struct ADLMIDI_AudioFormat g_output_format =
};
//static int DecodeBlock (decoder_t *p_dec, block_t *p_block); //For different version
+#if (LIBVLC_VERSION_MAJOR >= 3)
+static int DecodeBlock (decoder_t *p_dec, block_t *p_block);
+#else
static block_t *DecodeBlock (decoder_t *p_dec, block_t **pp_block);
+#endif
static void Flush (decoder_t *);
static int Open (vlc_object_t *p_this)
@@ -149,10 +156,12 @@ static int Open (vlc_object_t *p_this)
date_Set (&p_sys->end_date, 0);
p_dec->p_sys = p_sys;
- //==For different version==
- //p_dec->pf_decode = DecodeBlock;
- //p_dec->pf_flush = Flush;
+#if (LIBVLC_VERSION_MAJOR >= 3)
+ p_dec->pf_decode = DecodeBlock;
+ p_dec->pf_flush = Flush;
+#else
p_dec->pf_decode_audio = DecodeBlock;
+#endif
return VLC_SUCCESS;//VLCDEC_SUCCESS
}
@@ -168,134 +177,61 @@ static void Close (vlc_object_t *p_this)
static void Flush (decoder_t *p_dec)
{
decoder_sys_t *p_sys = p_dec->p_sys;
-
+#if (LIBVLC_VERSION_MAJOR >= 3)
date_Set (&p_sys->end_date, VLC_TS_INVALID);
+#else
+ date_Set (&p_sys->end_date, 0);
+#endif
adl_panic(p_sys->synth);
}
+#if (LIBVLC_VERSION_MAJOR >= 3)
+static int DecodeBlock (decoder_t *p_dec, block_t *p_block)
+{
+ decoder_sys_t *p_sys = p_dec->p_sys;
+ block_t *p_out = NULL;
+#else
static block_t *DecodeBlock (decoder_t *p_dec, block_t **pp_block)
{
block_t *p_block;
decoder_sys_t *p_sys = p_dec->p_sys;
block_t *p_out = NULL;
-
if (pp_block == NULL)
return NULL;
p_block = *pp_block;
- if (p_block == NULL)
- return NULL;
- *pp_block = NULL;
-
- if (p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED))
- {
- date_Set (&p_sys->end_date, 0);
- adl_panic(p_sys->synth);
- }
-
- if (p_block->i_pts > VLC_TS_INVALID && !date_Get (&p_sys->end_date))
- date_Set (&p_sys->end_date, p_block->i_pts);
- else
- if (p_block->i_pts < date_Get (&p_sys->end_date))
- {
- msg_Warn (p_dec, "MIDI message in the past?");
- goto drop;
- }
-
- if (p_block->i_buffer < 1)
- goto drop;
-
- uint8_t event = p_block->p_buffer[0];
- uint8_t channel = p_block->p_buffer[0] & 0xf;
- event &= 0xF0;
-
- if (event == 0xF0)
- switch (channel)
- {
- case 0:
- if (p_block->p_buffer[p_block->i_buffer - 1] != 0xF7)
- {
- case 7:
- msg_Warn (p_dec, "fragmented SysEx not implemented");
- goto drop;
- }
- //fluid_synth_sysex (p_sys->synth, (char *)p_block->p_buffer + 1,
- // p_block->i_buffer - 2, NULL, NULL, NULL, 0);
- break;
- case 0xF:
- adl_rt_resetState(p_sys->synth);
- break;
- }
-
- uint8_t p1 = (p_block->i_buffer > 1) ? (p_block->p_buffer[1] & 0x7f) : 0;
- uint8_t p2 = (p_block->i_buffer > 2) ? (p_block->p_buffer[2] & 0x7f) : 0;
+#endif
- switch (event & 0xF0)
+ if (p_block == NULL)
{
- case 0x80:
- adl_rt_noteOff(p_sys->synth, channel, p1);
- break;
- case 0x90:
- adl_rt_noteOn(p_sys->synth, channel, p1, p2);
- break;
- /*case 0xA0: note aftertouch not implemented */
- case 0xB0:
- adl_rt_controllerChange(p_sys->synth, channel, p1, p2);
- break;
- case 0xC0:
- adl_rt_patchChange(p_sys->synth, channel, p1);
- break;
- case 0xD0:
- adl_rt_channelAfterTouch(p_sys->synth, channel, p1);
- break;
- case 0xE0:
- adl_rt_pitchBendML(p_sys->synth, channel, p2, p1);
- break;
+#if (LIBVLC_VERSION_MAJOR >= 3)
+ return VLCDEC_SUCCESS;
+#else
+ return p_out;
+#endif
}
- unsigned samples =
- (p_block->i_pts - date_Get (&p_sys->end_date)) * 441 / 10000;
- if (samples == 0)
- goto drop;
-
- p_out = decoder_NewAudioBuffer (p_dec, samples);
- if (p_out == NULL)
- goto drop;
-
- p_out->i_pts = date_Get (&p_sys->end_date );
- samples = adl_generateFormat(p_sys->synth, (int)samples * 2,
- (ADL_UInt8*)p_out->p_buffer,
- (ADL_UInt8*)(p_out->p_buffer + g_output_format.containerSize),
- &g_output_format);
- samples /= 2;
- p_out->i_length = date_Increment (&p_sys->end_date, samples) - p_out->i_pts;
-
-drop:
- block_Release (p_block);
- return p_out;
-}
-
-#if 0
-static int DecodeBlock (decoder_t *p_dec, block_t *p_block)
-{
- decoder_sys_t *p_sys = p_dec->p_sys;
- block_t *p_out = NULL;
-
- if (p_block == NULL) /* No Drain */
- return VLC_SUCCESS;//VLCDEC_SUCCESS
+#if (LIBVLC_VERSION_MAJOR < 3)
+ *pp_block = NULL;
+#endif
if (p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED))
{
+#if (LIBVLC_VERSION_MAJOR >= 3)
Flush (p_dec);
if (p_block->i_flags & BLOCK_FLAG_CORRUPTED)
{
block_Release(p_block);
- return VLC_SUCCESS;//VLCDEC_SUCCESS
+ return VLCDEC_SUCCESS;
}
+#else
+ Flush (p_dec);
+#endif
}
- if (p_block->i_pts > VLC_TS_INVALID && !date_Get (&p_sys->end_date))
+ if (p_block->i_pts > VLC_TS_INVALID
+ && !date_Get (&p_sys->end_date))
date_Set (&p_sys->end_date, p_block->i_pts);
else
if (p_block->i_pts < date_Get (&p_sys->end_date))
@@ -360,21 +296,30 @@ static int DecodeBlock (decoder_t *p_dec, block_t *p_block)
if (samples == 0)
goto drop;
+#if (LIBVLC_VERSION_MAJOR >= 3)
if (decoder_UpdateAudioFormat (p_dec))
goto drop;
+#endif
+
p_out = decoder_NewAudioBuffer (p_dec, samples);
if (p_out == NULL)
goto drop;
p_out->i_pts = date_Get (&p_sys->end_date );
- p_out->i_length = date_Increment (&p_sys->end_date, samples)
- - p_out->i_pts;
- adl_generate(p_sys->synth, samples * 2, p_out->p_buffer);
+ samples = adl_generateFormat(p_sys->synth, (int)samples * 2,
+ (ADL_UInt8*)p_out->p_buffer,
+ (ADL_UInt8*)(p_out->p_buffer + g_output_format.containerSize),
+ &g_output_format);
+ samples /= 2;
+ p_out->i_length = date_Increment (&p_sys->end_date, samples) - p_out->i_pts;
+
drop:
block_Release (p_block);
+#if (LIBVLC_VERSION_MAJOR >= 3)
if (p_out != NULL)
decoder_QueueAudio (p_dec, p_out);
- return VLC_SUCCESS;//VLCDEC_SUCCESS
-}
-
+ return VLCDEC_SUCCESS;
+#else
+ return p_out;
#endif
+}