diff --git a/Kconfig.board b/Kconfig.board index a4cf893a6..d737b67da 100755 --- a/Kconfig.board +++ b/Kconfig.board @@ -71,6 +71,7 @@ config GEN_IMG_SCRIPT generate image scripte; default "board/common/gen_image_script/gen_image.sh" config RTT_CONSOLE_ID + depends on SUPPORT_RTSMART int "RTT console id" default 3 diff --git a/Makefile b/Makefile index 78b570801..c9c63e901 100755 --- a/Makefile +++ b/Makefile @@ -112,8 +112,8 @@ prepare_sourcecode:prepare_toolchain #ai @echo "download nncase sdk" @rm -rf src/big/utils/; rm -rf src/big/ai; - @wget -q --show-progress $(DOWNLOAD_URL)/downloads/kmodel/kmodel_v2.4.0.tgz -O - | tar -xzC src/big/ - @wget -q --show-progress $(DOWNLOAD_URL)/downloads/nncase/nncase_k230_v2.4.0.tgz -O - | tar -xzC src/big/ + @wget -q --show-progress $(DOWNLOAD_URL)/downloads/kmodel/kmodel_v2.5.1.tgz -O - | tar -xzC src/big/ + @wget -q --show-progress $(DOWNLOAD_URL)/downloads/nncase/nncase_k230_v2.5.1.tgz -O - | tar -xzC src/big/ #big utils @echo "download big utils" @@ -138,6 +138,15 @@ prepare_sourcecode:prepare_toolchain @wget -q --show-progress $(DOWNLOAD_URL)/downloads/dl/dl.tar.gz -O - | tar -xzC src/little/buildroot-ext/ @touch src/.src_fetched + +#dictionary_pen + @if [ "k230_evb_usiplpddr4_dictionary_pen_defconfig" == "$${CONF}" ] ; then \ + echo "download dictionary_pen" ; \ + wget -q --show-progress $(DOWNLOAD_URL)/downloads/dictionary_pen/cidianbi_kmodel_v2.5.1.tar.gz -O - | tar -xzC src/reference/business_poc/dictionary_pen_poc/ ; \ + cp src/reference/business_poc/dictionary_pen_poc/cidianbi_kmodel_v2.5.1/include src/reference/business_poc/dictionary_pen_poc/ -rf ; \ + fi; + + check_toolchain: @if [ ! -f $(CONFIG_TOOLCHAIN_PATH_LINUX)/$(CONFIG_TOOLCHAIN_PREFIX_LINUX)gcc ] || \ [ ! -f $(CONFIG_TOOLCHAIN_PATH_RTT)/$(CONFIG_TOOLCHAIN_PREFIX_RTT)gcc ]; then \ @@ -255,6 +264,15 @@ peephole:check_src make && make install; rm ./* -rf; \ cd -; +.PHONY: dictionary_pen +dictionary_pen:check_src + @export PATH=$(RTT_EXEC_PATH):$(PATH); \ + export RTSMART_SRC_DIR=$(K230_SDK_ROOT)/$(RT-SMART_SRC_PATH); \ + cd $(K230_SDK_ROOT)/src/reference/business_poc/dictionary_pen_poc; \ + mkdir -p build; \ + bash build.sh ; + + .PHONY: cdk-kernel cdk-kernel: linux @export PATH=$(RTT_EXEC_PATH):$(LINUX_EXEC_PATH):$(PATH);export RTSMART_SRC_DIR=$(K230_SDK_ROOT)/$(RT-SMART_SRC_PATH);export LINUX_BUILD_DIR=$(LINUX_BUILD_DIR); \ diff --git a/README.md b/README.md index cfef4d3a5..e5735d31e 100755 --- a/README.md +++ b/README.md @@ -143,7 +143,7 @@ make prepare_sourcecode 1. 根据不同开发板或软件功能,选择不同的配置config进行编译,编译命令格式:`make CONF=xxx`,如: > - 编译K230-USIP-LP3-EVB板子镜像,执行`make CONF=k230_evb_defconfig` 命令开始编译 - > - 编译CanMV-K230板子的镜像,执行 `make CONF=CONF=k230_canmv_defconfig` 命令开始编译 + > - 编译CanMV-K230板子的镜像,执行 `make CONF=k230_canmv_defconfig` 命令开始编译 > - 外部目录中自动下载的toolchain会映射至docker镜像中的`/opt/toolchain/`目录下。 > - 默认参数`-u root`指定docker以root用户执行,k230_sdk无需root权限即可编译 diff --git a/board/common/dev_firmware/ap6212a/config.txt b/board/common/dev_firmware/ap6212a/config.txt new file mode 100755 index 000000000..3e49931b0 --- /dev/null +++ b/board/common/dev_firmware/ap6212a/config.txt @@ -0,0 +1 @@ +android_msg_level=1 \ No newline at end of file diff --git a/board/common/dev_firmware/ap6256/config.txt b/board/common/dev_firmware/ap6256/config.txt new file mode 100755 index 000000000..3e49931b0 --- /dev/null +++ b/board/common/dev_firmware/ap6256/config.txt @@ -0,0 +1 @@ +android_msg_level=1 \ No newline at end of file diff --git a/board/common/gen_image_cfg/genimage-sdcard-dictionary-pen.cfg b/board/common/gen_image_cfg/genimage-sdcard-dictionary-pen.cfg new file mode 100755 index 000000000..41b7b825e --- /dev/null +++ b/board/common/gen_image_cfg/genimage-sdcard-dictionary-pen.cfg @@ -0,0 +1,73 @@ +image app.vfat { + vfat { + files = { + "big-core/app", + } + } + # empty =true + size = 1024M +} + +image sysimage-sdcard.img { + hdimage { + gpt = "true" + } + + partition uboot_spl_1 { + #512k@1M 0x400@0x800 + in-partition-table = false + offset = 1M + image = "little-core/uboot/fn_u-boot-spl.bin" + } + partition uboot_spl_2 { + #512k@1.5M 0x800@0xc00 + in-partition-table = false + offset = 0x180000 + image = "little-core/uboot/fn_u-boot-spl.bin" + } + partition uboot_env { + in-partition-table = false + offset = 0x1e0000 + image = "little-core/uboot/env.env" + size = 0x20000 + } + partition uboot { + #1.5m@2M 0xc00@0x1000 + in-partition-table = false + offset = 2M + image = "little-core/uboot/fn_ug_u-boot.bin" + } + # partition env { + # #128k@3.5M 0x800@0x1c00 + # in-partition-table = false + # offset = 0x380000 + # #image = "../little/uboot/u-boot.img" + # } + + partition rtt { + #20M@10M 0x800@0x800 + offset = 10M + image = "big-core/rtt_system.bin" + size = 20M + } + + partition linux { + #50M@30M 0x800@0x800 + offset = 30M + image = "little-core/linux_system.bin" + size = 50M + } + + partition rootfs { + offset = 128M + partition-type = 0x83 + image = "little-core/rootfs.ext4" + } + + partition fat32appfs { + #offset = 168M + partition-type = 0xc + # size = 32M + image = "app.vfat" + } +} \ No newline at end of file diff --git a/board/common/gen_image_script/gen_image_comm_func.sh b/board/common/gen_image_script/gen_image_comm_func.sh index c1a3fc381..750940280 100755 --- a/board/common/gen_image_script/gen_image_comm_func.sh +++ b/board/common/gen_image_script/gen_image_comm_func.sh @@ -2,6 +2,29 @@ source ${K230_SDK_ROOT}/.config source ${K230_SDK_ROOT}/.last_conf +gz_file_add_ver() +{ + [ $# -lt 1 ] && return + local f="$1" + + local sdk_ver="v0.0.0"; + local nncase_ver="0.0.0"; + + local sdk_ver_file="${K230_SDK_ROOT}/board/common/post_copy_rootfs/etc/version/release_version" + local nncase_ver_file="${K230_SDK_ROOT}/src/big/nncase/riscv64/nncase/include/nncase/version.h" + + + + + cat ${sdk_ver_file} | grep v | cut -d- -f 1 > /dev/null && \ + sdk_ver=$(cat ${sdk_ver_file} | grep v | cut -d- -f 1) + + cat ${nncase_ver_file} | grep NNCASE_VERSION -w | cut -d\" -f 2 > /dev/null && \ + nncase_ver=$(cat ${nncase_ver_file} | grep NNCASE_VERSION -w | cut -d\" -f 2) + + cp $f ${CONFIG_BOARD_NAME}_$(echo "$f" | sed -nE "s#[^-]*-([^\.]*).*#\1#p")_${sdk_ver}_nncase_v${nncase_ver}.img.gz; +} + #依赖 BUILD_DIR,K230_SDK_ROOT copye_file_to_images() @@ -271,6 +294,7 @@ gen_image() rm -rf "${GENIMAGE_TMP}" gzip -k -f ${image_name} chmod a+rw ${image_name} ${image_name}.gz; + gz_file_add_ver ${image_name}.gz } gen_image_spinor_proc_ai_mode() diff --git a/board/k230_evb_dictionary_pen/gen_dictionary_pen_device_image_sd.sh b/board/k230_evb_dictionary_pen/gen_dictionary_pen_device_image_sd.sh new file mode 100755 index 000000000..b0719d92f --- /dev/null +++ b/board/k230_evb_dictionary_pen/gen_dictionary_pen_device_image_sd.sh @@ -0,0 +1,98 @@ +#!/bin/bash + +source ${K230_SDK_ROOT}/board/common/gen_image_script/gen_image_comm_func.sh + + +env_dir="${K230_SDK_ROOT}/board/common/env" + +GENIMAGE_CFG_DIR="${K230_SDK_ROOT}/board/common/gen_image_cfg" +GENIMAGE_CFG_SD="${GENIMAGE_CFG_DIR}/genimage-sdcard-dictionary-pen.cfg" +GENIMAGE_CFG_SPI_NOR="${GENIMAGE_CFG_DIR}/genimage-spinor.cfg" +GENIMAGE_CFG_SPI_NAND="${GENIMAGE_CFG_DIR}/genimage-spinand.cfg" +GENIMAGE_CFG_SD_REMOTE="${GENIMAGE_CFG_DIR}/genimage-sdcard_remote.cfg" + +cfg_data_file_path="${GENIMAGE_CFG_DIR}/data" +quick_boot_cfg_data_file="${GENIMAGE_CFG_DIR}/data/quick_boot.bin" +face_database_data_file="${GENIMAGE_CFG_DIR}/data/face_data.bin" +sensor_cfg_data_file="${GENIMAGE_CFG_DIR}/data/sensor_cfg.bin" +ai_mode_data_file="${BUILD_DIR}/images/big-core/ai_mode.bin" #"${GENIMAGE_CFG_DIR}/data/ai_mode.bin" +speckle_data_file="${GENIMAGE_CFG_DIR}/data/speckle.bin" +rtapp_data_file="${BUILD_DIR}/images/big-core/fastboot_app.elf" + + + + +gen_dictionary_pen_device_app() +{ + #crop little-core + # rm -rf lib/modules/; + # rm -rf lib/libstdc++*; + #rm -rf lib/modules/ + #rm -rf usr/bin/fio; + #rm -rf usr/bin/lvgl_demo_widgets; + #rm -rf usr/bin/ssh* + #find mnt/ -type f -not -name k_ipcm.ko -not -name sharefs | xargs rm -rf ; + # rm -rf app/; + rm -rf lib/tuning-server; + #rm -rf usr/bin/stress-ng bin/bash usr/sbin/sshd usr/bin/trace-cmd usr/bin/lvgl_demo_widgets; + #find . -name *.ko | xargs rm -rf ; + + # fakeroot -- ${K230_SDK_ROOT}/tools/mkcpio-rootfs.sh; + + #cp ${K230_SDK_ROOT}/src/reference/dictionary_pen_poc/cidianbi_kmodel_v2.5.1/include ${K230_SDK_ROOT}/src/reference/dictionary_pen_poc/ + #rtapp and ai mode + cd ${K230_SDK_ROOT}; make dictionary_pen; + #creat dictionary_pen dir + mkdir -p ${BUILD_DIR}/images/big-core/app/dictionary_pen/ + cp ${K230_SDK_ROOT}/src/reference/business_poc/dictionary_pen_poc/cidianbi_kmodel_v2.5.1/* ${BUILD_DIR}/images/big-core/app/dictionary_pen/ -rf + cp ${K230_SDK_ROOT}/src/reference/business_poc/dictionary_pen_poc/include ${BUILD_DIR}/images/big-core/app/dictionary_pen/ -rf + cp ${K230_SDK_ROOT}/src/reference/business_poc/dictionary_pen_poc/build/dictionary_pen.elf ${BUILD_DIR}/images/big-core/app/dictionary_pen/ -rf + + # crop big-core + # find . -type f -not -name fastboot_app.elf -not -name init.sh -not -name doorbell.g711u -not -name person_detect_yolov5n.kmodel -not -name imx335-1920x1080_auto.json* -not -name imx335-1920x1080.bin -not -name imx335-1920x1080_manual.json* -not -name imx335-1920x1080.xml* -not -name imx335-2592x1944_auto.json* -not -name imx335-2592x1944.bin -not -name imx335-2592x1944_manual.json* -not -name imx335-2592x1944.xml* | xargs rm -rf + + # rm ${BUILD_DIR}/images/big-core/app/* -rf; + + cd ${RTSMART_SRC_DIR}/userapps/; python3 ../tools/mkromfs.py ${BUILD_DIR}/images/big-core/root/ ${RTSMART_SRC_DIR}/kernel/bsp/maix3/applications/romfs.c; + cd ${K230_SDK_ROOT};make rtt_update_romfs; + + cp ${BUILD_DIR}/big/rt-smart/rtthread.* ${BUILD_DIR}/images/big-core/; +} + +copye_file_to_images; +gen_dictionary_pen_device_app; +gen_version; +gen_uboot_bin; +gen_linux_bin; +gen_final_ext2; +gen_rtt_bin; +gen_env_bin; +copy_app; + +if [ "${CONFIG_REMOTE_TEST_PLATFORM}" = "y" ] ; then + gen_image ${GENIMAGE_CFG_SD_REMOTE} sysimage-sdcard.img +else + gen_image ${GENIMAGE_CFG_SD} sysimage-sdcard.img +fi + +if [ "${CONFIG_GEN_SECURITY_IMG}" = "y" ] ; then + gen_image ${GENIMAGE_CFG_SD_AES} sysimage-sdcard_aes.img + gen_image ${GENIMAGE_CFG_SD_SM} sysimage-sdcard_sm.img +fi + +# gen_image_spinor +# gen_image_spinand; + + + +cd ${BUILD_DIR}/images/ +rm -rf sysimage-sdcard_aes.img sysimage-sdcard_sm.img *.vfat + + + + + + + + + diff --git a/board/k230_evb_doorlock/gen_image_script/gen_doorlock_image.sh b/board/k230_evb_doorlock/gen_image_script/gen_doorlock_image.sh index 59b6da0b1..902985174 100755 --- a/board/k230_evb_doorlock/gen_image_script/gen_doorlock_image.sh +++ b/board/k230_evb_doorlock/gen_image_script/gen_doorlock_image.sh @@ -48,7 +48,7 @@ shrink_rootfs() rm -rf usr/bin/k230_timer_demo rm -rf usr/bin/gpio_keys_demo rm -rf lib/modules/5.10.4+/kernel/drivers/gpu/ - rm -rf /lib/modules/5.10.4+/kernel/drivers/net/wireless/aich/aiw4211lv10/aiw4211lv10.ko + find mnt/ -type f -not -name k_ipcm.ko -not -name sharefs | xargs rm -rf ; # rm -rf app/; rm -rf lib/tuning-server; @@ -82,16 +82,16 @@ gen_env_bin; copy_app; -if [ "${CONFIG_REMOTE_TEST_PLATFORM}" = "y" ] ; then - gen_image ${GENIMAGE_CFG_SD_REMOTE} sysimage-sdcard.img -else - gen_image ${GENIMAGE_CFG_SD} sysimage-sdcard.img -fi +# if [ "${CONFIG_REMOTE_TEST_PLATFORM}" = "y" ] ; then +# gen_image ${GENIMAGE_CFG_SD_REMOTE} sysimage-sdcard.img +# else +# gen_image ${GENIMAGE_CFG_SD} sysimage-sdcard.img +# fi -if [ "${CONFIG_GEN_SECURITY_IMG}" = "y" ] ; then - gen_image ${GENIMAGE_CFG_SD_AES} sysimage-sdcard_aes.img - gen_image ${GENIMAGE_CFG_SD_SM} sysimage-sdcard_sm.img -fi +# if [ "${CONFIG_GEN_SECURITY_IMG}" = "y" ] ; then +# gen_image ${GENIMAGE_CFG_SD_AES} sysimage-sdcard_aes.img +# gen_image ${GENIMAGE_CFG_SD_SM} sysimage-sdcard_sm.img +# fi if [ "${CONFIG_SPI_NOR}" = "y" ]; then cd ${BUILD_DIR}/;rm -rf images_bak;cp images images_bak -r; diff --git a/board/k230_evb_doorlock/gen_image_script/gen_doorlock_ov9286_image.sh b/board/k230_evb_doorlock/gen_image_script/gen_doorlock_ov9286_image.sh index f7a69de8b..8c3d490cb 100755 --- a/board/k230_evb_doorlock/gen_image_script/gen_doorlock_ov9286_image.sh +++ b/board/k230_evb_doorlock/gen_image_script/gen_doorlock_ov9286_image.sh @@ -88,16 +88,16 @@ gen_env_bin; copy_app; -if [ "${CONFIG_REMOTE_TEST_PLATFORM}" = "y" ] ; then - gen_image ${GENIMAGE_CFG_SD_REMOTE} sysimage-sdcard.img -else - gen_image ${GENIMAGE_CFG_SD} sysimage-sdcard.img -fi - -if [ "${CONFIG_GEN_SECURITY_IMG}" = "y" ] ; then - gen_image ${GENIMAGE_CFG_SD_AES} sysimage-sdcard_aes.img - gen_image ${GENIMAGE_CFG_SD_SM} sysimage-sdcard_sm.img -fi +# if [ "${CONFIG_REMOTE_TEST_PLATFORM}" = "y" ] ; then +# gen_image ${GENIMAGE_CFG_SD_REMOTE} sysimage-sdcard.img +# else +# gen_image ${GENIMAGE_CFG_SD} sysimage-sdcard.img +# fi + +# if [ "${CONFIG_GEN_SECURITY_IMG}" = "y" ] ; then +# gen_image ${GENIMAGE_CFG_SD_AES} sysimage-sdcard_aes.img +# gen_image ${GENIMAGE_CFG_SD_SM} sysimage-sdcard_sm.img +# fi if [ "${CONFIG_SPI_NOR}" = "y" ] ;then cd ${BUILD_DIR}/;rm -rf images_bak;cp images images_bak -r; diff --git a/board/k230_evb_peephole/gen_peephole_device_image_flash.sh b/board/k230_evb_peephole/gen_peephole_device_image_flash.sh new file mode 100755 index 000000000..8170e3428 --- /dev/null +++ b/board/k230_evb_peephole/gen_peephole_device_image_flash.sh @@ -0,0 +1,96 @@ +#!/bin/bash + +source ${K230_SDK_ROOT}/board/common/gen_image_script/gen_image_comm_func.sh + + +env_dir="${K230_SDK_ROOT}/board/common/env" + +GENIMAGE_CFG_DIR="${K230_SDK_ROOT}/board/common/gen_image_cfg" +GENIMAGE_CFG_SD="${GENIMAGE_CFG_DIR}/genimage-sdcard.cfg" +GENIMAGE_CFG_SD_AES="${GENIMAGE_CFG_DIR}/genimage-sdcard_aes.cfg" +GENIMAGE_CFG_SD_SM="${GENIMAGE_CFG_DIR}/genimage-sdcard_sm.cfg" +#GENIMAGE_CFG_SD_DDR4="${GENIMAGE_CFG_DIR}/genimage-sdcard_ddr4.cfg" +GENIMAGE_CFG_SPI_NOR="${GENIMAGE_CFG_DIR}/genimage-spinor.cfg" +GENIMAGE_CFG_SPI_NAND="${GENIMAGE_CFG_DIR}/genimage-spinand.cfg" +GENIMAGE_CFG_SD_REMOTE="${GENIMAGE_CFG_DIR}/genimage-sdcard_remote.cfg" + +cfg_data_file_path="${GENIMAGE_CFG_DIR}/data" +quick_boot_cfg_data_file="${GENIMAGE_CFG_DIR}/data/quick_boot.bin" +face_database_data_file="${GENIMAGE_CFG_DIR}/data/face_data.bin" +sensor_cfg_data_file="${GENIMAGE_CFG_DIR}/data/sensor_cfg.bin" +ai_mode_data_file="${BUILD_DIR}/images/big-core/ai_mode.bin" #"${GENIMAGE_CFG_DIR}/data/ai_mode.bin" +speckle_data_file="${GENIMAGE_CFG_DIR}/data/speckle.bin" +rtapp_data_file="${BUILD_DIR}/images/big-core/fastboot_app.elf" + +shrink_rootfs() +{ + # cd ${BUILD_DIR}/images/little-core/;fakeroot cp -r rootfs rootfs_mmc_sd; + # cd ${BUILD_DIR}/images/big-core/;fackroot cp -r root root_mmc_sd; + + cd ${K230_SDK_ROOT}; make peephole; + + #С���ļ�ϵͳ�ü��޸ģ� + cp ${K230_SDK_ROOT}/board/k230_evb_peephole/peephole_device_flash_rcS ${BUILD_DIR}/images/little-core/rootfs/etc/init.d/rcS; + cp ${K230_SDK_ROOT}/board/k230_evb_peephole/peephole_device_flash_rcK ${BUILD_DIR}/images/little-core/rootfs/etc/init.d/rcK; + cp ${K230_SDK_ROOT}/board/k230_evb_peephole/interfaces ${BUILD_DIR}/images/little-core/rootfs/etc/network/interfaces; + # cp ${K230_SDK_ROOT}/board/k230_evb_peephole/inittab ${BUILD_DIR}/images/little-core/rootfs/etc/inittab; + + cd ${BUILD_DIR}/images/little-core/rootfs/; + rm -rf usr/games; + rm -rf usr/doc; + rm -rf usr/man; + find usr/share -type f -not -name fonts | xargs rm -rf ; + rm -rf usr/bin/fio; + rm -rf usr/bin/lvgl_demo_widgets; + rm -rf usr/bin/ssh* + rm -rf usr/bin/sftp + rm -rf usr/bin/lat* + rm -rf usr/bin/hostapd_cli + rm -rf usr/bin/*test* + rm -rf usr/bin/k230_timer_demo + rm -rf usr/bin/gpio_keys_demo + rm -rf lib/modules/5.10.4/kernel/drivers/gpu/ + rm -rf etc/ssh + find lib/modules/5.10.4/kernel/drivers/net/usb/ -type f -not -name r8152.ko -not -name usbnet.ko | xargs rm -rf ; + rm -rf lib/modules/5.10.4/kernel/drivers/net/wireless/ + find mnt/ -type f -not -name k_ipcm.ko -not -name sharefs | xargs rm -rf ; + rm -rf app/tuning-server; + rm -rf lib/tuning-server; + rm -rf usr/bin/stress-ng bin/bash usr/sbin/sshd usr/bin/trace-cmd usr/bin/lvgl_demo_widgets; + + #����ļ�ϵͳ�ü��޸ģ� + cd ${BUILD_DIR}/images/big-core/root/bin/; + cp ${K230_SDK_ROOT}/src/reference/business_poc/peephole/big/out/peephole_dev.elf fastboot_app.elf; + /opt/toolchain/riscv64-linux-musleabi_for_x86_64-pc-linux-gnu/bin/riscv64-unknown-linux-musl-strip fastboot_app.elf; + + echo "/bin/fastboot_app.elf &" > init.sh + cp ${K230_SDK_ROOT}/src/big/kmodel/peephole/*.kmodel .; + find . -type f -not -name fastboot_app.elf -not -name init.sh -not -name imx335-2592x1944.bin \ + -not -name person_detect_yolov5n.kmodel | xargs rm -rf ; + cp ${K230_SDK_ROOT}/src/reference/business_poc/peephole/big/app/data/doorbell.g711u .; + + #���÷������� + if [ -f "${K230_SDK_ROOT}/src/big/mpp/userapps/src/vicap/src/isp/sdk/t_frameworks/t_database_c/calibration_data/sensor_cfg.bin" ]; then + mkdir -p ${cfg_data_file_path}/; + cp ${K230_SDK_ROOT}/src/big/mpp/userapps/src/vicap/src/isp/sdk/t_frameworks/t_database_c/calibration_data/sensor_cfg.bin ${cfg_data_file_path}/sensor_cfg.bin + fi +} + +copye_file_to_images; +gen_version; +gen_uboot_bin; +gen_linux_bin; +gen_final_ext2; +gen_rtt_bin; +gen_env_bin; +copy_app; + +if [ "${CONFIG_SPI_NOR}" = "y" ]; then + cd ${BUILD_DIR}/;rm -rf images_bak;cp images images_bak -r; + shrink_rootfs; + gen_image_spinor; + cd ${BUILD_DIR}/;rm -rf images_spinor;mv images images_spinor; mv images_bak images; cp images_spinor/sysimage-spinor32m*.img images; +fi + +# cd ${BUILD_DIR}/images/ +# rm -rf sysimage-sdcard_aes.img sysimage-sdcard_sm.img *.vfat diff --git a/board/k230_evb_peephole/gen_peephole_device_image.sh b/board/k230_evb_peephole/gen_peephole_device_image_sd.sh similarity index 95% rename from board/k230_evb_peephole/gen_peephole_device_image.sh rename to board/k230_evb_peephole/gen_peephole_device_image_sd.sh index e5bc97eda..ce4d577d2 100755 --- a/board/k230_evb_peephole/gen_peephole_device_image.sh +++ b/board/k230_evb_peephole/gen_peephole_device_image_sd.sh @@ -27,8 +27,8 @@ rtapp_data_file="${BUILD_DIR}/images/big-core/fastboot_app.elf" gen_peephole_device_app() { - cp ${K230_SDK_ROOT}/board/k230_evb_peephole/peephole_device_rcS ${BUILD_DIR}/images/little-core/rootfs/etc/init.d/rcS; - # cp ${K230_SDK_ROOT}/board/k230_evb_peephole/interface ${BUILD_DIR}/images/little-core/rootfs/etc/network + cp ${K230_SDK_ROOT}/board/k230_evb_peephole/peephole_device_sd_rcS ${BUILD_DIR}/images/little-core/rootfs/etc/init.d/rcS; + cp ${K230_SDK_ROOT}/board/k230_evb_peephole/interfaces ${BUILD_DIR}/images/little-core/rootfs/etc/network/interfaces; cd ${BUILD_DIR}/images/little-core/rootfs/; #crop little-core diff --git a/board/k230_evb_peephole/gen_peephole_phone_image.sh b/board/k230_evb_peephole/gen_peephole_phone_image.sh index 712fc32be..edfd17076 100755 --- a/board/k230_evb_peephole/gen_peephole_phone_image.sh +++ b/board/k230_evb_peephole/gen_peephole_phone_image.sh @@ -28,7 +28,7 @@ rtapp_data_file="${BUILD_DIR}/images/big-core/fastboot_app.elf" gen_peephole_phone_app() { cp ${K230_SDK_ROOT}/board/k230_evb_peephole/peephole_phone_rcS ${BUILD_DIR}/images/little-core/rootfs/etc/init.d/rcS; - cp ${K230_SDK_ROOT}/board/k230_evb_peephole/interface ${BUILD_DIR}/images/little-core/rootfs/etc/network + cp ${K230_SDK_ROOT}/board/k230_evb_peephole/interfaces_phone ${BUILD_DIR}/images/little-core/rootfs/etc/network/interfaces cp ${K230_SDK_ROOT}/src/common/cdk/user/out/big/sample_sys_init.elf ${BUILD_DIR}/images/big-core/root/bin/; #crop little-core diff --git a/board/k230_evb_peephole/interfaces b/board/k230_evb_peephole/interfaces index 9a99794be..7c97a1a2f 100644 --- a/board/k230_evb_peephole/interfaces +++ b/board/k230_evb_peephole/interfaces @@ -3,4 +3,10 @@ auto lo iface lo inet loopback +auto eth0 +# iface eth0 inet dhcp +iface eth0 inet static + address 10.99.231.10 + netmask 255.255.255.0 + gateway 10.99.231.1 diff --git a/board/k230_evb_peephole/interfaces_phone b/board/k230_evb_peephole/interfaces_phone new file mode 100644 index 000000000..1f400c959 --- /dev/null +++ b/board/k230_evb_peephole/interfaces_phone @@ -0,0 +1,12 @@ +# interface file auto-generated by buildroot + +auto lo +iface lo inet loopback + +auto eth0 +# iface eth0 inet dhcp +iface eth0 inet static + address 10.99.231.11 + netmask 255.255.255.0 + gateway 10.99.231.1 + diff --git a/board/k230_evb_peephole/peephole_device_flash_rcK b/board/k230_evb_peephole/peephole_device_flash_rcK new file mode 100755 index 000000000..804a869a7 --- /dev/null +++ b/board/k230_evb_peephole/peephole_device_flash_rcK @@ -0,0 +1,38 @@ +#!/bin/sh + + +# Stop all init scripts in /etc/init.d +# executing them in reversed numerical order. +# + +for i in $(ls -r /etc/init.d/S??*) ;do + + # Ignore dangling symlinks (if any). + [ ! -f "$i" ] && continue + + case "$i" in + *.sh) + # Source shell script for speed. + ( + trap - INT QUIT TSTP + set stop + . $i + ) + ;; + *) + # No sh extension, so fork subprocess. + $i stop + ;; + esac +done + +rmmod r8152 +umount /sharefs +rmmod sdhci-of-kendryte +rmmod sdhci-pltfm +rmmod sdhci +rmmod mmc_block +rmmod mmc_core + +killall sharefs +rmmod k_ipcm diff --git a/board/k230_evb_peephole/peephole_device_flash_rcS b/board/k230_evb_peephole/peephole_device_flash_rcS new file mode 100755 index 000000000..89b387aca --- /dev/null +++ b/board/k230_evb_peephole/peephole_device_flash_rcS @@ -0,0 +1,52 @@ +#!/bin/sh + + +# Start all init scripts in /etc/init.d +# executing them in numerical order. +# + +# echo "before install k_ipcm ..." +# /app/peephole_device/peephole_device -t +cd /mnt +insmod k_ipcm.ko +cd - +# echo "after install k_ipcm ..." +# /app/peephole_device/peephole_device -t + +# for i in /etc/init.d/S??* ;do + + # Ignore dangling symlinks (if any). +# [ ! -f "$i" ] && continue + +# case "$i" in +# *.sh) +# # Source shell script for speed. +# ( +# trap - INT QUIT TSTP +# set start +# . $i +# ) +# ;; +# *) +# # No sh extension, so fork subprocess. +# $i start +# ;; +# esac +# done + +/etc/init.d/S01syslogd start +/etc/init.d/S02klogd start +# /etc/init.d/S10mdev start +/etc/init.d/S20urandom start + +cat /etc/version/release_version + +cd /mnt +./sharefs & +cd - + +insmod /lib/modules/5.10.4/kernel/drivers/net/usb/r8152.ko && /etc/init.d/S40network start && /etc/init.d/S50telnet start & + +# TODO, FIXME, pathname hardcoded at the moment +# echo "start app ..." +nice -n -10 /app/peephole_device/peephole_device -s -m /sharefs/DCIM/video -j /sharefs/DCIM/snapshot & diff --git a/board/k230_evb_peephole/peephole_device_rcS b/board/k230_evb_peephole/peephole_device_sd_rcS old mode 100644 new mode 100755 similarity index 100% rename from board/k230_evb_peephole/peephole_device_rcS rename to board/k230_evb_peephole/peephole_device_sd_rcS diff --git a/board/k230_evb_peephole/peephole_phone_rcS b/board/k230_evb_peephole/peephole_phone_rcS old mode 100644 new mode 100755 index a4b29497d..9c2505705 --- a/board/k230_evb_peephole/peephole_phone_rcS +++ b/board/k230_evb_peephole/peephole_phone_rcS @@ -17,10 +17,6 @@ fi # ./sharefs & # cd - -ifconfig eth0 10.99.231.11 - -/app/peephole_phone/peephole_phone 10.99.231.10 & - for i in /etc/init.d/S??* ;do # Ignore dangling symlinks (if any). @@ -48,6 +44,8 @@ cat /etc/version/release_version # fi; # fi -auto eth0 +# auto eth0 # iface eth0 inet dhcp ifconfig eth0 10.99.231.11 +/app/peephole_phone/peephole_phone 10.99.231.10 & + diff --git a/board/k230_evb_peephole/sshd_config b/board/k230_evb_peephole/sshd_config new file mode 100644 index 000000000..809c0692b --- /dev/null +++ b/board/k230_evb_peephole/sshd_config @@ -0,0 +1,119 @@ +# $OpenBSD: sshd_config,v 1.103 2018/04/09 20:41:22 tj Exp $ + +# This is the sshd server system-wide configuration file. See +# sshd_config(5) for more information. + +# This sshd was compiled with PATH=/bin:/sbin:/usr/bin:/usr/sbin + +# The strategy used for options in the default sshd_config shipped with +# OpenSSH is to specify options with their default value where +# possible, but leave them commented. Uncommented options override the +# default value. + +#Port 22 +#AddressFamily any +#ListenAddress 0.0.0.0 +#ListenAddress :: + +#HostKey /etc/ssh/ssh_host_rsa_key +#HostKey /etc/ssh/ssh_host_ecdsa_key +#HostKey /etc/ssh/ssh_host_ed25519_key + +# Ciphers and keying +#RekeyLimit default none + +# Logging +#SyslogFacility AUTH +#LogLevel INFO + +# Authentication: + +PermitRootLogin yes +PermitEmptyPasswords yes + +#LoginGraceTime 2m +#PermitRootLogin prohibit-password +#StrictModes yes +#MaxAuthTries 6 +#MaxSessions 10 + +#PubkeyAuthentication yes + +# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2 +# but this is overridden so installations will only check .ssh/authorized_keys +AuthorizedKeysFile .ssh/authorized_keys + +#AuthorizedPrincipalsFile none + +#AuthorizedKeysCommand none +#AuthorizedKeysCommandUser nobody + +# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts +#HostbasedAuthentication no +# Change to yes if you don't trust ~/.ssh/known_hosts for +# HostbasedAuthentication +#IgnoreUserKnownHosts no +# Don't read the user's ~/.rhosts and ~/.shosts files +#IgnoreRhosts yes + +# To disable tunneled clear text passwords, change to no here! +#PasswordAuthentication yes +#PermitEmptyPasswords no + +# Change to no to disable s/key passwords +#ChallengeResponseAuthentication yes + +# Kerberos options +#KerberosAuthentication no +#KerberosOrLocalPasswd yes +#KerberosTicketCleanup yes +#KerberosGetAFSToken no + +# GSSAPI options +#GSSAPIAuthentication no +#GSSAPICleanupCredentials yes + +# Set this to 'yes' to enable PAM authentication, account processing, +# and session processing. If this is enabled, PAM authentication will +# be allowed through the ChallengeResponseAuthentication and +# PasswordAuthentication. Depending on your PAM configuration, +# PAM authentication via ChallengeResponseAuthentication may bypass +# the setting of "PermitRootLogin without-password". +# If you just want the PAM account and session checks to run without +# PAM authentication, then enable this but set PasswordAuthentication +# and ChallengeResponseAuthentication to 'no'. +#UsePAM no + +#AllowAgentForwarding yes +#AllowTcpForwarding yes +#GatewayPorts no +#X11Forwarding no +#X11DisplayOffset 10 +#X11UseLocalhost yes +#PermitTTY yes +#PrintMotd yes +#PrintLastLog yes +#TCPKeepAlive yes +#PermitUserEnvironment no +#Compression delayed +#ClientAliveInterval 0 +#ClientAliveCountMax 3 +#UseDNS no +#PidFile /var/run/sshd.pid +#MaxStartups 10:30:100 +#PermitTunnel no +#ChrootDirectory none +#VersionAddendum none + +# no default banner path +#Banner none + +# override default of no subsystems +Subsystem sftp /usr/libexec/sftp-server + +# Example of overriding settings on a per-user basis +#Match User anoncvs +# X11Forwarding no +# AllowTcpForwarding no +# PermitTTY no +# ForceCommand cvs server diff --git a/configs/k230_canmv_defconfig b/configs/k230_canmv_defconfig index 0414eb5b9..5d551b91e 100755 --- a/configs/k230_canmv_defconfig +++ b/configs/k230_canmv_defconfig @@ -18,6 +18,7 @@ CONFIG_LINUX_DEFCONFIG="k230_canmv" CONFIG_LINUX_DTB="k230_canmv" # CONFIG_REMOTE_TEST_PLATFORM is not set CONFIG_GEN_IMG_SCRIPT="board/common/gen_image_script/gen_image.sh" +CONFIG_RTT_CONSOLE_ID=3 # # toolchain configurations @@ -31,26 +32,14 @@ CONFIG_TOOLCHAIN_PATH_LINUX="/opt/toolchain/Xuantie-900-gcc-linux-5.10.4-glibc-x # Memory configuration # CONFIG_MEM_TOTAL_SIZE=0x20000000 -CONFIG_MEM_QUICK_BOOT_CFG_BASE=0x00000000 -CONFIG_MEM_QUICK_BOOT_CFG_SIZE=0x00040000 -CONFIG_MEM_SENSOR_CFG_BASE=0x00040000 -CONFIG_MEM_SENSOR_CFG_SIZE=0x000c0000 CONFIG_MEM_IPCM_BASE=0x00100000 CONFIG_MEM_IPCM_SIZE=0x00100000 CONFIG_MEM_RTT_SYS_BASE=0x00200000 CONFIG_MEM_RTT_SYS_SIZE=0x07E00000 -CONFIG_MEM_LINUX_SYS_BASE=0x08000000 -CONFIG_MEM_LINUX_SYS_SIZE=0x08000000 -CONFIG_MEM_AI_MODEL_BASE=0x1FC00000 -CONFIG_MEM_AI_MODEL_SIZE=0x00400000 -CONFIG_MEM_FACE_DATA_BASE=0x14000000 -CONFIG_MEM_FACE_DATA_SIZE=0x00040000 -CONFIG_MEM_SPECKLE_BASE=0x14040000 -CONFIG_MEM_SPECKLE_SIZE=0x01000000 CONFIG_MEM_MMZ_BASE=0x10000000 CONFIG_MEM_MMZ_SIZE=0x0FC00000 -CONFIG_MEM_RTAPP_BASE=0x18000000 -CONFIG_MEM_RTAPP_SIZE=0x8000000 +CONFIG_MEM_LINUX_SYS_BASE=0x08000000 +CONFIG_MEM_LINUX_SYS_SIZE=0x08000000 CONFIG_MEM_BOUNDARY_RESERVED_SIZE=0x00001000 # @@ -59,38 +48,14 @@ CONFIG_MEM_BOUNDARY_RESERVED_SIZE=0x00001000 # CONFIG_SPI_NOR is not set # CONFIG_SPI_NAND is not set CONFIG_SDCAED=y -# CONFIG_EMMC is not set - -# -# spi nor partion config -# -CONFIG_SPI_NOR_QUICK_BOOT_CFG_BASE=0x200000 -CONFIG_SPI_NOR_QUICK_BOOT_CFG_SIZE=0x80000 -# CONFIG_SPI_NOR_QUICK_BOOT_CFG_SUPPORT_BAKEUP is not set -CONFIG_SPI_NOR_FACE_DB_CFG_BASE=0x280000 -CONFIG_SPI_NOR_FACE_DB_CFG_SIZE=0x80000 -# CONFIG_SPI_NOR_FACE_DB_CFG_SUPPORT_BAKEUP is not set -CONFIG_SPI_NOR_SENSOR_CFG_CFG_BASE=0x300000 -CONFIG_SPI_NOR_SENSOR_CFG_CFG_SIZE=0x40000 -CONFIG_SPI_NOR_AI_MODE_CFG_BASE=0x340000 -CONFIG_SPI_NOR_AI_MODE_CFG_SIZE=0x300000 -CONFIG_SPI_NOR_SPECKLE_CFG_BASE=0x640000 -CONFIG_SPI_NOR_SPECKLE_CFG_SIZE=0x200000 -CONFIG_SPI_NOR_RTTK_BASE=0x840000 -CONFIG_SPI_NOR_RTTK_SIZE=0x1c0000 -CONFIG_SPI_NOR_RTT_APP_BASE=0xa00000 -CONFIG_SPI_NOR_RTT_APP_SIZE=0x5c0000 -CONFIG_SPI_NOR_LK_BASE=0xfc0000 -CONFIG_SPI_NOR_LK_SIZE=0x700000 -CONFIG_SPI_NOR_LR_BASE=0x16c0000 -CONFIG_SPI_NOR_LR_SIZE=0x900000 # # wifi configurations # -# CONFIG_AP6212A is not set -CONFIG_AP6256=y +CONFIG_AP6212A=y +# CONFIG_AP6256 is not set +CONFIG_SUPPORT_RTSMART=y +CONFIG_SUPPORT_LINUX=y +CONFIG_LINUX_RUN_CORE_ID=0 # CONFIG_BUILD_DEBUG_VER is not set CONFIG_BUILD_RELEASE_VER=y -CONFIG_SUPPORT_LINUX=y -CONFIG_SUPPORT_RTSMART=y \ No newline at end of file diff --git a/configs/k230_canmv_only_linux_defconfig b/configs/k230_canmv_only_linux_defconfig new file mode 100755 index 000000000..79e480dd2 --- /dev/null +++ b/configs/k230_canmv_only_linux_defconfig @@ -0,0 +1,55 @@ +# +# Automatically generated file; DO NOT EDIT. +# K230 SDK Configuration +# + +# +# board configuration +# +# CONFIG_BOARD_K230_EVB is not set +# CONFIG_BOARD_K230_FPGA is not set +# CONFIG_BOARD_K230D is not set +CONFIG_BOARD_K230_CANMV=y +CONFIG_BOARD_NAME="k230_evb" +# CONFIG_QUICK_BOOT is not set +# CONFIG_GEN_SECURITY_IMG is not set +CONFIG_UBOOT_DEFCONFIG="k230_canmv" +CONFIG_LINUX_DEFCONFIG="k230_evb_linux_enable_vector" +CONFIG_LINUX_DTB="k230_canmv" +# CONFIG_REMOTE_TEST_PLATFORM is not set +CONFIG_GEN_IMG_SCRIPT="board/k230_evb_only_linux/gen_image.sh" + +# +# toolchain configurations +# +CONFIG_TOOLCHAIN_PREFIX_RTT="riscv64-unknown-linux-musl-" +CONFIG_TOOLCHAIN_PATH_RTT="/opt/toolchain/riscv64-linux-musleabi_for_x86_64-pc-linux-gnu/bin" +CONFIG_TOOLCHAIN_PREFIX_LINUX="riscv64-unknown-linux-gnu-" +CONFIG_TOOLCHAIN_PATH_LINUX="/opt/toolchain/Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.0/bin" + +# +# Memory configuration +# +CONFIG_MEM_TOTAL_SIZE=0x20000000 +CONFIG_MEM_LINUX_SYS_BASE=0x00000000 +CONFIG_MEM_LINUX_SYS_SIZE=0x20000000 +CONFIG_MEM_BOUNDARY_RESERVED_SIZE=0x00001000 + +# +# storage configurations +# +# CONFIG_SPI_NOR is not set +# CONFIG_SPI_NAND is not set +CONFIG_SDCAED=y + +# +# wifi configurations +# +# CONFIG_AP6212A is not set +# CONFIG_AP6256 is not set +# CONFIG_SUPPORT_RTSMART is not set +CONFIG_SUPPORT_LINUX=y +CONFIG_LINUX_RUN_CORE_ID=1 +CONFIG_BUILD_DEBUG_VER=y +# CONFIG_BUILD_RELEASE_VER is not set +CONFIG_DBGLV=8 diff --git a/configs/k230_canmv_only_rtt_defconfig b/configs/k230_canmv_only_rtt_defconfig new file mode 100644 index 000000000..f2c3994ec --- /dev/null +++ b/configs/k230_canmv_only_rtt_defconfig @@ -0,0 +1,63 @@ +# +# Automatically generated file; DO NOT EDIT. +# K230 SDK Configuration +# + +# +# board configuration +# +# CONFIG_BOARD_K230_EVB is not set +# CONFIG_BOARD_K230_FPGA is not set +# CONFIG_BOARD_K230D is not set +CONFIG_BOARD_K230_CANMV=y +CONFIG_BOARD_NAME="k230_evb" +# CONFIG_QUICK_BOOT is not set +# CONFIG_GEN_SECURITY_IMG is not set +CONFIG_UBOOT_DEFCONFIG="k230_canmv" +CONFIG_LINUX_DEFCONFIG="k230_evb" +CONFIG_LINUX_DTB="k230_evb" +# CONFIG_REMOTE_TEST_PLATFORM is not set +CONFIG_GEN_IMG_SCRIPT="board/common/gen_image_script/gen_image.sh" +CONFIG_RTT_CONSOLE_ID=0 + +# +# toolchain configurations +# +CONFIG_TOOLCHAIN_PREFIX_RTT="riscv64-unknown-linux-musl-" +CONFIG_TOOLCHAIN_PATH_RTT="/opt/toolchain/riscv64-linux-musleabi_for_x86_64-pc-linux-gnu/bin" +CONFIG_TOOLCHAIN_PREFIX_LINUX="riscv64-unknown-linux-gnu-" +CONFIG_TOOLCHAIN_PATH_LINUX="/opt/toolchain/Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.0/bin" + +# +# Memory configuration +# +CONFIG_MEM_TOTAL_SIZE=0x20000000 +CONFIG_MEM_IPCM_BASE=0x00100000 +CONFIG_MEM_IPCM_SIZE=0x00100000 +CONFIG_MEM_RTT_SYS_BASE=0x00200000 +CONFIG_MEM_RTT_SYS_SIZE=0x0fe00000 +CONFIG_MEM_MMZ_BASE=0x10000000 +CONFIG_MEM_MMZ_SIZE=0x0FC00000 +CONFIG_MEM_BOUNDARY_RESERVED_SIZE=0x00001000 + +# +# storage configurations +# +# CONFIG_SPI_NOR is not set +# CONFIG_SPI_NAND is not set +CONFIG_SDCAED=y + +# +# spi nor partion config +# +CONFIG_SPI_NOR_RTTK_BASE=0x840000 +CONFIG_SPI_NOR_RTTK_SIZE=0x1c0000 +CONFIG_SPI_NOR_LK_BASE=0xfc0000 +CONFIG_SPI_NOR_LK_SIZE=0x700000 +CONFIG_SPI_NOR_LR_BASE=0x16c0000 +CONFIG_SPI_NOR_LR_SIZE=0x900000 +CONFIG_SUPPORT_RTSMART=y +# CONFIG_SUPPORT_LINUX is not set +CONFIG_BUILD_DEBUG_VER=y +# CONFIG_BUILD_RELEASE_VER is not set +CONFIG_DBGLV=8 diff --git a/configs/k230_evb_doorlock_ov9286_defconfig b/configs/k230_evb_doorlock_ov9286_defconfig index 1ef5ebfe3..5a317e56b 100755 --- a/configs/k230_evb_doorlock_ov9286_defconfig +++ b/configs/k230_evb_doorlock_ov9286_defconfig @@ -36,9 +36,9 @@ CONFIG_MEM_SENSOR_CFG_SIZE=0x000c0000 CONFIG_MEM_IPCM_BASE=0x00100000 CONFIG_MEM_IPCM_SIZE=0x00100000 CONFIG_MEM_RTT_SYS_BASE=0x0200000 -CONFIG_MEM_RTT_SYS_SIZE=0x02400000 -CONFIG_MEM_LINUX_SYS_BASE=0x2600000 -CONFIG_MEM_LINUX_SYS_SIZE=0x28e0000 +CONFIG_MEM_RTT_SYS_SIZE=0x02200000 +CONFIG_MEM_LINUX_SYS_BASE=0x2400000 +CONFIG_MEM_LINUX_SYS_SIZE=0x2ae0000 CONFIG_MEM_AI_MODEL_BASE=0x6200000 CONFIG_MEM_AI_MODEL_SIZE=0x0700000 CONFIG_MEM_FACE_DATA_BASE=0x7fc0000 @@ -81,10 +81,10 @@ CONFIG_SPI_NOR_SPECKLE_CFG_SIZE=0x010000 CONFIG_SPI_NOR_RTTK_BASE=0xa80000 CONFIG_SPI_NOR_RTTK_SIZE=0x270000 CONFIG_SPI_NOR_RTT_APP_BASE=0xcf0000 -CONFIG_SPI_NOR_RTT_APP_SIZE=0x3c0000 -CONFIG_SPI_NOR_LK_BASE=0x10B0000 -CONFIG_SPI_NOR_LK_SIZE=0x410000 -CONFIG_SPI_NOR_LR_BASE=0x14c0000 +CONFIG_SPI_NOR_RTT_APP_SIZE=0x3f0000 +CONFIG_SPI_NOR_LK_BASE=0x10E0000 +CONFIG_SPI_NOR_LK_SIZE=0x420000 +CONFIG_SPI_NOR_LR_BASE=0x1500000 CONFIG_SPI_NOR_LR_SIZE=0xb00000 # CONFIG_BUILD_DEBUG_VER is not set CONFIG_BUILD_RELEASE_VER=y diff --git a/configs/k230_evb_only_linux_defconfig b/configs/k230_evb_only_linux_defconfig index 7ffe6f6f2..e322d5fec 100644 --- a/configs/k230_evb_only_linux_defconfig +++ b/configs/k230_evb_only_linux_defconfig @@ -18,7 +18,6 @@ CONFIG_LINUX_DEFCONFIG="k230_evb_linux_enable_vector" CONFIG_LINUX_DTB="k230_evb" # CONFIG_REMOTE_TEST_PLATFORM is not set CONFIG_GEN_IMG_SCRIPT="board/k230_evb_only_linux/gen_image.sh" -CONFIG_RTT_CONSOLE_ID=3 # # toolchain configurations diff --git a/configs/k230_evb_peephole_device_defconfig b/configs/k230_evb_peephole_device_defconfig index c337b7cd0..42a8b342f 100755 --- a/configs/k230_evb_peephole_device_defconfig +++ b/configs/k230_evb_peephole_device_defconfig @@ -6,14 +6,14 @@ # # board configuration # -CONFIG_BOARD_K230_EVB=y +CONFIG_BOARD_K230_EVB_PEEPHOLE=y # CONFIG_BOARD_K230_FPGA is not set -CONFIG_BOARD_NAME="k230_evb_peephole_device" +CONFIG_BOARD_NAME="k230_evb_peephole_device_flash" CONFIG_QUICK_BOOT=y # CONFIG_GEN_SECURITY_IMG is not set CONFIG_UBOOT_DEFCONFIG="k230_evb" CONFIG_LINUX_DTB="k230_peephole_device" -CONFIG_GEN_IMG_SCRIPT="board/k230_evb_peephole/gen_peephole_device_image.sh" +CONFIG_GEN_IMG_SCRIPT="board/k230_evb_peephole/gen_peephole_device_image_flash.sh" # @@ -28,29 +28,66 @@ CONFIG_TOOLCHAIN_PATH_LINUX="/opt/toolchain/Xuantie-900-gcc-linux-5.10.4-glibc-x # Memory configuration # CONFIG_MEM_TOTAL_SIZE=0x20000000 -CONFIG_MEM_PARAM_BASE=0x00000000 -CONFIG_MEM_PARAM_SIZE=0x00100000 +CONFIG_MEM_QUICK_BOOT_CFG_BASE=0x00000000 +CONFIG_MEM_QUICK_BOOT_CFG_SIZE=0x00040000 +CONFIG_MEM_SENSOR_CFG_BASE=0x00040000 +CONFIG_MEM_SENSOR_CFG_SIZE=0x000C0000 CONFIG_MEM_IPCM_BASE=0x00100000 -CONFIG_MEM_IPCM_SIZE=0x00100000 -CONFIG_MEM_RTT_SYS_BASE=0x00200000 -CONFIG_MEM_RTT_SYS_SIZE=0x07E00000 -CONFIG_MEM_AI_MODEL_BASE=0x1FC00000 -CONFIG_MEM_AI_MODEL_SIZE=0x00400000 +CONFIG_MEM_IPCM_SIZE=0x00200000 +CONFIG_MEM_RTT_SYS_BASE=0x02000000 +CONFIG_MEM_RTT_SYS_SIZE=0x06000000 CONFIG_MEM_LINUX_SYS_BASE=0x08000000 -CONFIG_MEM_LINUX_SYS_SIZE=0x08000000 +CONFIG_MEM_LINUX_SYS_SIZE=0x07E00000 + +CONFIG_MEM_FACE_DATA_BASE=0x0FE00000 +CONFIG_MEM_FACE_DATA_SIZE=0x00040000 +CONFIG_MEM_SPECKLE_BASE=0x0FE40000 +CONFIG_MEM_SPECKLE_SIZE=0x00010000 + CONFIG_MEM_MMZ_BASE=0x10000000 CONFIG_MEM_MMZ_SIZE=0x0FC00000 +CONFIG_MEM_RTAPP_BASE=0x10000000 +CONFIG_MEM_RTAPP_SIZE=0x0FC00000 +CONFIG_MEM_AI_MODEL_BASE=0x1FC00000 +CONFIG_MEM_AI_MODEL_SIZE=0x00400000 + CONFIG_MEM_BOUNDARY_RESERVED_SIZE=0x00001000 # # storage configurations # -CONFIG_SPI_NOR=n +CONFIG_SPI_NOR=y CONFIG_SPI_NOR_CFG="" # CONFIG_SPI_NAND is not set CONFIG_SPI_NAND_CFG="" CONFIG_SDCAED=y CONFIG_EMMC=y CONFIG_SPI_EMMC_CFG="" + +# +# spi nor partion config +# +CONFIG_SPI_NOR_QUICK_BOOT_CFG_BASE=0x00200000 +CONFIG_SPI_NOR_QUICK_BOOT_CFG_SIZE=0x00040000 +# CONFIG_SPI_NOR_QUICK_BOOT_CFG_SUPPORT_BAKEUP is not set +CONFIG_SPI_NOR_FACE_DB_CFG_BASE=0x00240000 +CONFIG_SPI_NOR_FACE_DB_CFG_SIZE=0x00040000 +# CONFIG_SPI_NOR_FACE_DB_CFG_SUPPORT_BAKEUP is not set +CONFIG_SPI_NOR_SENSOR_CFG_CFG_BASE=0x00280000 +CONFIG_SPI_NOR_SENSOR_CFG_CFG_SIZE=0x00040000 +CONFIG_SPI_NOR_AI_MODE_CFG_BASE=0x002C0000 +CONFIG_SPI_NOR_AI_MODE_CFG_SIZE=0x00280000 +CONFIG_SPI_NOR_SPECKLE_CFG_BASE=0x00540000 +CONFIG_SPI_NOR_SPECKLE_CFG_SIZE=0x00040000 +CONFIG_SPI_NOR_RTTK_BASE=0x005C0000 +CONFIG_SPI_NOR_RTTK_SIZE=0x00180000 +CONFIG_SPI_NOR_RTT_APP_BASE=0x00740000 +CONFIG_SPI_NOR_RTT_APP_SIZE=0x00440000 +CONFIG_SPI_NOR_LK_BASE=0x00B80000 +CONFIG_SPI_NOR_LK_SIZE=0x00440000 +CONFIG_SPI_NOR_LR_BASE=0x00FC0000 +CONFIG_SPI_NOR_LR_SIZE=0x01040000 +# CONFIG_BUILD_DEBUG_VER is not set +CONFIG_BUILD_RELEASE_VER=y CONFIG_SUPPORT_LINUX=y -CONFIG_SUPPORT_RTSMART=y \ No newline at end of file +CONFIG_SUPPORT_RTSMART=y diff --git a/configs/k230_evb_peephole_device_sd_defconfig b/configs/k230_evb_peephole_device_sd_defconfig new file mode 100644 index 000000000..250974cf6 --- /dev/null +++ b/configs/k230_evb_peephole_device_sd_defconfig @@ -0,0 +1,56 @@ +# +# Automatically generated file; DO NOT EDIT. +# K230 SDK Configuration +# + +# +# board configuration +# +CONFIG_BOARD_K230_EVB=y +# CONFIG_BOARD_K230_FPGA is not set +CONFIG_BOARD_NAME="k230_evb_peephole_device_sd" +CONFIG_QUICK_BOOT=y +# CONFIG_GEN_SECURITY_IMG is not set +CONFIG_UBOOT_DEFCONFIG="k230_evb" +CONFIG_LINUX_DTB="k230_peephole_device" +CONFIG_GEN_IMG_SCRIPT="board/k230_evb_peephole/gen_peephole_device_image_sd.sh" + + +# +# toolchain configurations +# +CONFIG_TOOLCHAIN_PREFIX_RTT="riscv64-unknown-linux-musl-" +CONFIG_TOOLCHAIN_PATH_RTT="/opt/toolchain/riscv64-linux-musleabi_for_x86_64-pc-linux-gnu/bin" +CONFIG_TOOLCHAIN_PREFIX_LINUX="riscv64-unknown-linux-gnu-" +CONFIG_TOOLCHAIN_PATH_LINUX="/opt/toolchain/Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.0/bin" + +# +# Memory configuration +# +CONFIG_MEM_TOTAL_SIZE=0x20000000 +CONFIG_MEM_PARAM_BASE=0x00000000 +CONFIG_MEM_PARAM_SIZE=0x00100000 +CONFIG_MEM_IPCM_BASE=0x00100000 +CONFIG_MEM_IPCM_SIZE=0x00100000 +CONFIG_MEM_RTT_SYS_BASE=0x00200000 +CONFIG_MEM_RTT_SYS_SIZE=0x07E00000 +CONFIG_MEM_AI_MODEL_BASE=0x1FC00000 +CONFIG_MEM_AI_MODEL_SIZE=0x00400000 +CONFIG_MEM_LINUX_SYS_BASE=0x08000000 +CONFIG_MEM_LINUX_SYS_SIZE=0x08000000 +CONFIG_MEM_MMZ_BASE=0x10000000 +CONFIG_MEM_MMZ_SIZE=0x0FC00000 +CONFIG_MEM_BOUNDARY_RESERVED_SIZE=0x00001000 + +# +# storage configurations +# +CONFIG_SPI_NOR=n +CONFIG_SPI_NOR_CFG="" +# CONFIG_SPI_NAND is not set +CONFIG_SPI_NAND_CFG="" +CONFIG_SDCAED=y +CONFIG_EMMC=y +CONFIG_SPI_EMMC_CFG="" +CONFIG_SUPPORT_LINUX=y +CONFIG_SUPPORT_RTSMART=y \ No newline at end of file diff --git a/configs/k230_evb_peephole_phone_defconfig b/configs/k230_evb_peephole_phone_defconfig index 6e891015e..db21b671b 100755 --- a/configs/k230_evb_peephole_phone_defconfig +++ b/configs/k230_evb_peephole_phone_defconfig @@ -14,7 +14,6 @@ CONFIG_BOARD_NAME="k230_evb_peephole_phone" CONFIG_QUICK_BOOT=y # CONFIG_GEN_SECURITY_IMG is not set CONFIG_UBOOT_DEFCONFIG="k230_evb" -CONFIG_LINUX_DEFCONFIG="k230_evb_peephole_device" CONFIG_LINUX_DTB="k230_evb" BUILDROOT_DEFCONFIG="k230_evb_peephole_phone" # CONFIG_REMOTE_TEST_PLATFORM is not set @@ -49,7 +48,7 @@ CONFIG_MEM_BOUNDARY_RESERVED_SIZE=0x00001000 # # storage configurations # -CONFIG_SPI_NOR=y +CONFIG_SPI_NOR=n CONFIG_SPI_NOR_CFG="" # CONFIG_SPI_NAND is not set CONFIG_SPI_NAND_CFG="" @@ -57,4 +56,4 @@ CONFIG_SDCAED=y CONFIG_EMMC=y CONFIG_SPI_EMMC_CFG="" CONFIG_SUPPORT_LINUX=y -CONFIG_SUPPORT_RTSMART=y \ No newline at end of file +CONFIG_SUPPORT_RTSMART=y diff --git a/configs/k230_evb_usiplpddr4_dictionary_pen_defconfig b/configs/k230_evb_usiplpddr4_dictionary_pen_defconfig new file mode 100755 index 000000000..2c84bc400 --- /dev/null +++ b/configs/k230_evb_usiplpddr4_dictionary_pen_defconfig @@ -0,0 +1,53 @@ +# +# Automatically generated file; DO NOT EDIT. +# K230 SDK Configuration +# + +# +# board configuration +# +CONFIG_BOARD_K230_EVB=y +# CONFIG_BOARD_K230_FPGA is not set +CONFIG_BOARD_NAME="k230_evb" +CONFIG_QUICK_BOOT=y +# CONFIG_GEN_SECURITY_IMG is not set +CONFIG_UBOOT_DEFCONFIG="k230_evb_ddr4" +CONFIG_GEN_IMG_SCRIPT="board/k230_evb_dictionary_pen/gen_dictionary_pen_device_image_sd.sh" +# +# toolchain configurations +# +CONFIG_TOOLCHAIN_PREFIX_RTT="riscv64-unknown-linux-musl-" +CONFIG_TOOLCHAIN_PATH_RTT="/opt/toolchain/riscv64-linux-musleabi_for_x86_64-pc-linux-gnu/bin" +CONFIG_TOOLCHAIN_PREFIX_LINUX="riscv64-unknown-linux-gnu-" +CONFIG_TOOLCHAIN_PATH_LINUX="/opt/toolchain/Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.0/bin" + +# +# Memory configuration +# +CONFIG_MEM_TOTAL_SIZE=0x80000000 +CONFIG_MEM_PARAM_BASE=0x00000000 +CONFIG_MEM_PARAM_SIZE=0x00100000 +CONFIG_MEM_IPCM_BASE=0x00100000 +CONFIG_MEM_IPCM_SIZE=0x00100000 +CONFIG_MEM_RTT_SYS_BASE=0x00200000 +CONFIG_MEM_RTT_SYS_SIZE=0x2fe00000 +CONFIG_MEM_LINUX_SYS_BASE=0x30000000 +CONFIG_MEM_LINUX_SYS_SIZE=0x10000000 +CONFIG_MEM_AI_MODEL_BASE=0x50000000 +CONFIG_MEM_AI_MODEL_SIZE=0x0 +CONFIG_MEM_MMZ_BASE=0x40000000 +CONFIG_MEM_MMZ_SIZE=0x40000000 +CONFIG_MEM_BOUNDARY_RESERVED_SIZE=0x0000 + +# +# storage configurations +# +# CONFIG_SPI_NOR is not set +CONFIG_SPI_NOR_CFG="" +# CONFIG_SPI_NAND is not set +CONFIG_SPI_NAND_CFG="" +CONFIG_SDCAED=y +CONFIG_EMMC=y +CONFIG_SPI_EMMC_CFG="" +CONFIG_SUPPORT_LINUX=y +CONFIG_SUPPORT_RTSMART=y \ No newline at end of file diff --git a/repo.mak b/repo.mak index 391221283..dcfe1699d 100755 --- a/repo.mak +++ b/repo.mak @@ -1,11 +1,11 @@ -RT-SMART_VERSION = "0a2c55975d1181e66abf4ee10f8cf29f0966071d" -MPP_VERSION = "0955ee6e157771ff8870bf49fd0c598126abe9f2" +RT-SMART_VERSION = "fdeea349b50c985c0c4264a6d02fb7cec9ed5787" +MPP_VERSION = "d7ec0c9eeae092906db1061f292502dae2e5d286" UNITTEST_VERSION = "a07caf5e19a6a215605271cfeedce18111790e9d" -OPENSBI_VERSION = "9aa2f6d34e685bbbb0afaab4e308b93a9cd06ec7" -BUILDROOT-EXT_VERSION = "8eafd41f1dde4ff48b914d5978cecf7af627fba6" -LINUX_VERSION = "04b6371ff02d49cba18adc81dfcdbbec0cbfed56" -UBOOT_VERSION = "317894980fd498b863820b1343096fe188faae53" -CDK_VERSION = "dbfb3da07812b2f73257ebc1fb0d54dded1f7740" +OPENSBI_VERSION = "fcbb4027b6e1f89f52d9079483e5199f30558f5b" +BUILDROOT-EXT_VERSION = "adb839c7df7c9b9410159b4f9c57b299a2c38a2ev" +LINUX_VERSION = "57d3d53e66d36923ba95b2fa7941ed37551b48e4" +UBOOT_VERSION = "2580385862e86d308bad70d201772c50f750480e" +CDK_VERSION = "40a7755ce12891fb5bd5379c09b73f8eb8fb3240" RT-SMART_SRC_PATH = src/big/rt-smart MPP_SRC_PATH = src/big/mpp diff --git a/src/big/mpp/include/comm/k_connector_comm.h b/src/big/mpp/include/comm/k_connector_comm.h index b8958e4e6..0585ab774 100755 --- a/src/big/mpp/include/comm/k_connector_comm.h +++ b/src/big/mpp/include/comm/k_connector_comm.h @@ -42,7 +42,7 @@ extern "C" { #endif /* End of #ifdef __cplusplus */ -#define CONNECTOR_NUM_MAX 4 +#define CONNECTOR_NUM_MAX 128 #define BACKGROUND_BLACK_COLOR (0x808000) @@ -50,9 +50,13 @@ extern "C" { typedef enum { - HX8377_V2_MIPI_4LAN_1080X1920_30FPS, - LT9611_MIPI_4LAN_1920X1080_60FPS, + HX8377_V2_MIPI_4LAN_1080X1920_30FPS = 0, LT9611_MIPI_4LAN_1920X1080_30FPS, + LT9611_MIPI_ADAPT_RESOLUTION = 100, + LT9611_MIPI_4LAN_1920X1080_60FPS, + LT9611_MIPI_4LAN_1920X1080_50FPS, + LT9611_MIPI_4LAN_1920X1080_25FPS, + LT9611_MIPI_4LAN_1920X1080_24FPS, LT9611_MIPI_4LAN_1280X720_60FPS, LT9611_MIPI_4LAN_1280X720_50FPS, LT9611_MIPI_4LAN_640X480_60FPS, @@ -82,6 +86,14 @@ typedef struct { } k_connector_info; +typedef struct +{ + k_u32 connection_status; + k_u32 negotiated_count; + k_connector_type negotiated_types[256]; +} k_connector_negotiated_data; + + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/src/big/mpp/include/comm/k_sensor_comm.h b/src/big/mpp/include/comm/k_sensor_comm.h index 3980b78ef..81f1f013b 100755 --- a/src/big/mpp/include/comm/k_sensor_comm.h +++ b/src/big/mpp/include/comm/k_sensor_comm.h @@ -76,24 +76,24 @@ typedef enum { IMX335_MIPI_2LANE_RAW12_2592X1944_30FPS_MCLK_7425_LINEAR = 11, IMX335_MIPI_4LANE_RAW12_2592X1944_30FPS_MCLK_7425_LINEAR = 12, - IMX335_MIPI_4LANE_RAW10_2XDOL, - IMX335_MIPI_4LANE_RAW10_3XDOL, + IMX335_MIPI_4LANE_RAW10_2XDOL = 13, + IMX335_MIPI_4LANE_RAW10_3XDOL = 14, - SC_SC035HGS_MIPI_1LANE_RAW10_640X480_120FPS_LINEAR, - SC_SC035HGS_MIPI_1LANE_RAW10_640X480_60FPS_LINEAR, - SC_SC035HGS_MIPI_1LANE_RAW10_640X480_30FPS_LINEAR, + SC_SC035HGS_MIPI_1LANE_RAW10_640X480_120FPS_LINEAR = 15, + SC_SC035HGS_MIPI_1LANE_RAW10_640X480_60FPS_LINEAR = 16, + SC_SC035HGS_MIPI_1LANE_RAW10_640X480_30FPS_LINEAR = 17, - OV_OV9286_MIPI_1280X720_30FPS_10BIT_MCLK_25M_LINEAR_SPECKLE, - OV_OV9286_MIPI_1280X720_30FPS_10BIT_MCLK_25M_LINEAR_IR, - OV_OV9732_MIPI_1280X720_30FPS_10BIT_MCLK_16M_LINEAR, + OV_OV9286_MIPI_1280X720_30FPS_10BIT_MCLK_25M_LINEAR_SPECKLE = 18, + OV_OV9286_MIPI_1280X720_30FPS_10BIT_MCLK_25M_LINEAR_IR = 19, + OV_OV9732_MIPI_1280X720_30FPS_10BIT_MCLK_16M_LINEAR = 20, - OV_OV5647_MIPI_1920X1080_30FPS_10BIT_LINEAR, - OV_OV5647_MIPI_2592x1944_10FPS_10BIT_LINEAR, - OV_OV5647_MIPI_640x480_60FPS_10BIT_LINEAR, - OV_OV5647_MIPI_CSI0_1920X1080_30FPS_10BIT_LINEAR, + OV_OV5647_MIPI_1920X1080_30FPS_10BIT_LINEAR = 21, + OV_OV5647_MIPI_2592x1944_10FPS_10BIT_LINEAR = 22, + OV_OV5647_MIPI_640x480_60FPS_10BIT_LINEAR = 23, + OV_OV5647_MIPI_CSI0_1920X1080_30FPS_10BIT_LINEAR = 24, - SC_SC201CS_MIPI_1LANE_RAW10_1600X1200_30FPS_LINEAR, - SC_SC201CS_SLAVE_MODE_MIPI_1LANE_RAW10_1600X1200_30FPS_LINEAR, + SC_SC201CS_MIPI_1LANE_RAW10_1600X1200_30FPS_LINEAR = 25, + SC_SC201CS_SLAVE_MODE_MIPI_1LANE_RAW10_1600X1200_30FPS_LINEAR = 26, SENSOR_TYPE_MAX, } k_vicap_sensor_type; diff --git a/src/big/mpp/include/ioctl/k_connector_ioctl.h b/src/big/mpp/include/ioctl/k_connector_ioctl.h index 08c4302bf..ed01ab027 100755 --- a/src/big/mpp/include/ioctl/k_connector_ioctl.h +++ b/src/big/mpp/include/ioctl/k_connector_ioctl.h @@ -48,11 +48,13 @@ typedef enum { KD_IOC_NR_CONNECTOR_DEV_POWER, KD_IOC_NR_CONNECTOR_DEV_INIT, KD_IOC_NR_CONNECTOR_DEV_ID, + KD_IOC_NR_CONNECTOR_DEV_GET_NEG_DATA, } k_ioc_nr_connector; #define KD_IOC_CONNECTOR_S_POWER _IOW(K_IOC_TYPE_SENSOR, KD_IOC_NR_CONNECTOR_DEV_POWER, k_s32) #define KD_IOC_CONNECTOR_S_INIT _IOW(K_IOC_TYPE_SENSOR, KD_IOC_NR_CONNECTOR_DEV_INIT, k_connector_info) #define KD_IOC_CONNECTOR_G_ID _IOW(K_IOC_TYPE_SENSOR, KD_IOC_NR_CONNECTOR_DEV_ID, k_u32) +#define KD_IOC_CONNECTOR_G_NEG_DATA _IOW(K_IOC_TYPE_SENSOR, KD_IOC_NR_CONNECTOR_DEV_GET_NEG_DATA, k_connector_negotiated_data) #ifdef __cplusplus } diff --git a/src/big/mpp/include/ioctl/k_pm_ioctl.h b/src/big/mpp/include/ioctl/k_pm_ioctl.h new file mode 100644 index 000000000..006938410 --- /dev/null +++ b/src/big/mpp/include/ioctl/k_pm_ioctl.h @@ -0,0 +1,128 @@ +/** + * Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __K_PM_IOCTL_H__ +#define __K_PM_IOCTL_H__ + +#include "k_pm_comm.h" +#include "k_ioctl.h" +#include "k_type.h" +#ifdef __cplusplus +extern "C" { +#endif /* End of #ifdef __cplusplus */ + +typedef struct { + uint32_t reg; + uint32_t val; +} _k_pm_reg; + +typedef struct { + k_pm_domain domain; + uint32_t number; + k_pm_profile profiles[0]; +} _k_pm_domain_profiles; + +typedef struct { + k_pm_domain domain; + k_pm_governor governor; +} _k_pm_domain_governor; + +typedef struct { + k_pm_domain domain; + int32_t index; +} _k_pm_domain_profile; + +typedef struct { + k_pm_domain domain; + int32_t temp; // unit:0.01℃ + int32_t index; +} _k_pm_domain_thermal_protect; + +typedef struct { + k_pm_domain domain; + bool enable; +} _k_pm_domain_bool; + +enum { + K_IOC_NR_PM_SET_REG, + K_IOC_NR_PM_GET_REG, + K_IOC_NR_PM_GET_PROFILES, + K_IOC_NR_PM_GET_STAT, + K_IOC_NR_PM_SET_GOVERNOR, + K_IOC_NR_PM_GET_GOVERNOR, + K_IOC_NR_PM_SET_PROFILE, + K_IOC_NR_PM_GET_PROFILE, + K_IOC_NR_PM_SET_PROFILE_LOCK, + K_IOC_NR_PM_SET_PROFILE_UNLOCK, + K_IOC_NR_PM_SET_THERMAL_PROTECT, + K_IOC_NR_PM_GET_THERMAL_PROTECT, + K_IOC_NR_PM_SET_THERMAL_SHUTDOWN, + K_IOC_NR_PM_GET_THERMAL_SHUTDOWN, + K_IOC_NR_PM_SET_CLOCK, + K_IOC_NR_PM_SET_POWER, +}; + +#define K_IOC_PM_SET_REG \ + _IOW(K_IOC_TYPE_PM, K_IOC_NR_PM_SET_REG, _k_pm_reg) +#define K_IOC_PM_GET_REG \ + _IOWR(K_IOC_TYPE_PM, K_IOC_NR_PM_GET_REG, _k_pm_reg) +#define K_IOC_PM_GET_PROFILES \ + _IOWR(K_IOC_TYPE_PM, K_IOC_NR_PM_GET_PROFILES, _k_pm_domain_profiles) +#define K_IOC_PM_GET_STAT \ + _IOW(K_IOC_TYPE_PM, K_IOC_NR_PM_GET_STAT, k_pm_domain) +#define K_IOC_PM_SET_GOVERNOR \ + _IOW(K_IOC_TYPE_PM, K_IOC_NR_PM_SET_GOVERNOR, _k_pm_domain_governor) +#define K_IOC_PM_GET_GOVERNOR \ + _IOWR(K_IOC_TYPE_PM, K_IOC_NR_PM_GET_GOVERNOR, _k_pm_domain_governor) +#define K_IOC_PM_SET_PROFILE \ + _IOW(K_IOC_TYPE_PM, K_IOC_NR_PM_SET_PROFILE, _k_pm_domain_profile) +#define K_IOC_PM_GET_PROFILE \ + _IOWR(K_IOC_TYPE_PM, K_IOC_NR_PM_GET_PROFILE, _k_pm_domain_profile) +#define K_IOC_PM_SET_PROFILE_LOCK \ + _IOW(K_IOC_TYPE_PM, K_IOC_NR_PM_SET_PROFILE_LOCK, _k_pm_domain_profile) +#define K_IOC_PM_SET_PROFILE_UNLOCK \ + _IOW(K_IOC_TYPE_PM, K_IOC_NR_PM_SET_PROFILE_UNLOCK, \ + _k_pm_domain_profile) +#define K_IOC_PM_SET_THERMAL_PROTECT \ + _IOW(K_IOC_TYPE_PM, K_IOC_NR_PM_SET_THERMAL_PROTECT, \ + _k_pm_domain_thermal_protect) +#define K_IOC_PM_GET_THERMAL_PROTECT \ + _IOWR(K_IOC_TYPE_PM, K_IOC_NR_PM_GET_THERMAL_PROTECT, \ + _k_pm_domain_thermal_protect) +#define K_IOC_PM_SET_THERMAL_SHUTDOWN \ + _IOW(K_IOC_TYPE_PM, K_IOC_NR_PM_SET_THERMAL_SHUTDOWN, int32_t) +#define K_IOC_PM_GET_THERMAL_SHUTDOWN \ + _IOWR(K_IOC_TYPE_PM, K_IOC_NR_PM_GET_THERMAL_SHUTDOWN, int32_t) +#define K_IOC_PM_SET_CLOCK \ + _IOW(K_IOC_TYPE_PM, K_IOC_NR_PM_SET_CLOCK, _k_pm_domain_bool) +#define K_IOC_PM_SET_POWER \ + _IOW(K_IOC_TYPE_PM, K_IOC_NR_PM_SET_POWER, _k_pm_domain_bool) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/src/big/mpp/kernel/Makefile b/src/big/mpp/kernel/Makefile index 5cc072362..213694dfc 100644 --- a/src/big/mpp/kernel/Makefile +++ b/src/big/mpp/kernel/Makefile @@ -2,7 +2,11 @@ all: @cd sensor; make || exit 1 @cd fft; make || exit 1 @cd connector; make || exit 1 + @cd mediafreq; make || exit 1 + @cd pm; make || exit 1 clean: @cd sensor; make clean @cd fft; make clean @cd connector; make clean + @cd mediafreq; make clean + @cd pm; make clean \ No newline at end of file diff --git a/src/big/mpp/kernel/connector/src/connector_comm.c b/src/big/mpp/kernel/connector/src/connector_comm.c index 74bccb4a5..4d5eb6b2b 100755 --- a/src/big/mpp/kernel/connector/src/connector_comm.c +++ b/src/big/mpp/kernel/connector/src/connector_comm.c @@ -105,6 +105,24 @@ k_s32 connector_priv_ioctl(struct connector_driver_dev *dev, k_u32 cmd, void *ar } break; } + case KD_IOC_CONNECTOR_G_NEG_DATA : + { + k_connector_negotiated_data negotiated_data; + if (dev->connector_func.connector_get_negotiated_data == NULL) { + rt_kprintf("%s (%s)connector_get_negotiated_data is null\n", __func__, dev->connector_name); + return -1; + } + ret = dev->connector_func.connector_get_negotiated_data(dev, &negotiated_data); + if (ret == -1) { + rt_kprintf("%s (%s)connector_get_negotiated_data err\n", __func__, dev->connector_name); + return -1; + } + if (sizeof(negotiated_data) != lwp_put_to_user(args, &negotiated_data, sizeof(negotiated_data))){ + rt_kprintf("%s:%d lwp_put_to_user err\n", __func__, __LINE__); + return -1; + } + break; + } default: break; } diff --git a/src/big/mpp/kernel/connector/src/connector_dev.h b/src/big/mpp/kernel/connector/src/connector_dev.h index 55bc3aba8..9a4327c4e 100755 --- a/src/big/mpp/kernel/connector/src/connector_dev.h +++ b/src/big/mpp/kernel/connector/src/connector_dev.h @@ -48,6 +48,7 @@ typedef struct { k_s32 (*connector_power) (void *ctx, k_s32 on); k_s32 (*connector_init) (void *ctx, k_connector_info *info); k_s32 (*connector_get_chip_id) (void *ctx, k_u32 *chip_id); + k_s32 (*connector_get_negotiated_data) (void *ctx, k_connector_negotiated_data *negotiated_data); k_s32 (*connector_conn_check)(void *ctx, k_s32 *conn); } k_connector_function; diff --git a/src/big/mpp/kernel/connector/src/lt9611.c b/src/big/mpp/kernel/connector/src/lt9611.c index 570ecdb17..836d1a12e 100755 --- a/src/big/mpp/kernel/connector/src/lt9611.c +++ b/src/big/mpp/kernel/connector/src/lt9611.c @@ -59,6 +59,22 @@ struct lt9611_dev { k_i2c_info i2c_info; }; +struct lt9611_resolution { + k_u8 std_timing_high; + k_u8 std_timing_low; + k_u8 cea861_vic; + k_u32 connector_type; +}; + +#define LT9611_RESOLUTION_NUM 2 +struct lt9611_resolution lt9611_resolution[LT9611_RESOLUTION_NUM] = { + {0xd1, 0xc0, 16, LT9611_MIPI_4LAN_1920X1080_60FPS}, + {0x00, 0x00, 34, LT9611_MIPI_4LAN_1920X1080_30FPS}, + //{0x81, 0xc0, 4, LT9611_MIPI_4LAN_1280X720_60FPS}, + //{0x00, 0x00, 19, LT9611_MIPI_4LAN_1280X720_50FPS}, + //{0x00, 0x00, 1, LT9611_MIPI_4LAN_640X480_60FPS}, +}; + static void connector_set_drvdata(struct connector_driver_dev *dev, void *data) { dev->driver_data = data; @@ -631,6 +647,149 @@ static k_s32 lt9611_get_chip_id(void* ctx, k_u32* chip_id) return ret; } +#define EDID_BLOCK_COUNT 8 +#define EDID_BLOCK_SIZE 32 +static k_s32 lt9611_read_edid(struct lt9611_dev *lt9611_dev, k_u8 *edid_data, k_s32 len) +{ + k_s32 ret = 0; + k_s32 conn = 0; + k_s32 i, j; + k_u8 hpd_state = 0x00; + k_u8 ddc_state = 0x00; + k_u8 reg_val = 0x00; + + ret |= lt9611_write_reg(<9611_dev->i2c_info, 0xff, 0x82); + ret |= lt9611_read_reg(<9611_dev->i2c_info, 0x5e, &hpd_state); + conn = !!(hpd_state & 0x04); + if (conn == 0) { + rt_kprintf("HDMI monitor disconnected \n"); + return 0; + } + + ret |= lt9611_write_reg(<9611_dev->i2c_info, 0xff, 0x85); + ret |= lt9611_write_reg(<9611_dev->i2c_info, 0x03, 0xc9); + ret |= lt9611_write_reg(<9611_dev->i2c_info, 0x04, 0xa0); + ret |= lt9611_write_reg(<9611_dev->i2c_info, 0x05, 0x00); + ret |= lt9611_write_reg(<9611_dev->i2c_info, 0x06, EDID_BLOCK_SIZE); + ret |= lt9611_write_reg(<9611_dev->i2c_info, 0x14, 0x7f); + + for (i = 0; i < EDID_BLOCK_COUNT; i++) { + ret |= lt9611_write_reg(<9611_dev->i2c_info, 0x05, i * EDID_BLOCK_SIZE); + ret |= lt9611_write_reg(<9611_dev->i2c_info, 0x07, 0x36); + ret |= lt9611_write_reg(<9611_dev->i2c_info, 0x07, 0x31); + ret |= lt9611_write_reg(<9611_dev->i2c_info, 0x07, 0x37); + rt_thread_mdelay(8); + + ret |= lt9611_read_reg(<9611_dev->i2c_info, 0x40, &ddc_state); + if (ddc_state & 0x02) { + //rt_kprintf("DDC answer success \n"); + for (j = 0; j < EDID_BLOCK_SIZE; j++) { + ret |= lt9611_read_reg(<9611_dev->i2c_info, 0x83, ®_val); + edid_data[i * EDID_BLOCK_SIZE + j] = reg_val; + } + } else if (ddc_state & 0x50) { + rt_kprintf("HDMI read EDID failed: DDC no ack \n"); + lt9611_write_reg(<9611_dev->i2c_info, 0x07, 0x1f); + return -1; + } else { + rt_kprintf("HDMI read EDID failed \n"); + lt9611_write_reg(<9611_dev->i2c_info, 0x07, 0x1f); + return -1; + } + } + + return 256; +} + +#define MATCH_OK 0 +#define MATCH_FAILED 1 +static k_s32 parse_stardard_timing(k_u8 *stardard_timing, k_s32 len, struct lt9611_resolution *lt9611_resolution) +{ + k_s32 i = 0; + + for (i = 0; i < len; i = i + 2) { + if ((stardard_timing[i] == lt9611_resolution->std_timing_high) && + (stardard_timing[i + 1] == lt9611_resolution->std_timing_low)) + return MATCH_OK; + } + + return MATCH_FAILED; +} + +static k_s32 parse_cea861_timing(k_u8 *cea861_timing, k_s32 len, struct lt9611_resolution *lt9611_resolution) +{ + k_s32 i = 0; + + for (i = 0; i < len; i ++) { + if (cea861_timing[i] == lt9611_resolution->cea861_vic) + return MATCH_OK; + } + + return MATCH_FAILED; +} + +static k_s32 lt9611_parse_edid(k_u8 *edid_data, k_s32 len, k_connector_negotiated_data *negotiated_data) +{ + k_u8 stardard_timing[16]; + k_u8 cea861_timing[256]; + k_u8 cea861_len = 0; + k_s32 i = 0; + k_s32 match = 0; + k_s32 negotiated_count = 0; + + memcpy(stardard_timing, edid_data + 0x26, 16); + if (edid_data[0x7E] == 0x01 && edid_data[0x80] == 0x02) { + cea861_len = edid_data[0x84] & 0x1F; + memcpy(cea861_timing, edid_data + 0x85, cea861_len); + } + + for (i = 0; i < LT9611_RESOLUTION_NUM; i ++) { + match = parse_stardard_timing(stardard_timing, 16, <9611_resolution[i]); + if (match == MATCH_OK) { + negotiated_data->negotiated_types[negotiated_count] = lt9611_resolution[i].connector_type; + negotiated_count ++; + continue; + } + + match = parse_cea861_timing(cea861_timing, cea861_len, <9611_resolution[i]); + if (match == MATCH_OK) { + negotiated_data->negotiated_types[negotiated_count] = lt9611_resolution[i].connector_type; + negotiated_count ++; + continue; + } + } + negotiated_data->negotiated_count = negotiated_count; + + return negotiated_count; +} + +static k_s32 lt9611_get_negotiated_data(void* ctx, k_connector_negotiated_data *negotiated_data) +{ + k_s32 ret = 0; + struct connector_driver_dev* dev = ctx; + struct lt9611_dev *lt9611_dev = connector_get_drvdata(dev); + k_u8 edid_data[256]; + + memset(edid_data, 0x00, 256); + ret = lt9611_read_edid(lt9611_dev, edid_data, 256); + if (ret == 0) { + negotiated_data->connection_status = 0; + negotiated_data->negotiated_count = 1; + negotiated_data->negotiated_types[0] = LT9611_MIPI_4LAN_1920X1080_60FPS; + return 1; + } + + ret = lt9611_parse_edid(edid_data, 256, negotiated_data); + if (ret == 0) { + negotiated_data->connection_status = 1; + negotiated_data->negotiated_count = 1; + negotiated_data->negotiated_types[0] = LT9611_MIPI_4LAN_1920X1080_60FPS; + return 1; + } + + return negotiated_data->negotiated_count; +} + static k_s32 lt9611_conn_check(void* ctx, k_s32* conn) { k_s32 ret = 0; @@ -653,6 +812,7 @@ struct connector_driver_dev lt9611_connector_drv = { .connector_power = lt9611_power_on, .connector_init = lt9611_init, .connector_get_chip_id = lt9611_get_chip_id, + .connector_get_negotiated_data = lt9611_get_negotiated_data, .connector_conn_check = lt9611_conn_check, }, }; diff --git a/src/big/mpp/kernel/lib/libaudio.a b/src/big/mpp/kernel/lib/libaudio.a index 3772329b7..10e29e8ff 100644 Binary files a/src/big/mpp/kernel/lib/libaudio.a and b/src/big/mpp/kernel/lib/libaudio.a differ diff --git a/src/big/mpp/kernel/lib/libcmpi.a b/src/big/mpp/kernel/lib/libcmpi.a index 73f5af875..cb2153f18 100644 Binary files a/src/big/mpp/kernel/lib/libcmpi.a and b/src/big/mpp/kernel/lib/libcmpi.a differ diff --git a/src/big/mpp/kernel/lib/libdma.a b/src/big/mpp/kernel/lib/libdma.a index 4c93f75b2..6caa4b40d 100644 Binary files a/src/big/mpp/kernel/lib/libdma.a and b/src/big/mpp/kernel/lib/libdma.a differ diff --git a/src/big/mpp/kernel/lib/libdpu.a b/src/big/mpp/kernel/lib/libdpu.a index 17f89b4c9..8e0841ef7 100644 Binary files a/src/big/mpp/kernel/lib/libdpu.a and b/src/big/mpp/kernel/lib/libdpu.a differ diff --git a/src/big/mpp/kernel/lib/liblog.a b/src/big/mpp/kernel/lib/liblog.a index a0adaacab..f0a218ae1 100644 Binary files a/src/big/mpp/kernel/lib/liblog.a and b/src/big/mpp/kernel/lib/liblog.a differ diff --git a/src/big/mpp/kernel/lib/libmediafreq.a b/src/big/mpp/kernel/lib/libmediafreq.a deleted file mode 100644 index 5b12e7c6d..000000000 Binary files a/src/big/mpp/kernel/lib/libmediafreq.a and /dev/null differ diff --git a/src/big/mpp/kernel/lib/libmmz.a b/src/big/mpp/kernel/lib/libmmz.a index 6252de80e..737bee838 100644 Binary files a/src/big/mpp/kernel/lib/libmmz.a and b/src/big/mpp/kernel/lib/libmmz.a differ diff --git a/src/big/mpp/kernel/lib/libpm.a b/src/big/mpp/kernel/lib/libpm.a deleted file mode 100644 index ffeac027b..000000000 Binary files a/src/big/mpp/kernel/lib/libpm.a and /dev/null differ diff --git a/src/big/mpp/kernel/lib/libsys.a b/src/big/mpp/kernel/lib/libsys.a index a8f969f3e..4617af09f 100644 Binary files a/src/big/mpp/kernel/lib/libsys.a and b/src/big/mpp/kernel/lib/libsys.a differ diff --git a/src/big/mpp/kernel/lib/libvb.a b/src/big/mpp/kernel/lib/libvb.a index 0e970f57a..245f2529f 100644 Binary files a/src/big/mpp/kernel/lib/libvb.a and b/src/big/mpp/kernel/lib/libvb.a differ diff --git a/src/big/mpp/kernel/lib/libvdss.a b/src/big/mpp/kernel/lib/libvdss.a index 92edd83f6..468b9b4f8 100644 Binary files a/src/big/mpp/kernel/lib/libvdss.a and b/src/big/mpp/kernel/lib/libvdss.a differ diff --git a/src/big/mpp/kernel/lib/libvicap.a b/src/big/mpp/kernel/lib/libvicap.a index 09fc03d13..0c341d8bc 100644 Binary files a/src/big/mpp/kernel/lib/libvicap.a and b/src/big/mpp/kernel/lib/libvicap.a differ diff --git a/src/big/mpp/kernel/lib/libvo.a b/src/big/mpp/kernel/lib/libvo.a index 5f060dde4..54b401f56 100644 Binary files a/src/big/mpp/kernel/lib/libvo.a and b/src/big/mpp/kernel/lib/libvo.a differ diff --git a/src/big/mpp/kernel/lib/libvpu.a b/src/big/mpp/kernel/lib/libvpu.a index 7405b677e..9ce41e8f6 100644 Binary files a/src/big/mpp/kernel/lib/libvpu.a and b/src/big/mpp/kernel/lib/libvpu.a differ diff --git a/src/big/mpp/kernel/lib/libvvi.a b/src/big/mpp/kernel/lib/libvvi.a index 0cf3b53dd..f9be42ed1 100644 Binary files a/src/big/mpp/kernel/lib/libvvi.a and b/src/big/mpp/kernel/lib/libvvi.a differ diff --git a/src/big/mpp/kernel/lib/libvvo.a b/src/big/mpp/kernel/lib/libvvo.a index 9c2c27c6b..062f7bcb2 100644 Binary files a/src/big/mpp/kernel/lib/libvvo.a and b/src/big/mpp/kernel/lib/libvvo.a differ diff --git a/src/big/mpp/kernel/mediafreq/Makefile b/src/big/mpp/kernel/mediafreq/Makefile new file mode 100755 index 000000000..4747f0b95 --- /dev/null +++ b/src/big/mpp/kernel/mediafreq/Makefile @@ -0,0 +1,32 @@ + +include $(MPP_SRC_DIR)/kernel/mpp.mk +include $(MPP_SRC_DIR)/kernel/rt-smart.mk + +CURRECT_DIR_NAME=$(shell basename `pwd`) +LOCAL_SRC_DIR = $(shell pwd) +LIB = $(MPP_SRC_DIR)/kernel/lib/lib$(CURRECT_DIR_NAME).a + +LOCAL_CFLAGS = -I$(LOCAL_SRC_DIR)/src/ -I$(LOCAL_SRC_DIR)/src/sysctl/sysctl_media_clock + +SRCS = $(wildcard $(LOCAL_SRC_DIR)/src/*.c) +SRCS += $(wildcard $(LOCAL_SRC_DIR)/src/sysctl/sysctl_media_clock/*.c) + +OBJS = $(patsubst %.c,%.o,$(SRCS)) + +all: $(LIB) + @-rm -f $(OBJS) + echo "${PWD}/Makefile all" + +$(OBJS): %.o : %.c + @$(CC) $(CC_CFLAGS) $(LOCAL_CFLAGS) $(BSP_CFLGAS) $(RTSMART_CFLAGS) $(MPP_DRIVER_CFLGAS) -c $< -o $@ + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +clean: + echo "${PWD}/Makefile clean" + -rm -rf $(LIB) + -rm -f $(OBJS) + +.PHONY: all clean + diff --git a/src/big/mpp/kernel/mediafreq/src/media_freq_mod.c b/src/big/mpp/kernel/mediafreq/src/media_freq_mod.c new file mode 100755 index 000000000..e09a675dd --- /dev/null +++ b/src/big/mpp/kernel/mediafreq/src/media_freq_mod.c @@ -0,0 +1,50 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#ifdef RT_USING_POSIX + #include + #include + #include +#endif +#include "io.h" + +#include "k_module.h" +#include "k_type.h" +#include "sysctl_media_clk.h" + +void media_freq_set_defalut() +{ + sysctl_media_clk_set_leaf_div(SYSCTL_CLK_AI_SRC, 1,1); /*set to 800M*/ +} + +k_s32 media_freq_init(void) +{ + media_freq_set_defalut(); + return 0; +} diff --git a/src/big/mpp/kernel/mediafreq/src/sysctl/sysctl_media_clock/sysctl_media_clk.c b/src/big/mpp/kernel/mediafreq/src/sysctl/sysctl_media_clock/sysctl_media_clk.c new file mode 100755 index 000000000..bef12df8a --- /dev/null +++ b/src/big/mpp/kernel/mediafreq/src/sysctl/sysctl_media_clock/sysctl_media_clk.c @@ -0,0 +1,2858 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include "sysctl_boot.h" +#include "sysctl_media_clk.h" +#include "ioremap.h" +#include "board.h" + +/* created by yangfan */ +/* please refer to the sysctl_media_clk.h file for API description */ +#define OSC_CLOCK_FREQ_24M (24000000) + +extern volatile sysctl_boot_t* sysctl_boot; + +volatile sysctl_media_clk_t* sysctl_media_clk = (volatile sysctl_media_clk_t*)SYSCTL_CLK_BASE_ADDR; + +/* if PLL bypass, the output clock is 24m clock. If there is no bypass, the clock comes from PLL */ +bool sysctl_media_boot_get_root_clk_bypass(sysctl_media_clk_node_e clk) +{ + switch(clk) + { + case SYSCTL_CLK_ROOT_PLL0: + case SYSCTL_CLK_ROOT_PLL0_DIV_2: + case SYSCTL_CLK_ROOT_PLL0_DIV_3: + case SYSCTL_CLK_ROOT_PLL0_DIV_4: + return ((sysctl_boot->pll[0].cfg1 >> 19) & 0x1) ? true:false; + + case SYSCTL_CLK_ROOT_PLL1: + case SYSCTL_CLK_ROOT_PLL1_DIV_2: + case SYSCTL_CLK_ROOT_PLL1_DIV_3: + case SYSCTL_CLK_ROOT_PLL1_DIV_4: + return ((sysctl_boot->pll[1].cfg1 >> 19) & 0x1) ? true:false; + + case SYSCTL_CLK_ROOT_PLL2: + case SYSCTL_CLK_ROOT_PLL2_DIV_2: + case SYSCTL_CLK_ROOT_PLL2_DIV_3: + case SYSCTL_CLK_ROOT_PLL2_DIV_4: + return ((sysctl_boot->pll[2].cfg1 >> 19) & 0x1) ? true:false; + + case SYSCTL_CLK_ROOT_PLL3: + case SYSCTL_CLK_ROOT_PLL3_DIV_2: + case SYSCTL_CLK_ROOT_PLL3_DIV_3: + case SYSCTL_CLK_ROOT_PLL3_DIV_4: + return ((sysctl_boot->pll[3].cfg1 >> 19) & 0x1) ? true:false; + + default: + return false; + } +} + +/* get PLL output frequency. +* freq = (double)OSC_CLOCK_FREQ_24M * (double)(fbdiv+1) / (double)(refdiv+1) / (double)(outdiv+1) +*/ +uint32_t sysctl_media_boot_get_root_clk_freq(sysctl_media_clk_node_e clk) +{ + uint32_t refdiv; /* reference clock divide */ + uint32_t outdiv; /* output clock divide */ + uint32_t fbdiv; /* feedback clock divide */ + uint32_t freq; + + switch(clk) + { + case SYSCTL_CLK_ROOT_OSC_IN: + return OSC_CLOCK_FREQ_24M; /* 24MHz */ + + case SYSCTL_CLK_ROOT_PLL0: + case SYSCTL_CLK_ROOT_PLL0_DIV_2: + case SYSCTL_CLK_ROOT_PLL0_DIV_3: + case SYSCTL_CLK_ROOT_PLL0_DIV_4: + { + if(true == sysctl_media_boot_get_root_clk_bypass(clk)) + { + freq = OSC_CLOCK_FREQ_24M; + } + else + { + refdiv = (sysctl_boot->pll[0].cfg0 >> 16) & 0x3F; /* bit 16~21 */ + outdiv = (sysctl_boot->pll[0].cfg0 >> 24) & 0xF; /* bit 24~27 */ + fbdiv = (sysctl_boot->pll[0].cfg0 >> 0) & 0x1FFF; /* bit 0~12 */ + freq = (double)OSC_CLOCK_FREQ_24M * (double)(fbdiv+1) / (double)(refdiv+1) / (double)(outdiv+1); + } + switch(clk) + { + case SYSCTL_CLK_ROOT_PLL0: + return freq; + case SYSCTL_CLK_ROOT_PLL0_DIV_2: + return freq/2; + case SYSCTL_CLK_ROOT_PLL0_DIV_3: + return freq/3; + default: + return freq/4; + } + } + + case SYSCTL_CLK_ROOT_PLL1: + case SYSCTL_CLK_ROOT_PLL1_DIV_2: + case SYSCTL_CLK_ROOT_PLL1_DIV_3: + case SYSCTL_CLK_ROOT_PLL1_DIV_4: + { + if(true == sysctl_media_boot_get_root_clk_bypass(clk)) + { + freq = OSC_CLOCK_FREQ_24M; + } + else + { + refdiv = (sysctl_boot->pll[1].cfg0 >> 16) & 0x3F; /* bit 16~21 */ + outdiv = (sysctl_boot->pll[1].cfg0 >> 24) & 0xF; /* bit 24~27 */ + fbdiv = (sysctl_boot->pll[1].cfg0 >> 0) & 0x1FFF; /* bit 0~12 */ + freq = (double)OSC_CLOCK_FREQ_24M * (double)(fbdiv+1) / (double)(refdiv+1) / (double)(outdiv+1); + } + switch(clk) + { + case SYSCTL_CLK_ROOT_PLL1: + return freq; + case SYSCTL_CLK_ROOT_PLL1_DIV_2: + return freq/2; + case SYSCTL_CLK_ROOT_PLL1_DIV_3: + return freq/3; + default: + return freq/4; + } + } + + case SYSCTL_CLK_ROOT_PLL2: + case SYSCTL_CLK_ROOT_PLL2_DIV_2: + case SYSCTL_CLK_ROOT_PLL2_DIV_3: + case SYSCTL_CLK_ROOT_PLL2_DIV_4: + { + if(true == sysctl_media_boot_get_root_clk_bypass(clk)) + { + freq = OSC_CLOCK_FREQ_24M; + } + else + { + refdiv = (sysctl_boot->pll[2].cfg0 >> 16) & 0x3F; /* bit 16~21 */ + outdiv = (sysctl_boot->pll[2].cfg0 >> 24) & 0xF; /* bit 24~27 */ + fbdiv = (sysctl_boot->pll[2].cfg0 >> 0) & 0x1FFF; /* bit 0~12 */ + freq = (double)OSC_CLOCK_FREQ_24M * (double)(fbdiv+1) / (double)(refdiv+1) / (double)(outdiv+1); + } + switch(clk) + { + case SYSCTL_CLK_ROOT_PLL2: + return freq; + case SYSCTL_CLK_ROOT_PLL2_DIV_2: + return freq/2; + case SYSCTL_CLK_ROOT_PLL2_DIV_3: + return freq/3; + default: + return freq/4; + } + } + + case SYSCTL_CLK_ROOT_PLL3: + case SYSCTL_CLK_ROOT_PLL3_DIV_2: + case SYSCTL_CLK_ROOT_PLL3_DIV_3: + case SYSCTL_CLK_ROOT_PLL3_DIV_4: + { + if(true == sysctl_media_boot_get_root_clk_bypass(clk)) + { + freq = OSC_CLOCK_FREQ_24M; + } + else + { + refdiv = (sysctl_boot->pll[3].cfg0 >> 16) & 0x3F; /* bit 16~21 */ + outdiv = (sysctl_boot->pll[3].cfg0 >> 24) & 0xF; /* bit 24~27 */ + fbdiv = (sysctl_boot->pll[3].cfg0 >> 0) & 0x1FFF; /* bit 0~12 */ + freq = (double)OSC_CLOCK_FREQ_24M * (double)(fbdiv+1) / (double)(refdiv+1) / (double)(outdiv+1); + } + switch(clk) + { + case SYSCTL_CLK_ROOT_PLL3: + return freq; + case SYSCTL_CLK_ROOT_PLL3_DIV_2: + return freq/2; + case SYSCTL_CLK_ROOT_PLL3_DIV_3: + return freq/3; + default: + return freq/4; + } + } + + default: + return 0; + } +} + + +/*************************************************************************** +* +* API of trunk and leaf node +* +**************************************************************************/ +/* 设置时钟树上叶子节点的时钟源,即根据寄存器设计文档来描述MUX;如果时钟节点只有一个时钟源,则返回false。 */ +bool sysctl_media_clk_set_leaf_parent(sysctl_media_clk_node_e leaf, sysctl_media_clk_node_e parent) +{ + volatile uint32_t ret; + + switch(leaf) + { + /*--------------------------- CPU1 CLOCK ------------------------------------*/ + case SYSCTL_CLK_CPU_1_SRC: + { + if(SYSCTL_CLK_ROOT_PLL0 == parent) + { + ret = sysctl_media_clk->cpu1_clk_cfg; + ret &= 0xfffffff9; + sysctl_media_clk->cpu1_clk_cfg = ret | (0 << 1); + return true; + } + else if(SYSCTL_CLK_ROOT_PLL1_DIV_2 == parent) + { + ret = sysctl_media_clk->cpu1_clk_cfg; + ret &= 0xfffffff9; + sysctl_media_clk->cpu1_clk_cfg = ret | (1 << 1); + return true; + } + else if(SYSCTL_CLK_ROOT_PLL3 == parent) + { + ret = sysctl_media_clk->cpu1_clk_cfg; + ret &= 0xfffffff9; + sysctl_media_clk->cpu1_clk_cfg = ret | (2 << 1); + return true; + } + else + { + return false; + } + } + case SYSCTL_CLK_CPU_1_PLIC: + case SYSCTL_CLK_CPU_1_ACLK: + case SYSCTL_CLK_CPU_1_NOC_DDRCP0: + return false; + case SYSCTL_CLK_CPU_1_PCLK: + return false; /* always pll0_div4 */ + + /*--------------------------- AI CLOCK ------------------------------------*/ + case SYSCTL_CLK_AI_SRC: + { + if(SYSCTL_CLK_ROOT_PLL0_DIV_2 == parent) + { + ret = sysctl_media_clk->ai_clk_cfg; + ret &= 0xfffffffb; + sysctl_media_clk->ai_clk_cfg = ret | (0 << 2); + return true; + } + else if(SYSCTL_CLK_ROOT_PLL3_DIV_2 == parent) + { + ret = sysctl_media_clk->ai_clk_cfg; + ret &= 0xfffffffb; + sysctl_media_clk->ai_clk_cfg = ret | (1 << 2); + return true; + } + else + { + return false; + } + } + case SYSCTL_CLK_AI_ACLK: + case SYSCTL_CLK_AI_DDRCP3: + return false; /* always pll0_div4 */ + + /*--------------------------- VPU CLOCK ------------------------------------*/ + case SYSCTL_CLK_VPU_SRC: + case SYSCTL_CLK_VPU_ACLK_SRC: + case SYSCTL_CLK_VPU_ACLK: + case SYSCTL_CLK_VPU_DDRCP2: + case SYSCTL_CLK_VPU_CFG: + return false; + + /*--------------------------- AUDIO CLOCK ------------------------------------*/ + case SYSCTL_CLK_AUDIO_PCLK_GATE: + case SYSCTL_CLK_CODEC_PCLK_GATE: + return false; + case SYSCTL_CLK_CODEC_ADC_MCLK: + case SYSCTL_CLK_CODEC_DAC_MCLK: + case SYSCTL_CLK_AUDIO_DEV_CLK: + case SYSCTL_CLK_PDM_CLK: + return false; + + /*--------------------------- ISP CLOCK ------------------------------------*/ + case SYSCTL_CLK_ISP_CFG_CLK: + case SYSCTL_CLK_CSI_0_PIXEL_CLK: + case SYSCTL_CLK_CSI_1_PIXEL_CLK: + case SYSCTL_CLK_CSI_2_PIXEL_CLK: + return false; + + case SYSCTL_CLK_MCLK_0: + { + if(SYSCTL_CLK_ROOT_PLL1_DIV_3 == parent) + { + ret = sysctl_media_clk->mclk_cfg; + ret &= 0xffffffe7; + sysctl_media_clk->mclk_cfg = ret | (0 << 3); + return true; + } + else if(SYSCTL_CLK_ROOT_PLL1_DIV_4 == parent) + { + ret = sysctl_media_clk->mclk_cfg; + ret &= 0xffffffe7; + sysctl_media_clk->mclk_cfg = ret | (1 << 3); + return true; + } + else if(SYSCTL_CLK_ROOT_PLL0_DIV_4 == parent) + { + ret = sysctl_media_clk->mclk_cfg; + ret &= 0xffffffe7; + sysctl_media_clk->mclk_cfg = ret | (2 << 3); + return true; + } + else + { + return false; + } + } + case SYSCTL_CLK_MCLK_1: + { + if(SYSCTL_CLK_ROOT_PLL1_DIV_3 == parent) + { + ret = sysctl_media_clk->mclk_cfg; + ret &= 0xfffff3ff; + sysctl_media_clk->mclk_cfg = ret | (0 << 10); + return true; + } + else if(SYSCTL_CLK_ROOT_PLL1_DIV_4 == parent) + { + ret = sysctl_media_clk->mclk_cfg; + ret &= 0xfffff3ff; + sysctl_media_clk->mclk_cfg = ret | (1 << 10); + return true; + } + else if(SYSCTL_CLK_ROOT_PLL0_DIV_4 == parent) + { + ret = sysctl_media_clk->mclk_cfg; + ret &= 0xfffff3ff; + sysctl_media_clk->mclk_cfg = ret | (2 << 10); + return true; + } + else + { + return false; + } + } + case SYSCTL_CLK_MCLK_2: + { + if(SYSCTL_CLK_ROOT_PLL1_DIV_3 == parent) + { + ret = sysctl_media_clk->mclk_cfg; + ret &= 0xfff9ffff; + sysctl_media_clk->mclk_cfg = ret | (0 << 17); + return true; + } + else if(SYSCTL_CLK_ROOT_PLL1_DIV_4 == parent) + { + ret = sysctl_media_clk->mclk_cfg; + ret &= 0xfff9ffff; + sysctl_media_clk->mclk_cfg = ret | (1 << 17); + return true; + } + else if(SYSCTL_CLK_ROOT_PLL0_DIV_4 == parent) + { + ret = sysctl_media_clk->mclk_cfg; + ret &= 0xfff9ffff; + sysctl_media_clk->mclk_cfg = ret | (2 << 17); + return true; + } + else + { + return false; + } + } + + case SYSCTL_CLK_ISP_CLK: + { + if(SYSCTL_CLK_ROOT_PLL0_DIV_4 == parent) + { + ret = sysctl_media_clk->isp_clkdiv_cfg; + ret &= 0xdfffffff; + sysctl_media_clk->isp_clkdiv_cfg = ret | (0 << 29); + return true; + } + else if(SYSCTL_CLK_ROOT_PLL2_DIV_4 == parent) + { + ret = sysctl_media_clk->isp_clkdiv_cfg; + ret &= 0xdfffffff; + sysctl_media_clk->isp_clkdiv_cfg = ret | (1 << 29); + return true; + } + else + { + return false; + } + } + case SYSCTL_CLK_ISP_MEM_CLK_GATE: + return false; + + case SYSCTL_CLK_ISP_HCLK: + return false; + + case SYSCTL_CLK_ISP_ACLK_GATE: + case SYSCTL_CLK_DDRC_P1CLK_GATE: + return false; + + case SYSCTL_CLK_ISP_DWECLK_GATE: + case SYSCTL_CLK_ISP_VSECLK_GATE: + return false; + + /*--------------------------- DPU CLOCK ------------------------------------*/ + case SYSCTL_CLK_DPU_CLK: + case SYSCTL_CLK_DPU_ACLK_GATE: + case SYSCTL_CLK_DPU_PCLK: + return false; + + default: + return false; + } +} + +/* 获取时钟树上叶子节点的时钟源,即读取MUX对应的寄存器的值;默认返回SYSCTL_CLK_ROOT_MAX */ +sysctl_media_clk_node_e sysctl_media_clk_get_leaf_parent(sysctl_media_clk_node_e leaf) +{ + switch(leaf) + { + /*--------------------------- CPU1 CLOCK ------------------------------------*/ + case SYSCTL_CLK_CPU_1_SRC: + { + switch((sysctl_media_clk->cpu1_clk_cfg >> 1) & 0x3) + { + case 0: + return SYSCTL_CLK_ROOT_PLL0; + case 1: + return SYSCTL_CLK_ROOT_PLL1_DIV_2; + case 2: + return SYSCTL_CLK_ROOT_PLL3; + default: + return SYSCTL_CLK_ROOT_MAX; + } + } + case SYSCTL_CLK_CPU_1_PLIC: + case SYSCTL_CLK_CPU_1_ACLK: + return SYSCTL_CLK_CPU_1_SRC; + case SYSCTL_CLK_CPU_1_NOC_DDRCP0: + return SYSCTL_CLK_CPU_1_ACLK; + case SYSCTL_CLK_CPU_1_PCLK: + return SYSCTL_CLK_ROOT_PLL0_DIV_4; + + /*--------------------------- AI CLOCK ------------------------------------*/ + case SYSCTL_CLK_AI_SRC: + { + if(0 == ((sysctl_media_clk->ai_clk_cfg >> 2) & 0x1)) + return SYSCTL_CLK_ROOT_PLL0_DIV_2; + else + return SYSCTL_CLK_ROOT_PLL3_DIV_2; + } + case SYSCTL_CLK_AI_ACLK: + case SYSCTL_CLK_AI_DDRCP3: + return SYSCTL_CLK_ROOT_PLL0_DIV_4; + + /*--------------------------- VPU CLOCK ------------------------------------*/ + case SYSCTL_CLK_VPU_SRC: + return SYSCTL_CLK_ROOT_PLL0_DIV_2; + case SYSCTL_CLK_VPU_ACLK_SRC: + return SYSCTL_CLK_VPU_SRC; + case SYSCTL_CLK_VPU_ACLK: + case SYSCTL_CLK_VPU_DDRCP2: + return SYSCTL_CLK_VPU_ACLK_SRC; + case SYSCTL_CLK_VPU_CFG: + return SYSCTL_CLK_ROOT_PLL0_DIV_4; + + /*--------------------------- AUDIO CLOCK ------------------------------------*/ + case SYSCTL_CLK_AUDIO_PCLK_GATE: + case SYSCTL_CLK_CODEC_PCLK_GATE: + return SYSCTL_CLK_LS_PCLK_SRC; + + case SYSCTL_CLK_CODEC_ADC_MCLK: + case SYSCTL_CLK_CODEC_DAC_MCLK: + case SYSCTL_CLK_AUDIO_DEV_CLK: + case SYSCTL_CLK_PDM_CLK: + return SYSCTL_CLK_ROOT_PLL0_DIV_4; + + /*--------------------------- DDR CLOCK ------------------------------------*/ + case SYSCTL_CLK_DDRC_CORE_CLK: + { + switch((sysctl_media_clk->ddr_clk_cfg >> 0) & 0x3) + { + case 0: + return SYSCTL_CLK_ROOT_PLL0_DIV_2; + case 1: + return SYSCTL_CLK_ROOT_PLL0_DIV_3; + case 2: + return SYSCTL_CLK_ROOT_PLL2_DIV_4; + default: + return SYSCTL_CLK_ROOT_MAX; + } + } + case SYSCTL_CLK_DDRC_BYPASS_GATE: + return SYSCTL_CLK_ROOT_PLL2_DIV_4; + case SYSCTL_CLK_DDRC_PCLK: + return SYSCTL_CLK_ROOT_PLL0_DIV_4; + + /*--------------------------- ISP CLOCK ------------------------------------*/ + case SYSCTL_CLK_ISP_CFG_CLK: + return SYSCTL_CLK_ROOT_PLL1_DIV_4; + case SYSCTL_CLK_CSI_0_PIXEL_CLK: + case SYSCTL_CLK_CSI_1_PIXEL_CLK: + case SYSCTL_CLK_CSI_2_PIXEL_CLK: + return SYSCTL_CLK_ROOT_PLL2_DIV_4; + + case SYSCTL_CLK_MCLK_0: + { + switch((sysctl_media_clk->mclk_cfg >> 3) & 0x3) + { + case 0: + return SYSCTL_CLK_ROOT_PLL1_DIV_3; + case 1: + return SYSCTL_CLK_ROOT_PLL1_DIV_4; + case 2: + return SYSCTL_CLK_ROOT_PLL0_DIV_4; + default: + return SYSCTL_CLK_ROOT_MAX; + } + } + case SYSCTL_CLK_MCLK_1: + { + switch((sysctl_media_clk->mclk_cfg >> 10) & 0x3) + { + case 0: + return SYSCTL_CLK_ROOT_PLL1_DIV_3; + case 1: + return SYSCTL_CLK_ROOT_PLL1_DIV_4; + case 2: + return SYSCTL_CLK_ROOT_PLL0_DIV_4; + default: + return SYSCTL_CLK_ROOT_MAX; + } + } + case SYSCTL_CLK_MCLK_2: + { + switch((sysctl_media_clk->mclk_cfg >> 17) & 0x3) + { + case 0: + return SYSCTL_CLK_ROOT_PLL1_DIV_3; + case 1: + return SYSCTL_CLK_ROOT_PLL1_DIV_4; + case 2: + return SYSCTL_CLK_ROOT_PLL0_DIV_4; + default: + return SYSCTL_CLK_ROOT_MAX; + } + } + + case SYSCTL_CLK_ISP_CLK: + { + if(0 == ((sysctl_media_clk->isp_clkdiv_cfg >> 29) & 0x1)) + return SYSCTL_CLK_ROOT_PLL0_DIV_4; + else + return SYSCTL_CLK_ROOT_PLL2_DIV_4; + } + case SYSCTL_CLK_ISP_MEM_CLK_GATE: + return SYSCTL_CLK_ISP_CLK; + + case SYSCTL_CLK_ISP_HCLK: + return SYSCTL_CLK_ROOT_PLL0_DIV_4; + + case SYSCTL_CLK_ISP_ACLK_GATE: + case SYSCTL_CLK_DDRC_P1CLK_GATE: + return SYSCTL_CLK_ROOT_PLL0_DIV_4; + + case SYSCTL_CLK_ISP_DWECLK_GATE: + case SYSCTL_CLK_ISP_VSECLK_GATE: + return SYSCTL_CLK_ROOT_PLL0_DIV_3; + + /*--------------------------- DPU CLOCK ------------------------------------*/ + case SYSCTL_CLK_DPU_CLK: + return SYSCTL_CLK_ROOT_PLL1_DIV_4; + case SYSCTL_CLK_DPU_ACLK_GATE: + return SYSCTL_CLK_ROOT_PLL0_DIV_4; + case SYSCTL_CLK_DPU_PCLK: + return SYSCTL_CLK_ROOT_PLL0_DIV_4; + + default: + return SYSCTL_CLK_ROOT_MAX; + } +} + +/* 设置时钟节点enable,注意:只设置本时钟节点的enable,不会设置上游时钟的enable。*/ +void sysctl_media_clk_set_leaf_en(sysctl_media_clk_node_e leaf, bool enable) +{ + switch(leaf) + { + /*--------------------------- CPU1 CLOCK ------------------------------------*/ + case SYSCTL_CLK_CPU_1_SRC: + if(enable == true) + sysctl_media_clk->cpu1_clk_cfg |= (1 << 0); + else + sysctl_media_clk->cpu1_clk_cfg &= ~(1 << 0); + break; + + case SYSCTL_CLK_CPU_1_PLIC: + if(enable == true) + sysctl_media_clk->cpu1_clk_cfg |= (1 << 15); + else + sysctl_media_clk->cpu1_clk_cfg &= ~(1 << 15); + break; + + case SYSCTL_CLK_CPU_1_ACLK: + break; + + case SYSCTL_CLK_CPU_1_NOC_DDRCP0: + if(enable == true) + sysctl_media_clk->ddr_clk_cfg |= (1 << 3); + else + sysctl_media_clk->ddr_clk_cfg &= ~(1 << 3); + break; + + case SYSCTL_CLK_CPU_1_PCLK: + if(enable == true) + sysctl_media_clk->cpu1_clk_cfg |= (1 << 19); + else + sysctl_media_clk->cpu1_clk_cfg &= ~(1 << 19); + break; + + /*--------------------------- AI CLOCK ------------------------------------*/ + case SYSCTL_CLK_AI_SRC: + if(enable == true) + sysctl_media_clk->ai_clk_cfg |= (1 << 0); + else + sysctl_media_clk->ai_clk_cfg &= ~(1 << 0); + break; + + case SYSCTL_CLK_AI_ACLK: + if(enable == true) + sysctl_media_clk->ai_clk_cfg |= (1 << 10); + else + sysctl_media_clk->ai_clk_cfg &= ~(1 << 10); + break; + + case SYSCTL_CLK_AI_DDRCP3: + if(enable == true) + sysctl_media_clk->ddr_clk_cfg |= (1 << 6); + else + sysctl_media_clk->ddr_clk_cfg &= ~(1 << 6); + break; + + /*--------------------------- VPU CLOCK ------------------------------------*/ + case SYSCTL_CLK_VPU_SRC: + if(enable == true) + sysctl_media_clk->vpu_clk_cfg |= (1 << 0); + else + sysctl_media_clk->vpu_clk_cfg &= ~(1 << 0); + break; + + case SYSCTL_CLK_VPU_ACLK_SRC: + break; + + case SYSCTL_CLK_VPU_ACLK: + if(enable == true) + sysctl_media_clk->vpu_clk_cfg |= (1 << 5); + else + sysctl_media_clk->vpu_clk_cfg &= ~(1 << 5); + break; + + case SYSCTL_CLK_VPU_DDRCP2: + if(enable == true) + sysctl_media_clk->ddr_clk_cfg |= (1 << 5); + else + sysctl_media_clk->ddr_clk_cfg &= ~(1 << 5); + break; + + case SYSCTL_CLK_VPU_CFG: + if(enable == true) + sysctl_media_clk->vpu_clk_cfg |= (1 << 10); + else + sysctl_media_clk->vpu_clk_cfg &= ~(1 << 10); + break; + + case SYSCTL_CLK_AUDIO_PCLK_GATE: + if(enable == true) + sysctl_media_clk->ls_clken_cfg0 |= (1 << 13); + else + sysctl_media_clk->ls_clken_cfg0 &= ~(1 << 13); + break; + + case SYSCTL_CLK_ADC_PCLK_GATE: + if(enable == true) + sysctl_media_clk->ls_clken_cfg0 |= (1 << 15); + else + sysctl_media_clk->ls_clken_cfg0 &= ~(1 << 15); + break; + + case SYSCTL_CLK_CODEC_PCLK_GATE: + if(enable == true) + sysctl_media_clk->ls_clken_cfg0 |= (1 << 14); + else + sysctl_media_clk->ls_clken_cfg0 &= ~(1 << 14); + break; + + case SYSCTL_CLK_CODEC_ADC_MCLK: + if(enable == true) + sysctl_media_clk->ls_clken_cfg0 |= (1 << 29); + else + sysctl_media_clk->ls_clken_cfg0 &= ~(1 << 29); + break; + + case SYSCTL_CLK_CODEC_DAC_MCLK: + if(enable == true) + sysctl_media_clk->ls_clken_cfg0 |= (1 << 30); + else + sysctl_media_clk->ls_clken_cfg0 &= ~(1 << 30); + break; + + case SYSCTL_CLK_AUDIO_DEV_CLK: + if(enable == true) + sysctl_media_clk->ls_clken_cfg0 |= (1 << 28); + else + sysctl_media_clk->ls_clken_cfg0 &= ~(1 << 28); + break; + + case SYSCTL_CLK_PDM_CLK: + if(enable == true) + sysctl_media_clk->ls_clken_cfg0 |= (1 << 31); + else + sysctl_media_clk->ls_clken_cfg0 &= ~(1 << 31); + break; + + /*--------------------------- ISP CLOCK ------------------------------------*/ + case SYSCTL_CLK_ISP_CFG_CLK: + if(enable == true) + sysctl_media_clk->isp_clken_cfg |= (1 << 0); + else + sysctl_media_clk->isp_clken_cfg &= ~(1 << 0); + break; + + case SYSCTL_CLK_CSI_0_PIXEL_CLK: + if(enable == true) + sysctl_media_clk->isp_clken_cfg |= (1 << 6); + else + sysctl_media_clk->isp_clken_cfg &= ~(1 << 6); + break; + + case SYSCTL_CLK_CSI_1_PIXEL_CLK: + if(enable == true) + sysctl_media_clk->isp_clken_cfg |= (1 << 7); + else + sysctl_media_clk->isp_clken_cfg &= ~(1 << 7); + break; + + case SYSCTL_CLK_CSI_2_PIXEL_CLK: + if(enable == true) + sysctl_media_clk->isp_clken_cfg |= (1 << 8); + else + sysctl_media_clk->isp_clken_cfg &= ~(1 << 8); + break; + + case SYSCTL_CLK_MCLK_0: + if(enable == true) + sysctl_media_clk->mclk_cfg |= (1 << 0); + else + sysctl_media_clk->mclk_cfg &= ~(1 << 0); + break; + + case SYSCTL_CLK_MCLK_1: + if(enable == true) + sysctl_media_clk->mclk_cfg |= (1 << 1); + else + sysctl_media_clk->mclk_cfg &= ~(1 << 1); + break; + + case SYSCTL_CLK_MCLK_2: + if(enable == true) + sysctl_media_clk->mclk_cfg |= (1 << 2); + else + sysctl_media_clk->mclk_cfg &= ~(1 << 2); + break; + + case SYSCTL_CLK_ISP_CLK: + if(enable == true) + sysctl_media_clk->isp_clken_cfg |= (1 << 12); + else + sysctl_media_clk->isp_clken_cfg &= ~(1 << 12); + break; + + case SYSCTL_CLK_ISP_MEM_CLK_GATE: + if(enable == true) + sysctl_media_clk->isp_clken_cfg |= (1 << 17); + else + sysctl_media_clk->isp_clken_cfg &= ~(1 << 17); + break; + + case SYSCTL_CLK_ISP_HCLK: + if(enable == true) + sysctl_media_clk->isp_clken_cfg |= (1 << 13); + else + sysctl_media_clk->isp_clken_cfg &= ~(1 << 13); + break; + + case SYSCTL_CLK_ISP_ACLK_GATE: + if(enable == true) + sysctl_media_clk->isp_clken_cfg |= (1 << 14); + else + sysctl_media_clk->isp_clken_cfg &= ~(1 << 14); + break; + + case SYSCTL_CLK_DDRC_P1CLK_GATE: + if(enable == true) + sysctl_media_clk->ddr_clk_cfg |= (1 << 4); + else + sysctl_media_clk->ddr_clk_cfg &= ~(1 << 4); + break; + + case SYSCTL_CLK_ISP_DWECLK_GATE: + if(enable == true) + sysctl_media_clk->isp_clken_cfg |= (1 << 15); + else + sysctl_media_clk->isp_clken_cfg &= ~(1 << 15); + break; + + case SYSCTL_CLK_ISP_VSECLK_GATE: + if(enable == true) + sysctl_media_clk->isp_clken_cfg |= (1 << 16); + else + sysctl_media_clk->isp_clken_cfg &= ~(1 << 16); + break; + + /*--------------------------- DPU CLOCK ------------------------------------*/ + case SYSCTL_CLK_DPU_CLK: + if(enable == true) + sysctl_media_clk->dpu_clk_cfg |= (1 << 0); + else + sysctl_media_clk->dpu_clk_cfg &= ~(1 << 0); + break; + + case SYSCTL_CLK_DPU_ACLK_GATE: + if(enable == true) + sysctl_media_clk->dpu_clk_cfg |= (1 << 1); + else + sysctl_media_clk->dpu_clk_cfg &= ~(1 << 1); + break; + + case SYSCTL_CLK_DPU_PCLK: + if(enable == true) + sysctl_media_clk->dpu_clk_cfg |= (1 << 2); + else + sysctl_media_clk->dpu_clk_cfg &= ~(1 << 2); + break; + + /*--------------------------- DISP CLOCK ------------------------------------*/ + case SYSCTL_CLK_DISP_GPU: + if(enable == true) + sysctl_media_clk->vo_clk_cfg |= (1 << 6); + else + sysctl_media_clk->vo_clk_cfg &= ~(1 << 6); + break; + + case SYSCTL_CLK_DPIPCLK: + if(enable == true) + sysctl_media_clk->vo_clk_cfg |= (1 << 2); + else + sysctl_media_clk->vo_clk_cfg &= ~(1 << 2); + break; + + default: + break; + } +} + +/* 获取本时钟节点的enable状态 */ +bool sysctl_meida_clk_get_leaf_en(sysctl_media_clk_node_e leaf) +{ + switch(leaf) + { + /*--------------------------- CPU1 CLOCK ------------------------------------*/ + case SYSCTL_CLK_CPU_1_SRC: + return (0 == ((sysctl_media_clk->cpu1_clk_cfg >> 0) & 0x1)) ? false : true; + case SYSCTL_CLK_CPU_1_PLIC: + return (0 == ((sysctl_media_clk->cpu1_clk_cfg >> 15) & 0x1)) ? false : true; + case SYSCTL_CLK_CPU_1_ACLK: + return true; + case SYSCTL_CLK_CPU_1_NOC_DDRCP0: + return (0 == ((sysctl_media_clk->ddr_clk_cfg >> 3) & 0x1)) ? false : true; + case SYSCTL_CLK_CPU_1_PCLK: + return (0 == ((sysctl_media_clk->cpu1_clk_cfg >> 19) & 0x1)) ? false : true; + + /*--------------------------- AI CLOCK ------------------------------------*/ + case SYSCTL_CLK_AI_SRC: + return (0 == ((sysctl_media_clk->ai_clk_cfg >> 0) & 0x1)) ? false : true; + case SYSCTL_CLK_AI_ACLK: + return (0 == ((sysctl_media_clk->ai_clk_cfg >> 10) & 0x1)) ? false : true; + case SYSCTL_CLK_AI_DDRCP3: + return (0 == ((sysctl_media_clk->ddr_clk_cfg >> 6) & 0x1)) ? false : true; + + /*--------------------------- VPU CLOCK ------------------------------------*/ + case SYSCTL_CLK_VPU_SRC: + return (0 == ((sysctl_media_clk->vpu_clk_cfg >> 0) & 0x1)) ? false : true; + case SYSCTL_CLK_VPU_ACLK_SRC: + return true; + case SYSCTL_CLK_VPU_ACLK: + return (0 == ((sysctl_media_clk->vpu_clk_cfg >> 5) & 0x1)) ? false : true; + case SYSCTL_CLK_VPU_DDRCP2: + return (0 == ((sysctl_media_clk->ddr_clk_cfg >> 5) & 0x1)) ? false : true; + case SYSCTL_CLK_VPU_CFG: + return (0 == ((sysctl_media_clk->vpu_clk_cfg >> 10) & 0x1)) ? false : true; + + case SYSCTL_CLK_AUDIO_PCLK_GATE: + return (0 == ((sysctl_media_clk->ls_clken_cfg0 >> 13) & 0x1)) ? false : true; + case SYSCTL_CLK_CODEC_PCLK_GATE: + return (0 == ((sysctl_media_clk->ls_clken_cfg0 >> 14) & 0x1)) ? false : true; + + case SYSCTL_CLK_CODEC_ADC_MCLK: + return (0 == ((sysctl_media_clk->ls_clken_cfg0 >> 29) & 0x1)) ? false : true; + case SYSCTL_CLK_CODEC_DAC_MCLK: + return (0 == ((sysctl_media_clk->ls_clken_cfg0 >> 30) & 0x1)) ? false : true; + case SYSCTL_CLK_AUDIO_DEV_CLK: + return (0 == ((sysctl_media_clk->ls_clken_cfg0 >> 28) & 0x1)) ? false : true; + case SYSCTL_CLK_PDM_CLK: + return (0 == ((sysctl_media_clk->ls_clken_cfg0 >> 31) & 0x1)) ? false : true; + + /*--------------------------- ISP CLOCK ------------------------------------*/ + case SYSCTL_CLK_ISP_CFG_CLK: + return (0 == ((sysctl_media_clk->isp_clken_cfg >> 0) & 0x1)) ? false : true; + case SYSCTL_CLK_CSI_0_PIXEL_CLK: + return (0 == ((sysctl_media_clk->isp_clken_cfg >> 6) & 0x1)) ? false : true; + case SYSCTL_CLK_CSI_1_PIXEL_CLK: + return (0 == ((sysctl_media_clk->isp_clken_cfg >> 7) & 0x1)) ? false : true; + case SYSCTL_CLK_CSI_2_PIXEL_CLK: + return (0 == ((sysctl_media_clk->isp_clken_cfg >> 8) & 0x1)) ? false : true; + + case SYSCTL_CLK_MCLK_0: + return (0 == ((sysctl_media_clk->mclk_cfg >> 0) & 0x1)) ? false : true; + case SYSCTL_CLK_MCLK_1: + return (0 == ((sysctl_media_clk->mclk_cfg >> 1) & 0x1)) ? false : true; + case SYSCTL_CLK_MCLK_2: + return (0 == ((sysctl_media_clk->mclk_cfg >> 2) & 0x1)) ? false : true; + + case SYSCTL_CLK_ISP_CLK: + return (0 == ((sysctl_media_clk->isp_clken_cfg >> 12) & 0x1)) ? false : true; + case SYSCTL_CLK_ISP_MEM_CLK_GATE: + return (0 == ((sysctl_media_clk->isp_clken_cfg >> 17) & 0x1)) ? false : true; + + case SYSCTL_CLK_ISP_HCLK: + return (0 == ((sysctl_media_clk->isp_clken_cfg >> 13) & 0x1)) ? false : true; + + case SYSCTL_CLK_ISP_ACLK_GATE: + return (0 == ((sysctl_media_clk->isp_clken_cfg >> 14) & 0x1)) ? false : true; + case SYSCTL_CLK_DDRC_P1CLK_GATE: + return (0 == ((sysctl_media_clk->isp_clken_cfg >> 4) & 0x1)) ? false : true; + + case SYSCTL_CLK_ISP_DWECLK_GATE: + return (0 == ((sysctl_media_clk->isp_clken_cfg >> 15) & 0x1)) ? false : true; + case SYSCTL_CLK_ISP_VSECLK_GATE: + return (0 == ((sysctl_media_clk->isp_clken_cfg >> 16) & 0x1)) ? false : true; + + /*--------------------------- DPU CLOCK ------------------------------------*/ + case SYSCTL_CLK_DPU_CLK: + return (0 == ((sysctl_media_clk->dpu_clk_cfg >> 0) & 0x1)) ? false : true; + case SYSCTL_CLK_DPU_ACLK_GATE: + return (0 == ((sysctl_media_clk->dpu_clk_cfg >> 1) & 0x1)) ? false : true; + case SYSCTL_CLK_DPU_PCLK: + return (0 == ((sysctl_media_clk->dpu_clk_cfg >> 2) & 0x1)) ? false : true; + + default: + return true; + } +} + +/* 设置本时钟节点的分频系数, freq = root_freq * numerator / denominator */ +bool sysctl_media_clk_set_leaf_div(sysctl_media_clk_node_e leaf, uint32_t numerator, uint32_t denominator) +{ + volatile uint32_t ret; + + if(denominator == 0) + return false; + + switch(leaf) + { + /*--------------------------- CPU0 CLOCK ------------------------------------*/ + case SYSCTL_CLK_CPU_0_SRC: + { + if((numerator > 16) || (numerator < 1) || (denominator != 16)) + return false; + else + { + /* 1/16 --- 16/16 */ + ret = sysctl_media_clk->cpu0_clk_cfg; + ret &= 0xffffffe1; + sysctl_media_clk->cpu0_clk_cfg = ret | (((numerator - 1) << 1) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_CPU_0_PLIC: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->cpu0_clk_cfg; + ret &= 0xffffe3ff; + sysctl_media_clk->cpu0_clk_cfg = ret | (((denominator - 1) << 10) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_CPU_0_ACLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->cpu0_clk_cfg; + ret &= 0xfffffe3f; + sysctl_media_clk->cpu0_clk_cfg = ret | (((denominator - 1) << 6) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_CPU_0_NOC_DDRCP4: + return false; + case SYSCTL_CLK_CPU_0_PCLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->cpu0_clk_cfg; + ret &= 0xffffc7ff; + sysctl_media_clk->cpu0_clk_cfg = ret | (((denominator - 1) << 15) | (1 << 31)); + return true; + } + } + + /*--------------------------- CPU1 CLOCK ------------------------------------*/ + case SYSCTL_CLK_CPU_1_SRC: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->cpu1_clk_cfg; + ret &= 0xffffffc7; + sysctl_media_clk->cpu1_clk_cfg = ret | (((denominator - 1) << 3) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_CPU_1_PLIC: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->cpu1_clk_cfg; + ret &= 0xfff8ffff; + sysctl_media_clk->cpu1_clk_cfg = ret | (((denominator - 1) << 16) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_CPU_1_ACLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->cpu1_clk_cfg; + ret &= 0xffff8fff; + sysctl_media_clk->cpu1_clk_cfg = ret | (((denominator - 1) << 12) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_CPU_1_NOC_DDRCP0: + return false; + + case SYSCTL_CLK_CPU_1_PCLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->cpu0_clk_cfg; + ret &= 0xffffc7ff; + sysctl_media_clk->cpu0_clk_cfg = ret | (((denominator - 1) << 15) | (1 << 31)); + return true; + } + } + /*--------------------------- AI CLOCK ------------------------------------*/ + case SYSCTL_CLK_AI_SRC: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->ai_clk_cfg; + ret &= 0xffffffc7; + sysctl_media_clk->ai_clk_cfg = ret | (((denominator - 1) << 3) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_AI_ACLK: + case SYSCTL_CLK_AI_DDRCP3: + return false; + + /*--------------------------- VPU CLOCK ------------------------------------*/ + case SYSCTL_CLK_VPU_SRC: + { + if((numerator > 16) || (numerator < 1) || (denominator != 16)) + return false; + else + { + /* 1/16 --- 16/16 */ + ret = sysctl_media_clk->vpu_clk_cfg; + ret &= 0xffffffe1; + sysctl_media_clk->vpu_clk_cfg = ret | (((numerator - 1) << 1) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_VPU_ACLK_SRC: + { + if((numerator != 1) || (denominator < 1) || (denominator > 16)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/16 */ + ret = sysctl_media_clk->vpu_clk_cfg; + ret &= 0xfffffc3f; + sysctl_media_clk->vpu_clk_cfg = ret | (((denominator - 1) << 6) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_VPU_ACLK: + case SYSCTL_CLK_VPU_DDRCP2: + return false; + case SYSCTL_CLK_VPU_CFG: + { + if((numerator != 1) || (denominator < 1) || (denominator > 16)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/16 */ + ret = sysctl_media_clk->vpu_clk_cfg; + ret &= 0xffff87ff; + sysctl_media_clk->vpu_clk_cfg = ret | (((denominator - 1) << 11) | (1 << 31)); + return true; + } + } + + /*--------------------------- PMU CLOCK ------------------------------------*/ + case SYSCTL_CLK_PMU_PCLK: + return false; + + /*--------------------------- HS CLOCK ------------------------------------*/ + case SYSCTL_CLK_HS_HCLK_HIGH_SRC: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->hs_sdclk_cfg; + ret &= 0xfffffff8; + sysctl_media_clk->hs_sdclk_cfg = ret | (((denominator - 1) << 0) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_HS_HCLK_HIGH_GATE: + return false; + + case SYSCTL_CLK_HS_HCLK_SRC: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->hs_sdclk_cfg; + ret &= 0xffffffc7; + sysctl_media_clk->hs_sdclk_cfg = ret | (((denominator - 1) << 3) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_SD_0_HCLK_GATE: + case SYSCTL_CLK_SD_1_HCLK_GATE: + case SYSCTL_CLK_USB_0_HCLK_GATE: + case SYSCTL_CLK_USB_1_HCLK_GATE: + case SYSCTL_CLK_SSI_1_HCLK_GATE: + case SYSCTL_CLK_SSI_2_HCLK_GATE: + return false; + + case SYSCTL_CLK_SSI_0_ACLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->hs_spi_cfg; + ret &= 0xfffff1ff; + sysctl_media_clk->hs_spi_cfg = ret | (((denominator - 1) << 9) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_SSI_1_CLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->hs_spi_cfg; + ret &= 0xffffffc7; + sysctl_media_clk->hs_spi_cfg = ret | (((denominator - 1) << 3) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_SSI_2_CLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->hs_spi_cfg; + ret &= 0xfffffe3f; + sysctl_media_clk->hs_spi_cfg = ret | (((denominator - 1) << 6) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_QSPI_ACLK_SRC: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->hs_spi_cfg; + ret &= 0xffff8fff; + sysctl_media_clk->hs_spi_cfg = ret | (((denominator - 1) << 12) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_SSI_1_ACLK_GATE: + case SYSCTL_CLK_SSI_2_ACLK_GATE: + return false; + + case SYSCTL_CLK_SSI_0_CLK: + return false; + + case SYSCTL_CLK_SD_ACLK_SRC: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->hs_sdclk_cfg; + ret &= 0xfffffe3f; + sysctl_media_clk->hs_sdclk_cfg = ret | (((denominator - 1) << 6) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_SD_0_ACLK_GATE: + case SYSCTL_CLK_SD_1_ACLK_GATE: + case SYSCTL_CLK_SD_0_BCLK_GATE: + case SYSCTL_CLK_SD_1_BCLK_GATE: + return false; + + case SYSCTL_CLK_SD_CCLK_SRC: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->hs_sdclk_cfg; + ret &= 0xffff8fff; + sysctl_media_clk->hs_sdclk_cfg = ret | (((denominator - 1) << 12) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_SD_0_CCLK_GATE: + case SYSCTL_CLK_SD_1_CCLK_GATE: + return false; + + case SYSCTL_CLK_PLL0_DIV_16: + return false; + case SYSCTL_CLK_USB_REF_50M: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->hs_spi_cfg; + ret &= 0xfffc7fff; + sysctl_media_clk->hs_spi_cfg = ret | (((denominator - 1) << 15) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_USB_0_REF_CLK: + case SYSCTL_CLK_USB_1_REF_CLK: + return false; + + case SYSCTL_CLK_SD_TMCLK_SRC: + { + if((numerator != 1) || (denominator < 1) || (denominator > 32)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/32 */ + ret = sysctl_media_clk->hs_sdclk_cfg; + ret &= 0xfff07fff; + sysctl_media_clk->hs_sdclk_cfg = ret | (((denominator - 1) << 15) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_SD_0_TMCLK_GATE: + case SYSCTL_CLK_SD_1_TMCLK_GATE: + return false; + + /*--------------------------- LS CLOCK ------------------------------------*/ + case SYSCTL_CLK_LS_PCLK_SRC: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/4, 1/8 --- 1/8 */ + ret = sysctl_media_clk->ls_clkdiv_cfg; + ret &= 0xfffffff8; + sysctl_media_clk->ls_clkdiv_cfg = ret | (((denominator - 1) << 0) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_UART_0_PCLK_GATE: + case SYSCTL_CLK_UART_1_PCLK_GATE: + case SYSCTL_CLK_UART_2_PCLK_GATE: + case SYSCTL_CLK_UART_3_PCLK_GATE: + case SYSCTL_CLK_UART_4_PCLK_GATE: + case SYSCTL_CLK_I2C_0_PCLK_GATE: + case SYSCTL_CLK_I2C_1_PCLK_GATE: + case SYSCTL_CLK_I2C_2_PCLK_GATE: + case SYSCTL_CLK_I2C_3_PCLK_GATE: + case SYSCTL_CLK_I2C_4_PCLK_GATE: + case SYSCTL_CLK_GPIO_PCLK_GATE: + case SYSCTL_CLK_PWM_PCLK_GATE: + case SYSCTL_CLK_JAMLINK_0_PCLK_GATE: + case SYSCTL_CLK_JAMLINK_1_PCLK_GATE: + case SYSCTL_CLK_JAMLINK_2_PCLK_GATE: + case SYSCTL_CLK_JAMLINK_3_PCLK_GATE: + case SYSCTL_CLK_AUDIO_PCLK_GATE: + case SYSCTL_CLK_ADC_PCLK_GATE: + case SYSCTL_CLK_CODEC_PCLK_GATE: + return false; + + case SYSCTL_CLK_UART_0_CLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->uart_i2c_clkdiv_cfg; + ret &= 0xfffffff8; + sysctl_media_clk->uart_i2c_clkdiv_cfg = ret | (((denominator - 1) << 0) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_UART_1_CLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->uart_i2c_clkdiv_cfg; + ret &= 0xffffffc7; + sysctl_media_clk->uart_i2c_clkdiv_cfg = ret | (((denominator - 1) << 3) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_UART_2_CLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->uart_i2c_clkdiv_cfg; + ret &= 0xfffffe3f; + sysctl_media_clk->uart_i2c_clkdiv_cfg = ret | (((denominator - 1) << 6) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_UART_3_CLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->uart_i2c_clkdiv_cfg; + ret &= 0xfffff1ff; + sysctl_media_clk->uart_i2c_clkdiv_cfg = ret | (((denominator - 1) << 9) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_UART_4_CLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->uart_i2c_clkdiv_cfg; + ret &= 0xffff8fff; + sysctl_media_clk->uart_i2c_clkdiv_cfg = ret | (((denominator - 1) << 12) | (1 << 31)); + return true; + } + } + + case SYSCTL_CLK_JAMLINKCO_DIV: + { + if((numerator != 1) || (denominator < 2) || (denominator > 512) || (denominator % 2 != 0)) + return false; + else + { + /* 1/2, 1/4, 1/8 --- 1/512 */ + ret = sysctl_media_clk->ls_clkdiv_cfg; + ret &= 0x807fffff; + sysctl_media_clk->ls_clkdiv_cfg = ret | (((denominator/2 - 1) << 23) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_JAMLINK_0_CO_GATE: + case SYSCTL_CLK_JAMLINK_1_CO_GATE: + case SYSCTL_CLK_JAMLINK_2_CO_GATE: + case SYSCTL_CLK_JAMLINK_3_CO_GATE: + return false; + + case SYSCTL_CLK_I2C_0_CLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->uart_i2c_clkdiv_cfg; + ret &= 0xfffc7fff; + sysctl_media_clk->uart_i2c_clkdiv_cfg = ret | (((denominator - 1) << 15) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_I2C_1_CLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->uart_i2c_clkdiv_cfg; + ret &= 0xffe3ffff; + sysctl_media_clk->uart_i2c_clkdiv_cfg = ret | (((denominator - 1) << 18) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_I2C_2_CLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->uart_i2c_clkdiv_cfg; + ret &= 0xff1fffff; + sysctl_media_clk->uart_i2c_clkdiv_cfg = ret | (((denominator - 1) << 21) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_I2C_3_CLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->uart_i2c_clkdiv_cfg; + ret &= 0xf8ffffff; + sysctl_media_clk->uart_i2c_clkdiv_cfg = ret | (((denominator - 1) << 24) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_I2C_4_CLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->uart_i2c_clkdiv_cfg; + ret &= 0xc7ffffff; + sysctl_media_clk->uart_i2c_clkdiv_cfg = ret | (((denominator - 1) << 27) | (1 << 31)); + return true; + } + } + + case SYSCTL_CLK_CODEC_ADC_MCLK: + { + if((numerator < 0x10) || (numerator > 0x1B9) || (denominator < 0xC35) || (denominator > 0x3D09)) + return false; + if(numerator * 2 > denominator) //根据文档描述,max_sum的设定值至少是inc_step设定值的2倍以上 + return false; + + ret = sysctl_media_clk->codec_adc_mclkdiv_cfg; + ret &= 0xf8000000; + sysctl_media_clk->codec_adc_mclkdiv_cfg = ret | ((numerator << 14) | (denominator << 0) | (1 << 31)); + return true; + } + case SYSCTL_CLK_CODEC_DAC_MCLK: + { + if((numerator < 0x10) || (numerator > 0x1B9) || (denominator < 0xC35) || (denominator > 0x3D09)) + return false; + if(numerator * 2 > denominator) //根据文档描述,max_sum的设定值至少是inc_step设定值的2倍以上 + return false; + + ret = sysctl_media_clk->codec_dac_mclkdiv_cfg; + ret &= 0xf8000000; + sysctl_media_clk->codec_dac_mclkdiv_cfg = ret | ((numerator << 14) | (denominator << 0) | (1 << 31)); + return true; + } + case SYSCTL_CLK_AUDIO_DEV_CLK: + { + if((numerator < 0x4) || (numerator > 0x1B9) || (denominator < 0xC35) || (denominator > 0xF424)) + return false; + if(numerator * 2 > denominator) //根据文档描述,max_sum的设定值至少是inc_step设定值的2倍以上 + return false; + + ret = sysctl_media_clk->audio_clkdiv_cfg; + ret &= 0x80000000; + sysctl_media_clk->audio_clkdiv_cfg = ret | ((numerator << 16) | (denominator << 0) | (1 << 31)); + // ret |= ((numerator << 16) | (denominator << 0)); + // ret |= (1 << 31); + // sysctl_media_clk->audio_clkdiv_cfg = ret; + return true; + } + + //review。注意,此处需要与clock_provider.dtsi保持一致,dtsi可能会被改变。 + //后者不需要按照dtsi再修改,此处代码已经写好,即在配置寄存器的时候,配置两个寄存器即可。 + case SYSCTL_CLK_PDM_CLK: + { + if((numerator < 0x2) || (numerator > 0x1B9) || (denominator < 0xC35) || (denominator > 0x1E848)) + return false; + if(numerator * 2 > denominator) //根据文档描述,max_sum的设定值至少是inc_step设定值的2倍以上 + return false; + + // sysctl_media_clk->pdm_clkdiv_cfg0 = ((numerator << 32) | (denominator << 0) | (1 << 63)); + sysctl_media_clk->pdm_clkdiv_cfg0 = (denominator << 0); + sysctl_media_clk->pdm_clkdiv_cfg1 = ((numerator << 0) | (1 << 31)); + return true; + } + #if 0 + case SYSCTL_CLK_SUM_DIV: + { + if((numerator != 1) || (denominator < 3125) || (denominator > 125000)) + return false; + else + { + /* 1/3125 --- 1/125000 */ + ret = sysctl_media_clk->pdm_clkdiv_cfg0; + ret &= 0xfffe0000; + sysctl_media_clk->pdm_clkdiv_cfg0 = ret | ((denominator) << 0); + return true; + } + } + + case SYSCTL_CLK_STEP_DIV: + { + if((numerator > 441) || (numerator < 2) || (denominator != 1)) + return false; + else + { + /* 2/1 --- 441/1 */ + ret = sysctl_media_clk->pdm_clkdiv_cfg1; + ret &= 0xffff0000; + sysctl_media_clk->pdm_clkdiv_cfg1 = ret | (((numerator) << 0) | (1 << 31)); + return true; + } + } + + case SYSCTL_CLK_PDM_CLK_GATE: + return false; +#endif + + case SYSCTL_CLK_ADC_CLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 1024)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/1024 */ + ret = sysctl_media_clk->ls_clkdiv_cfg; + ret &= 0xffffe007; + sysctl_media_clk->ls_clkdiv_cfg = ret | (((denominator - 1) << 3) | (1 << 31)); + return true; + } + } + + case SYSCTL_CLK_GPIO_DBCLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 1024)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/1024 */ + ret = sysctl_media_clk->ls_clkdiv_cfg; + ret &= 0xff801fff; + sysctl_media_clk->ls_clkdiv_cfg = ret | (((denominator - 1) << 13) | (1 << 31)); + return true; + } + } + + /*--------------------------- SYSCTL CLOCK ------------------------------------*/ + case SYSCTL_CLK_PCLK: + return false; + case SYSCTL_CLK_WDT_0_PCLK_GATE: + case SYSCTL_CLK_WDT_1_PCLK_GATE: + case SYSCTL_CLK_TIMER_PCLK_GATE: + case SYSCTL_CLK_IOMUX_PCLK_GATE: + case SYSCTL_CLK_MAILBOX_PCLK_GATE: + return false; + + case SYSCTL_CLK_HDI_CLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->sysctl_clk_div_cfg; + ret &= 0x8fffffff; + sysctl_media_clk->sysctl_clk_div_cfg = ret | (((denominator - 1) << 28) | (1 << 31)); + return true; + } + } + + case SYSCTL_CLK_STC_CLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 32)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/32 */ + ret = sysctl_media_clk->sysctl_clk_div_cfg; + ret &= 0xfff07fff; + sysctl_media_clk->sysctl_clk_div_cfg = ret | (((denominator - 1) << 15) | (1 << 31)); + return true; + } + } + + case SYSCTL_CLK_TS_CLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 256)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/256 */ + ret = sysctl_media_clk->sysctl_clk_div_cfg; + ret &= 0xf00fffff; + sysctl_media_clk->sysctl_clk_div_cfg = ret | (((denominator - 1) << 20) | (1 << 31)); + return true; + } + } + + /*--------------------------- TIMER CLOCK ------------------------------------*/ + case SYSCTL_CLK_TIMERX_PULSE_IN: + return false; + case SYSCTL_CLK_TIMER_0_SRC: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->timer_clk_cfg; + ret &= 0xfffffff8; + sysctl_media_clk->timer_clk_cfg = ret | (((denominator - 1) << 0) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_TIMER_0_CLK: + return false; + + case SYSCTL_CLK_TIMER_1_SRC: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->timer_clk_cfg; + ret &= 0xffffffc7; + sysctl_media_clk->timer_clk_cfg = ret | (((denominator - 1) << 3) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_TIMER_1_CLK: + return false; + + case SYSCTL_CLK_TIMER_2_SRC: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->timer_clk_cfg; + ret &= 0xfffffe3f; + sysctl_media_clk->timer_clk_cfg = ret | (((denominator - 1) << 6) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_TIMER_2_CLK: + return false; + + case SYSCTL_CLK_TIMER_3_SRC: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->timer_clk_cfg; + ret &= 0xfffff1ff; + sysctl_media_clk->timer_clk_cfg = ret | (((denominator - 1) << 9) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_TIMER_3_CLK: + return false; + + case SYSCTL_CLK_TIMER_4_SRC: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->timer_clk_cfg; + ret &= 0xffff8fff; + sysctl_media_clk->timer_clk_cfg = ret | (((denominator - 1) << 12) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_TIMER_4_CLK: + return false; + + /*--------------------------- SHRM CLOCK ------------------------------------*/ + case SYSCTL_CLK_SHRM_SRC: + return false; + case SYSCTL_CLK_SHRM_DIV_2: + return false; + case SYSCTL_CLK_SHRM_AXIS_CLK_GATE: + case SYSCTL_CLK_DECOMPRESS_ACLK_GATE: + return false; + + case SYSCTL_CLK_SHRM_PCLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->shrm_clk_cfg; + ret &= 0xffe3ffff; + sysctl_media_clk->shrm_clk_cfg = ret | (((denominator - 1) << 18) | (1 << 31)); + return true; + } + } + + case SYSCTL_CLK_SHRM_AXIM_CLK_GATE: + case SYSCTL_CLK_GSDMA_ACLK_GATE: + case SYSCTL_CLK_NONAI2D_ACLK_GATE: + case SYSCTL_CLK_PDMA_ACLK_GATE: + return false; + + /*--------------------------- DDR CLOCK ------------------------------------*/ + case SYSCTL_CLK_DDRC_CORE_CLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 16)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/16 */ + ret = sysctl_media_clk->ddr_clk_cfg; + ret &= 0xffffc3ff; + sysctl_media_clk->ddr_clk_cfg = ret | (((denominator - 1) << 10) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_DDRC_BYPASS_GATE: + return false; + case SYSCTL_CLK_DDRC_PCLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 16)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/16 */ + ret = sysctl_media_clk->ddr_clk_cfg; + ret &= 0xfffc3fff; + sysctl_media_clk->ddr_clk_cfg = ret | (((denominator - 1) << 14) | (1 << 31)); + return true; + } + } + + /*--------------------------- ISP CLOCK ------------------------------------*/ + case SYSCTL_CLK_ISP_CFG_CLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 32)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/32 */ + ret = sysctl_media_clk->isp_clkdiv_cfg; + ret &= 0xffffffe0; + sysctl_media_clk->isp_clkdiv_cfg = ret | (((denominator - 1) << 0) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_CSI_0_PIXEL_CLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 64)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/64 */ + ret = sysctl_media_clk->isp_clkdiv_cfg; + ret &= 0xfffff81f; + sysctl_media_clk->isp_clkdiv_cfg = ret | (((denominator - 1) << 5) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_CSI_1_PIXEL_CLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 64)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/64 */ + ret = sysctl_media_clk->isp_clkdiv_cfg; + ret &= 0xfffe07ff; + sysctl_media_clk->isp_clkdiv_cfg = ret | (((denominator - 1) << 11) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_CSI_2_PIXEL_CLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 64)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/64 */ + ret = sysctl_media_clk->isp_clkdiv_cfg; + ret &= 0xff81ffff; + sysctl_media_clk->isp_clkdiv_cfg = ret | (((denominator - 1) << 17) | (1 << 31)); + return true; + } + } + + case SYSCTL_CLK_MCLK_0: + { + if((numerator != 1) || (denominator < 1) || (denominator > 32)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/32 */ + ret = sysctl_media_clk->mclk_cfg; + ret &= 0xfffffc1f; + sysctl_media_clk->mclk_cfg = ret | (((denominator - 1) << 5) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_MCLK_1: + { + if((numerator != 1) || (denominator < 1) || (denominator > 32)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/32 */ + ret = sysctl_media_clk->mclk_cfg; + ret &= 0xfffe0fff; + sysctl_media_clk->mclk_cfg = ret | (((denominator - 1) << 12) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_MCLK_2: + { + if((numerator != 1) || (denominator < 1) || (denominator > 32)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/32 */ + ret = sysctl_media_clk->mclk_cfg; + ret &= 0xff07ffff; + sysctl_media_clk->mclk_cfg = ret | (((denominator - 1) << 19) | (1 << 31)); + return true; + } + } + + case SYSCTL_CLK_ISP_CLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->isp_clkdiv_cfg; + ret &= 0xe3ffffff; + sysctl_media_clk->isp_clkdiv_cfg = ret | (((denominator - 1) << 26) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_ISP_MEM_CLK_GATE: + return false; + + case SYSCTL_CLK_ISP_HCLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->isp_clkdiv_cfg; + ret &= 0xfc7fffff; + sysctl_media_clk->isp_clkdiv_cfg = ret | (((denominator - 1) << 23) | (1 << 31)); + return true; + } + } + + case SYSCTL_CLK_ISP_ACLK_GATE: + case SYSCTL_CLK_DDRC_P1CLK_GATE: + return false; + + case SYSCTL_CLK_ISP_DWECLK_GATE: + case SYSCTL_CLK_ISP_VSECLK_GATE: + return false; + + /*--------------------------- DPU CLOCK ------------------------------------*/ + case SYSCTL_CLK_DPU_CLK: + { + if((numerator > 16) || (numerator < 1) || (denominator != 16)) + return false; + else + { + /* 1/16, 2/16, 3/16 --- 16/16 */ + ret = sysctl_media_clk->dpu_clk_cfg; + ret &= 0xffffff87; + sysctl_media_clk->dpu_clk_cfg = ret | (((numerator - 1) << 3) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_DPU_ACLK_GATE: + return false; + case SYSCTL_CLK_DPU_PCLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->dpu_clk_cfg; + ret &= 0xfffffc7f; + sysctl_media_clk->dpu_clk_cfg = ret | (((denominator - 1) << 7) | (1 << 31)); + return true; + } + } + + /*--------------------------- DISPLAY CLOCK ------------------------------------*/ + case SYSCTL_CLK_DISP_HCLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->disp_clk_div; + ret &= 0xfffffff8; + sysctl_media_clk->disp_clk_div = ret | (((denominator - 1) << 0) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_DISP_ACLK_GATE: + return false; + + case SYSCTL_CLK_DISP_CLKEXT: + { + if((numerator != 1) || (denominator < 1) || (denominator > 16)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/16 */ + ret = sysctl_media_clk->disp_clk_div; + ret &= 0xfff0ffff; + sysctl_media_clk->disp_clk_div = ret | (((denominator - 1) << 16) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_DISP_GPU: + { + if((numerator != 1) || (denominator < 1) || (denominator > 16)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/16 */ + ret = sysctl_media_clk->disp_clk_div; + ret &= 0xff0fffff; + sysctl_media_clk->disp_clk_div = ret | (((denominator - 1) << 20) | (1 << 31)); + return true; + } + } + + case SYSCTL_CLK_DPIPCLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 256)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/256 */ + ret = sysctl_media_clk->disp_clk_div; + ret &= 0xfffff807; + sysctl_media_clk->disp_clk_div = ret | (((denominator - 1) << 3) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_DISP_CFGCLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 32)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/32 */ + ret = sysctl_media_clk->disp_clk_div; + ret &= 0xffff07ff; + sysctl_media_clk->disp_clk_div = ret | (((denominator - 1) << 11) | (1 << 31)); + return true; + } + } + + case SYSCTL_CLK_DISP_REFCLK_GATE: + return false; + + /*--------------------------- SEC CLOCK ------------------------------------*/ + case SYSCTL_CLK_SEC_PCLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->sec_clk_div; + ret &= 0xfffffff1; + sysctl_media_clk->sec_clk_div = ret | (((denominator - 1) << 1) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_SEC_FIXCLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 32)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/32 */ + ret = sysctl_media_clk->sec_clk_div; + ret &= 0xfffff83f; + sysctl_media_clk->sec_clk_div = ret | (((denominator - 1) << 6) | (1 << 31)); + return true; + } + } + + case SYSCTL_CLK_SEC_ACLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->sec_clk_div; + ret &= 0xffffc7ff; + sysctl_media_clk->sec_clk_div = ret | (((denominator - 1) << 11) | (1 << 31)); + return true; + } + } + + /*--------------------------- USB TEST MODE CLOCK ------------------------------------*/ + case SYSCTL_CLK_USB_CLK_480: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->usb_test_clk_div; + ret &= 0xfffffff1; + sysctl_media_clk->usb_test_clk_div = ret | (((denominator - 1) << 1) | (1 << 31)); + return true; + } + } + case SYSCTL_CLK_USB_CLK_100: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->usb_test_clk_div; + ret &= 0xffffff8f; + sysctl_media_clk->usb_test_clk_div = ret | (((denominator - 1) << 4) | (1 << 31)); + return true; + } + } + + /*--------------------------- DPHY DFT MODE CLOCK ------------------------------------*/ + case SYSCTL_CLK_DPHY_TEST_CLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 16)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/16 */ + ret = sysctl_media_clk->dphy_test_clk_div; + ret &= 0xffffffe1; + sysctl_media_clk->dphy_test_clk_div = ret | (((denominator - 1) << 1) | (1 << 31)); + return true; + } + } + + /*--------------------------- SPI2AXI CLOCK ------------------------------------*/ + case SYSCTL_CLK_SPI2AXI_ACLK: + { + if((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + else + { + /* 1/1, 1/2, 1/3 --- 1/8 */ + ret = sysctl_media_clk->spi2axi_clk_div; + ret &= 0xfffffff1; + sysctl_media_clk->spi2axi_clk_div = ret | (((denominator - 1) << 1) | (1 << 31)); + return true; + } + } + + default: + return false; + } +} + +/* 获取本时钟节点的分频系数 */ +double sysctl_media_clk_get_leaf_div(sysctl_media_clk_node_e leaf) +{ + switch(leaf) + { + /*--------------------------- CPU0 CLOCK ------------------------------------*/ + case SYSCTL_CLK_CPU_0_SRC: + return (double)(((sysctl_media_clk->cpu0_clk_cfg >> 1) & 0xF) + 1) / 16.0; /* 1/16 --- 16/16 */ + case SYSCTL_CLK_CPU_0_PLIC: + return 1.0/(double)(((sysctl_media_clk->cpu0_clk_cfg >> 10) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_CPU_0_ACLK: + return 1.0/(double)(((sysctl_media_clk->cpu0_clk_cfg >> 6) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_CPU_0_NOC_DDRCP4: + return 1; + case SYSCTL_CLK_CPU_0_PCLK: + return 1.0/(double)(((sysctl_media_clk->cpu0_clk_cfg >> 15) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + + /*--------------------------- CPU1 CLOCK ------------------------------------*/ + case SYSCTL_CLK_CPU_1_SRC: + return 1.0/(double)(((sysctl_media_clk->cpu1_clk_cfg >> 3) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_CPU_1_PLIC: + return 1.0/(double)(((sysctl_media_clk->cpu1_clk_cfg >> 16) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_CPU_1_ACLK: + return 1.0/(double)(((sysctl_media_clk->cpu1_clk_cfg >> 12) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_CPU_1_NOC_DDRCP0: + return 1; + case SYSCTL_CLK_CPU_1_PCLK: + return 1.0/(double)(((sysctl_media_clk->cpu0_clk_cfg >> 15) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + + /*--------------------------- AI CLOCK ------------------------------------*/ + case SYSCTL_CLK_AI_SRC: + return 1.0/(double)(((sysctl_media_clk->ai_clk_cfg >> 3) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_AI_ACLK: + case SYSCTL_CLK_AI_DDRCP3: + return 1; + + /*--------------------------- VPU CLOCK ------------------------------------*/ + case SYSCTL_CLK_VPU_SRC: + return (double)(((sysctl_media_clk->vpu_clk_cfg >> 1) & 0xF) + 1) / 16.0; /* 1/16 --- 16/16 */ + case SYSCTL_CLK_VPU_ACLK_SRC: + return 1.0/(double)(((sysctl_media_clk->vpu_clk_cfg >> 6) & 0xF) + 1); /* 1/1, 1/2, 1/3 --- 1/16 */ + case SYSCTL_CLK_VPU_ACLK: + case SYSCTL_CLK_VPU_DDRCP2: + return 1; + case SYSCTL_CLK_VPU_CFG: + return 1.0/(double)(((sysctl_media_clk->vpu_clk_cfg >> 11) & 0xF) + 1); /* 1/1, 1/2, 1/3 --- 1/16 */ + + /*--------------------------- PMU CLOCK ------------------------------------*/ + case SYSCTL_CLK_PMU_PCLK: + return 1; + + /*--------------------------- HS CLOCK ------------------------------------*/ + case SYSCTL_CLK_HS_HCLK_HIGH_SRC: + return 1.0/(double)(((sysctl_media_clk->hs_sdclk_cfg >> 0) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_HS_HCLK_HIGH_GATE: + return 1; + case SYSCTL_CLK_HS_HCLK_SRC: + return 1.0/(double)(((sysctl_media_clk->hs_sdclk_cfg >> 3) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_SD_0_HCLK_GATE: + case SYSCTL_CLK_SD_1_HCLK_GATE: + case SYSCTL_CLK_USB_0_HCLK_GATE: + case SYSCTL_CLK_USB_1_HCLK_GATE: + case SYSCTL_CLK_SSI_1_HCLK_GATE: + case SYSCTL_CLK_SSI_2_HCLK_GATE: + return 1; + + case SYSCTL_CLK_SSI_0_ACLK: + return 1.0/(double)(((sysctl_media_clk->hs_spi_cfg >> 9) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_SSI_1_CLK: + return 1.0/(double)(((sysctl_media_clk->hs_spi_cfg >> 3) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_SSI_2_CLK: + return 1.0/(double)(((sysctl_media_clk->hs_spi_cfg >> 6) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_QSPI_ACLK_SRC: + return 1.0/(double)(((sysctl_media_clk->hs_spi_cfg >> 12) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_SSI_1_ACLK_GATE: + case SYSCTL_CLK_SSI_2_ACLK_GATE: + return 1; + + case SYSCTL_CLK_SSI_0_CLK: + return 1; + + case SYSCTL_CLK_SD_ACLK_SRC: + return 1.0/(double)(((sysctl_media_clk->hs_sdclk_cfg >> 6) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_SD_0_ACLK_GATE: + case SYSCTL_CLK_SD_1_ACLK_GATE: + case SYSCTL_CLK_SD_0_BCLK_GATE: + case SYSCTL_CLK_SD_1_BCLK_GATE: + return 1; + + case SYSCTL_CLK_SD_CCLK_SRC: + return 1.0/(double)(((sysctl_media_clk->hs_sdclk_cfg >> 6) & 0x7) + 1); /* maxinum = 1/2, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_SD_0_CCLK_GATE: + case SYSCTL_CLK_SD_1_CCLK_GATE: + return 1; + + case SYSCTL_CLK_PLL0_DIV_16: + return 1.0/16; + case SYSCTL_CLK_USB_REF_50M: + return 1.0/(double)(((sysctl_media_clk->hs_spi_cfg >> 15) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_USB_0_REF_CLK: + case SYSCTL_CLK_USB_1_REF_CLK: + return 1; + + case SYSCTL_CLK_SD_TMCLK_SRC: + return 1.0/(double)(((sysctl_media_clk->hs_sdclk_cfg >> 15) & 0x1F) + 1); /* maxinum = 1/24, 1/24 --- 1/32 */ + case SYSCTL_CLK_SD_0_TMCLK_GATE: + case SYSCTL_CLK_SD_1_TMCLK_GATE: + return 1; + + /*--------------------------- LS CLOCK ------------------------------------*/ + case SYSCTL_CLK_LS_PCLK_SRC: + return 1.0/(double)(((sysctl_media_clk->ls_clkdiv_cfg >> 0) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_UART_0_PCLK_GATE: + case SYSCTL_CLK_UART_1_PCLK_GATE: + case SYSCTL_CLK_UART_2_PCLK_GATE: + case SYSCTL_CLK_UART_3_PCLK_GATE: + case SYSCTL_CLK_UART_4_PCLK_GATE: + case SYSCTL_CLK_I2C_0_PCLK_GATE: + case SYSCTL_CLK_I2C_1_PCLK_GATE: + case SYSCTL_CLK_I2C_2_PCLK_GATE: + case SYSCTL_CLK_I2C_3_PCLK_GATE: + case SYSCTL_CLK_I2C_4_PCLK_GATE: + case SYSCTL_CLK_GPIO_PCLK_GATE: + case SYSCTL_CLK_PWM_PCLK_GATE: + case SYSCTL_CLK_JAMLINK_0_PCLK_GATE: + case SYSCTL_CLK_JAMLINK_1_PCLK_GATE: + case SYSCTL_CLK_JAMLINK_2_PCLK_GATE: + case SYSCTL_CLK_JAMLINK_3_PCLK_GATE: + case SYSCTL_CLK_AUDIO_PCLK_GATE: + case SYSCTL_CLK_ADC_PCLK_GATE: + case SYSCTL_CLK_CODEC_PCLK_GATE: + return 1; + + case SYSCTL_CLK_UART_0_CLK: + return 1.0/(double)(((sysctl_media_clk->uart_i2c_clkdiv_cfg >> 0) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_UART_1_CLK: + return 1.0/(double)(((sysctl_media_clk->uart_i2c_clkdiv_cfg >> 3) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_UART_2_CLK: + return 1.0/(double)(((sysctl_media_clk->uart_i2c_clkdiv_cfg >> 6) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_UART_3_CLK: + return 1.0/(double)(((sysctl_media_clk->uart_i2c_clkdiv_cfg >> 9) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_UART_4_CLK: + return 1.0/(double)(((sysctl_media_clk->uart_i2c_clkdiv_cfg >> 12) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + + case SYSCTL_CLK_JAMLINKCO_DIV: + return 1.0/(double)(2 * (((sysctl_media_clk->ls_clkdiv_cfg >> 23) & 0xFF) + 1)); /* 1/2, 1/4, 1/8 --- 1/512 */ + case SYSCTL_CLK_JAMLINK_0_CO_GATE: + case SYSCTL_CLK_JAMLINK_1_CO_GATE: + case SYSCTL_CLK_JAMLINK_2_CO_GATE: + case SYSCTL_CLK_JAMLINK_3_CO_GATE: + return 1; + + case SYSCTL_CLK_I2C_0_CLK: + return 1.0/(double)(((sysctl_media_clk->uart_i2c_clkdiv_cfg >> 15) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_I2C_1_CLK: + return 1.0/(double)(((sysctl_media_clk->uart_i2c_clkdiv_cfg >> 18) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_I2C_2_CLK: + return 1.0/(double)(((sysctl_media_clk->uart_i2c_clkdiv_cfg >> 21) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_I2C_3_CLK: + return 1.0/(double)(((sysctl_media_clk->uart_i2c_clkdiv_cfg >> 24) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_I2C_4_CLK: + return 1.0/(double)(((sysctl_media_clk->uart_i2c_clkdiv_cfg >> 27) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ +#if 0 + case SYSCTL_CLK_CODEC_ADC_MCLK: + return (double)((sysctl_media_clk->codec_adc_mclkdiv_cfg >> 14) & 0x1B9)/(double)((sysctl_media_clk->codec_adc_mclkdiv_cfg >> 0) & 0x3D09); + case SYSCTL_CLK_CODEC_DAC_MCLK: + return (double)((sysctl_media_clk->codec_dac_mclkdiv_cfg >> 14) & 0x1B9)/(double)((sysctl_media_clk->codec_adc_mclkdiv_cfg >> 0) & 0x3D09); + case SYSCTL_CLK_AUDIO_DEV_CLK: + return (double)((sysctl_media_clk->audio_clkdiv_cfg >> 16) & 0x1B9)/(double)((sysctl_media_clk->codec_adc_mclkdiv_cfg >> 0) & 0xF424); + + //review。注意,此处需要与clock_provider.dtsi保持一致,dtsi可能会被改变。 + //后者不需要按照dtsi再修改,此处代码已经写好,即在配置寄存器的时候,配置两个寄存器即可。 + // case SYSCTL_CLK_PDM_CLK: + // return (double)((sysctl_media_clk->pdm_clkdiv_cfg1 >> 0) & 0x1B9)/(double)((sysctl_media_clk->pdm_clkdiv_cfg0 >> 0) & 0x1E848); + case SYSCTL_CLK_SUM_DIV: + return 1.0/(double)((sysctl_media_clk->pdm_clkdiv_cfg0 >> 0) & 0x1E848); + case SYSCTL_CLK_STEP_DIV: + return (double)((sysctl_media_clk->pdm_clkdiv_cfg1 >> 0) & 0x1B9) / 1.0; + case SYSCTL_CLK_PDM_CLK_GATE: + return 1; +#endif + case SYSCTL_CLK_CODEC_ADC_MCLK: + return (double)((sysctl_media_clk->codec_adc_mclkdiv_cfg >> 14) & 0x1fff)/(double)((sysctl_media_clk->codec_adc_mclkdiv_cfg >> 0) & 0x3fff); + case SYSCTL_CLK_CODEC_DAC_MCLK: + return (double)((sysctl_media_clk->codec_dac_mclkdiv_cfg >> 14) & 0x1fff)/(double)((sysctl_media_clk->codec_dac_mclkdiv_cfg >> 0) & 0x3fff); + case SYSCTL_CLK_AUDIO_DEV_CLK: + return (double)((sysctl_media_clk->audio_clkdiv_cfg >> 16) & 0x7fff)/(double)((sysctl_media_clk->audio_clkdiv_cfg >> 0) & 0xffff); + case SYSCTL_CLK_PDM_CLK: + return (double)((sysctl_media_clk->pdm_clkdiv_cfg1 >> 0) & 0xffff)/(double)((sysctl_media_clk->pdm_clkdiv_cfg0 >> 0) & 0x1ffff); + + +#if 0 + //review。注意,此处需要与clock_provider.dtsi保持一致,dtsi可能会被改变。 + //后者不需要按照dtsi再修改,此处代码已经写好,即在配置寄存器的时候,配置两个寄存器即可。 + // case SYSCTL_CLK_PDM_CLK: + // return (double)((sysctl_media_clk->pdm_clkdiv_cfg1 >> 0) & 0x1B9)/(double)((sysctl_media_clk->pdm_clkdiv_cfg0 >> 0) & 0x1E848); + case SYSCTL_CLK_SUM_DIV: + return 1.0/(double)((sysctl_media_clk->pdm_clkdiv_cfg0 >> 0) & 0x1ffff); + case SYSCTL_CLK_STEP_DIV: + return (double)((sysctl_media_clk->pdm_clkdiv_cfg1 >> 0) & 0xffff) / 1.0; + case SYSCTL_CLK_PDM_CLK_GATE: + return 1; +#endif + + case SYSCTL_CLK_ADC_CLK: + return 1.0/(double)(((sysctl_media_clk->ls_clkdiv_cfg >> 3) & 0x3FF) + 1); /* 1/1, 1/2, 1/3 --- 1/1024 */ + + case SYSCTL_CLK_GPIO_DBCLK: + return 1.0/(double)(((sysctl_media_clk->ls_clkdiv_cfg >> 13) & 0x3FF) + 1); /* 1/1, 1/2, 1/3 --- 1/1024 */ + + /*--------------------------- SYSCTL CLOCK ------------------------------------*/ + case SYSCTL_CLK_PCLK: + // return 1.0/(double)(((sysctl_media_clk->sysctl_clk_div_cfg >> 0) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + return 1; + case SYSCTL_CLK_WDT_0_PCLK_GATE: + case SYSCTL_CLK_WDT_1_PCLK_GATE: + case SYSCTL_CLK_TIMER_PCLK_GATE: + case SYSCTL_CLK_IOMUX_PCLK_GATE: + case SYSCTL_CLK_MAILBOX_PCLK_GATE: + return 1; + + case SYSCTL_CLK_HDI_CLK: + return 1.0/(double)(((sysctl_media_clk->sysctl_clk_div_cfg >> 28) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + + case SYSCTL_CLK_STC_CLK: + return 1.0/(double)(((sysctl_media_clk->sysctl_clk_div_cfg >> 15) & 0x1F) + 1); /* 1/1, 1/2, 1/3 --- 1/32 */ + + case SYSCTL_CLK_TS_CLK: + return 1.0/(double)(((sysctl_media_clk->sysctl_clk_div_cfg >> 20) & 0xFF) + 1); /* 1/1, 1/2, 1/3 --- 1/256 */ + + /*--------------------------- TIMER CLOCK ------------------------------------*/ + case SYSCTL_CLK_TIMERX_PULSE_IN: + return 1; + case SYSCTL_CLK_TIMER_0_SRC: + return 1.0/(double)(((sysctl_media_clk->timer_clk_cfg >> 0) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_TIMER_0_CLK: + return 1; + + case SYSCTL_CLK_TIMER_1_SRC: + return 1.0/(double)(((sysctl_media_clk->timer_clk_cfg >> 3) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_TIMER_1_CLK: + return 1; + + case SYSCTL_CLK_TIMER_2_SRC: + return 1.0/(double)(((sysctl_media_clk->timer_clk_cfg >> 6) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_TIMER_2_CLK: + return 1; + + case SYSCTL_CLK_TIMER_3_SRC: + return 1.0/(double)(((sysctl_media_clk->timer_clk_cfg >> 9) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_TIMER_3_CLK: + return 1; + + case SYSCTL_CLK_TIMER_4_SRC: + return 1.0/(double)(((sysctl_media_clk->timer_clk_cfg >> 12) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_TIMER_4_CLK: + return 1; + + + /*--------------------------- SHRM CLOCK ------------------------------------*/ + case SYSCTL_CLK_SHRM_SRC: + return 1; + case SYSCTL_CLK_SHRM_DIV_2: + return 1.0/2; + case SYSCTL_CLK_SHRM_AXIS_CLK_GATE: + case SYSCTL_CLK_DECOMPRESS_ACLK_GATE: + return 1; + + case SYSCTL_CLK_SHRM_PCLK: + return 1.0/(double)(((sysctl_media_clk->shrm_clk_cfg >> 18) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + + case SYSCTL_CLK_SHRM_AXIM_CLK_GATE: + case SYSCTL_CLK_GSDMA_ACLK_GATE: + case SYSCTL_CLK_NONAI2D_ACLK_GATE: + case SYSCTL_CLK_PDMA_ACLK_GATE: + return 1; + + /*--------------------------- DDR CLOCK ------------------------------------*/ + case SYSCTL_CLK_DDRC_CORE_CLK: + return 1.0/(double)(((sysctl_media_clk->ddr_clk_cfg >> 10) & 0xF) + 1); /* 1/1, 1/2, 1/3 --- 1/16 */ + case SYSCTL_CLK_DDRC_BYPASS_GATE: + return 1; + case SYSCTL_CLK_DDRC_PCLK: + return 1.0/(double)(((sysctl_media_clk->ddr_clk_cfg >> 14) & 0xF) + 1); /* 1/1, 1/2, 1/3 --- 1/16 */ + + /*--------------------------- ISP CLOCK ------------------------------------*/ + case SYSCTL_CLK_ISP_CFG_CLK: + return 1.0/(double)(((sysctl_media_clk->isp_clkdiv_cfg >> 0) & 0x1F) + 1); /* 1/1, 1/2, 1/3 --- 1/32 */ + case SYSCTL_CLK_CSI_0_PIXEL_CLK: + return 1.0/(double)(((sysctl_media_clk->isp_clkdiv_cfg >> 5) & 0x3F) + 1); /* 1/1, 1/2, 1/3 --- 1/64 */ + case SYSCTL_CLK_CSI_1_PIXEL_CLK: + return 1.0/(double)(((sysctl_media_clk->isp_clkdiv_cfg >> 11) & 0x3F) + 1); /* 1/1, 1/2, 1/3 --- 1/64 */ + case SYSCTL_CLK_CSI_2_PIXEL_CLK: + return 1.0/(double)(((sysctl_media_clk->isp_clkdiv_cfg >> 17) & 0x3F) + 1); /* 1/1, 1/2, 1/3 --- 1/64 */ + + case SYSCTL_CLK_MCLK_0: + return 1.0/(double)(((sysctl_media_clk->mclk_cfg >> 5) & 0x1F) + 1); /* 1/1, 1/2, 1/3 --- 1/32 */ + case SYSCTL_CLK_MCLK_1: + return 1.0/(double)(((sysctl_media_clk->mclk_cfg >> 12) & 0x1F) + 1); /* 1/1, 1/2, 1/3 --- 1/32 */ + case SYSCTL_CLK_MCLK_2: + return 1.0/(double)(((sysctl_media_clk->mclk_cfg >> 19) & 0x1F) + 1); /* 1/1, 1/2, 1/3 --- 1/32 */ + + case SYSCTL_CLK_ISP_CLK: + return 1.0/(double)(((sysctl_media_clk->isp_clkdiv_cfg >> 26) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_ISP_MEM_CLK_GATE: + return 1; + + case SYSCTL_CLK_ISP_HCLK: + return 1.0/(double)(((sysctl_media_clk->isp_clkdiv_cfg >> 23) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + + case SYSCTL_CLK_ISP_ACLK_GATE: + case SYSCTL_CLK_DDRC_P1CLK_GATE: + return 1; + + case SYSCTL_CLK_ISP_DWECLK_GATE: + case SYSCTL_CLK_ISP_VSECLK_GATE: + return 1; + + /*--------------------------- DPU CLOCK ------------------------------------*/ + case SYSCTL_CLK_DPU_CLK: + return (double)(((sysctl_media_clk->dpu_clk_cfg >> 3) & 0xF) + 1) / 16.0; /* 1/16 --- 16/16 */ + case SYSCTL_CLK_DPU_ACLK_GATE: + return 1; + case SYSCTL_CLK_DPU_PCLK: + return 1.0/(double)(((sysctl_media_clk->dpu_clk_cfg >> 7) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + + /*--------------------------- DISPLAY CLOCK ------------------------------------*/ + case SYSCTL_CLK_DISP_HCLK: + return 1.0/(double)(((sysctl_media_clk->disp_clk_div >> 0) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_DISP_ACLK_GATE: + return 1; + + case SYSCTL_CLK_DISP_CLKEXT: + return 1.0/(double)(((sysctl_media_clk->disp_clk_div >> 16) & 0xF) + 1); /* 1/1, 1/2, 1/3 --- 1/16 */ + case SYSCTL_CLK_DISP_GPU: + return 1.0/(double)(((sysctl_media_clk->disp_clk_div >> 20) & 0xF) + 1); /* 1/1, 1/2, 1/3 --- 1/16 */ + + case SYSCTL_CLK_DPIPCLK: + return 1.0/(double)(((sysctl_media_clk->disp_clk_div >> 3) & 0xFF) + 1); /* 1/1, 1/2, 1/3 --- 1/256 */ + case SYSCTL_CLK_DISP_CFGCLK: + return 1.0/(double)(((sysctl_media_clk->disp_clk_div >> 11) & 0x1F) + 1); /* 1/1, 1/2, 1/3 --- 1/32 */ + + case SYSCTL_CLK_DISP_REFCLK_GATE: + return 1; + + /*--------------------------- SEC CLOCK ------------------------------------*/ + case SYSCTL_CLK_SEC_PCLK: + return 1.0/(double)(((sysctl_media_clk->sec_clk_div >> 1) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_SEC_FIXCLK: + return 1.0/(double)(((sysctl_media_clk->sec_clk_div >> 6) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + + case SYSCTL_CLK_SEC_ACLK: + return 1.0/(double)(((sysctl_media_clk->sec_clk_div >> 11) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + + /*--------------------------- USB TEST MODE CLOCK ------------------------------------*/ + case SYSCTL_CLK_USB_CLK_480: + return 1.0/(double)(((sysctl_media_clk->usb_test_clk_div >> 1) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + case SYSCTL_CLK_USB_CLK_100: + return 1.0/(double)(((sysctl_media_clk->usb_test_clk_div >> 4) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + + /*--------------------------- DPHY DFT MODE CLOCK ------------------------------------*/ + case SYSCTL_CLK_DPHY_TEST_CLK: + return 1.0/(double)(((sysctl_media_clk->dphy_test_clk_div >> 1) & 0xF) + 1); /* 1/1, 1/2, 1/3 --- 1/16 */ + + /*--------------------------- SPI2AXI CLOCK ------------------------------------*/ + case SYSCTL_CLK_SPI2AXI_ACLK: + return 1.0/(double)(((sysctl_media_clk->spi2axi_clk_div >> 1) & 0x7) + 1); /* 1/1, 1/2, 1/3 --- 1/8 */ + + default: + return 1; + } +} + +/* 计算本时钟节点的频率。它会搜索整个时钟路径,从时钟源开始计算每一级的分频,最终得出当前时钟节点的频率 +* 1. 对于根节点的clock,利用sysctl_boot_get_root_clk_freq(node)获取clock的频率(此时分频系数div=1); +* 2. 对于叶子节点的clock,利用while循环搜索叶子节点的根节点并计算出整条路径上的div,找到根节点后,利用 +* sysctl_boot_get_root_clk_freq(node) * div计算出叶子节点的频率。 + */ +uint32_t sysctl_media_clk_get_leaf_freq(sysctl_media_clk_node_e leaf) +{ + double div = 1.0; + sysctl_media_clk_node_e node; + + node = leaf; + + if(node == SYSCTL_CLK_TIMERX_PULSE_IN) + { + return (uint32_t)(50000000 * div); + } + + /* calc leaf chain div */ + while(node > SYSCTL_CLK_ROOT_MAX) + { + div *= sysctl_media_clk_get_leaf_div(node); + node = sysctl_media_clk_get_leaf_parent(node); + } + + /* get root freq and calc leaf freq */ + return (uint32_t)(sysctl_media_boot_get_root_clk_freq(node) * div); +} + +/** + * 实际上,本函数主要针对小数分频。 + * + * method=1/2,本函数会根据父节点时钟、实际需要的时钟,计算分频系数; + * method=3,本函数会根据输入节点、实际需要的时钟,计算分频系数 +*/ +int sysctl_media_clk_find_approximate(sysctl_media_clk_node_e leaf, + uint32_t mul_min, + uint32_t mul_max, + uint32_t div_min, + uint32_t div_max, + sysctl_media_clk_mul_div_methord_e method, + unsigned long rate, + unsigned long parent_rate, + uint32_t *div, + uint32_t *mul) +{ + long abs_min; + long abs_current; + /* we used interger to instead of float */ + long perfect_divide; + + uint32_t a,b; + int i = 0; + int n = 0; + unsigned long mul_ulong,div_ulong; + + volatile uint32_t codec_clk[9] = { + 2048000, + 3072000, + 4096000, + 6144000, + 8192000, + 11289600, + 12288000, + 24576000, + 49152000 + }; + volatile uint32_t codec_div[9][2] = { + {3125, 16}, + {3125, 24}, + {3125, 32}, + {3125, 48}, + {3125, 64}, + {15625, 441}, + {3125, 96}, + {3125, 192}, + {3125, 384} + }; + + volatile uint32_t pdm_clk[20] = { + 128000, + 192000, + 256000, + 384000, + 512000, + 768000, + 1024000, + 1411200, + 1536000, + 2048000, + 2822400, + 3072000, + 4096000, + 5644800, + 6144000, + 8192000, + 11289600, + 12288000, + 24576000, + 49152000 + }; + volatile uint32_t pdm_div[20][2] = { + {3125, 1}, + {6250, 3}, + {3125, 2}, + {3125, 3}, + {3125, 4}, + {3125, 6}, + {3125, 8}, + {125000, 441}, + {3125, 12}, + {3125, 16}, + {62500, 441}, + {3125, 24}, + {3125, 32}, + {31250, 441}, + {3125, 48}, + {3125, 64}, + {15625, 441}, + {3125, 96}, + {3125, 192}, + {3125, 384} + }; + + switch(method) { + + /* only mul can be changeable, 1/8,2/8,3/8...*/ + case SYSCTL_CLK_MUL_CHANGEABLE: { + perfect_divide = (long)((parent_rate*1000) / rate); + abs_min = abs(perfect_divide - (long)(((long)div_max*1000)/(long)mul_min)); + + for(i = mul_min + 1; i <= mul_max; i++) { + abs_current = abs(perfect_divide - (long)((long)((long)div_max*1000)/(long)i)); + if(abs_min > abs_current ) { + abs_min = abs_current; + *mul = i; + } + } + + *div = div_min; + break; + } + /* only div can be changeable, 1/1,1/2,1/3...*/ + case SYSCTL_CLK_DIV_CHANGEABLE: { + perfect_divide = (long)((parent_rate*1000) / rate); + abs_min = abs(perfect_divide - (long)(((long)div_min*1000)/(long)mul_max)); + *div = div_min; + + for(i = div_min + 1; i <= div_max; i++) { + abs_current = abs(perfect_divide - (long)((long)((long)i*1000)/(long)mul_max)); + if(abs_min > abs_current ) { + abs_min = abs_current; + *div = i; + } + } + *mul = mul_min; + break; + } + + case SYSCTL_CLK_MUL_DIV_CHANGEABLE: { + if((SYSCTL_CLK_CODEC_ADC_MCLK == leaf) || (SYSCTL_CLK_CODEC_DAC_MCLK == leaf)) + { + for(int i=0;i<9;i++) + { + if(0 == (rate - codec_clk[i])) + { + *div = codec_div[i][0]; + *mul = codec_div[i][1]; + } + } + } + else if((SYSCTL_CLK_AUDIO_DEV_CLK == leaf) || (SYSCTL_CLK_PDM_CLK == leaf)) + { + for(int i=0;i<20;i++) + { + if(0 == (rate - pdm_clk[i])) + { + *div = pdm_div[i][0]; + *mul = pdm_div[i][1]; + } + } + } + else + { + return -1; + } + break; + } + + default:{ + return -3; + } + } + return 0; +} + +bool sysctl_media_clk_set_leaf_parent_div(sysctl_media_clk_node_e leaf, sysctl_media_clk_node_e parent, uint32_t numerator, uint32_t denominator) +{ + uint32_t reg, value; + + if (denominator == 0) + return false; + + switch (leaf) { + /*--------------------------- CPU1 CLOCK ------------------------------------*/ + case SYSCTL_CLK_CPU_1_SRC: + if ((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + + if (SYSCTL_CLK_ROOT_PLL0 == parent) + value = 0; + else if (SYSCTL_CLK_ROOT_PLL1_DIV_2 == parent) + value = 1; + else if (SYSCTL_CLK_ROOT_PLL3 == parent) + value = 2; + else + return false; + + reg = sysctl_media_clk->cpu1_clk_cfg; + reg |= ((1 << 31) | (7 << 3)); + sysctl_media_clk->cpu1_clk_cfg = reg; + + reg &= ~(3 << 1); + reg |= (value << 1); + sysctl_media_clk->cpu1_clk_cfg = reg; + + reg &= ~(7 << 3); + reg |= ((1 << 31) | ((denominator - 1) << 3)); + sysctl_media_clk->cpu1_clk_cfg = reg; + break; + /*--------------------------- AI CLOCK ------------------------------------*/ + case SYSCTL_CLK_AI_SRC: + if ((numerator != 1) || (denominator < 1) || (denominator > 8)) + return false; + + if (SYSCTL_CLK_ROOT_PLL0_DIV_2 == parent) + value = 0; + else if (SYSCTL_CLK_ROOT_PLL3_DIV_2 == parent) + value = 1; + else + return false; + + reg = sysctl_media_clk->ai_clk_cfg; + reg |= ((1 << 31) | (7 << 3)); + sysctl_media_clk->ai_clk_cfg = reg; + + reg &= ~(1 << 2); + reg |= (value << 2); + sysctl_media_clk->ai_clk_cfg = reg; + + reg &= ~(7 << 3); + reg |= ((1 << 31) | ((denominator - 1) << 3)); + sysctl_media_clk->ai_clk_cfg = reg; + break; + default: + return false; + } + return true; +} + +void sysctl_media_clk_set_leaf_en_multi(sysctl_media_clk_node_e leaf, bool enable) +{ + static sysctl_media_clk_node_e leaf_list[] = { + SYSCTL_CLK_AI_SRC, SYSCTL_CLK_DPU_CLK, SYSCTL_CLK_VPU_SRC}; + static uint32_t ref_count[sizeof(leaf_list) / sizeof(leaf_list[0])]; + rt_base_t level; + int idx = -1; + + for (int i = 0; i < sizeof(leaf_list) / sizeof(leaf_list[0]); i++) { + if (leaf_list[i] == leaf) { + idx = i; + break; + } + } + if (idx < 0) + return; + + level = rt_hw_interrupt_disable(); + if (enable == true) { + if (ref_count[idx] == 0) + sysctl_media_clk_set_leaf_en(leaf, enable); + ref_count[idx]++; + if (ref_count[idx] == UINT32_MAX) + rt_kprintf("error: clk %d enable too many times\n", idx); + } else if (ref_count[idx]) { + ref_count[idx]--; + if (ref_count[idx] == 0) + sysctl_media_clk_set_leaf_en(leaf, enable); + } + rt_hw_interrupt_enable(level); +} + +int rt_hw_sysctl_media_clk_init(void) +{ + sysctl_media_clk = rt_ioremap((void*)CMU_BASE_ADDR, CMU_IO_SIZE); + if(!sysctl_media_clk) { + rt_kprintf("sysctl_media_clk ioremap error\n"); + return -1; + } + + return 0; +} +INIT_BOARD_EXPORT(rt_hw_sysctl_media_clk_init); diff --git a/src/big/mpp/kernel/mediafreq/src/sysctl/sysctl_media_clock/sysctl_media_clk.h b/src/big/mpp/kernel/mediafreq/src/sysctl/sysctl_media_clock/sysctl_media_clk.h new file mode 100755 index 000000000..0a50fbfd4 --- /dev/null +++ b/src/big/mpp/kernel/mediafreq/src/sysctl/sysctl_media_clock/sysctl_media_clk.h @@ -0,0 +1,1009 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __SYSCTL_MEDIA_CLK_H__ +#define __SYSCTL_MEDIA_CLK_H__ + +#include +#include + +#define SYSCTL_BASE_ADDR 0x91100000 +#define SYSCTL_CLK_BASE_ADDR (SYSCTL_BASE_ADDR + 0x0000) /* SYSCTL_BASE_ADDR=0x9110_0000 */ + +typedef struct sysctl_media_clk { + volatile uint32_t cpu0_clk_cfg; /* 0x00 */ + volatile uint32_t cpu1_clk_cfg; /* 0x04 */ + volatile uint32_t ai_clk_cfg; /* 0x08 */ + volatile uint32_t vpu_clk_cfg; /* 0x0c */ + volatile uint32_t pmu_clk_cfg; /* 0x10 */ + volatile uint32_t reserved0[1]; /* 0x14 */ + volatile uint32_t hs_clken_cfg; /* 0x18 */ + volatile uint32_t hs_sdclk_cfg; /* 0x1c */ + volatile uint32_t hs_spi_cfg; /* 0x20 */ + volatile uint32_t ls_clken_cfg0; /* 0x24 */ + volatile uint32_t ls_clken_cfg1; /* 0x28 */ + volatile uint32_t uart_i2c_clkdiv_cfg; /* 0x2c */ + volatile uint32_t ls_clkdiv_cfg; /* 0x30 */ + volatile uint32_t audio_clkdiv_cfg; /* 0x34 */ + volatile uint32_t codec_adc_mclkdiv_cfg; /* 0x38 */ + volatile uint32_t codec_dac_mclkdiv_cfg; /* 0x3c */ + volatile uint32_t pdm_clkdiv_cfg0; /* 0x40 */ + volatile uint32_t pdm_clkdiv_cfg1; /* 0x44 */ + volatile uint32_t reserved1[2]; /* 0x48 0x4c */ + volatile uint32_t sysctl_clken_cfg; /* 0x50 */ + volatile uint32_t timer_clk_cfg; /* 0x54 */ + volatile uint32_t sysctl_clk_div_cfg; /* 0x58 */ + volatile uint32_t shrm_clk_cfg; /* 0x5c */ + volatile uint32_t ddr_clk_cfg; /* 0x60 */ + volatile uint32_t isp_clken_cfg; /* 0x64 */ + volatile uint32_t isp_clkdiv_cfg; /* 0x68 */ + volatile uint32_t mclk_cfg; /* 0x6c */ + volatile uint32_t dpu_clk_cfg; /* 0x70 */ + volatile uint32_t vo_clk_cfg; /* 0x74 */ + volatile uint32_t disp_clk_div; /* 0x78 */ + volatile uint32_t reserved2[1]; /* 0x7c */ + volatile uint32_t sec_clk_div; /* 0x80 */ + volatile uint32_t reserved3[31]; /* 0x84 0x88 0x8c 0x90 0x94 0x98 0x9c 0xa0-0xac 0xb0-0xbc 0xc0-0xcc 0xd0-0xdc 0xe0-0xec 0xf0-0xfc*/ + volatile uint32_t usb_test_clk_div; /* 0x100 */ + volatile uint32_t dphy_test_clk_div; /* 0x104 */ + volatile uint32_t spi2axi_clk_div; /* 0x108 */ +} sysctl_media_clk_t; + +typedef enum { + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /***********************************************ROOT******************************************************/ + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /* clock root */ + /* sysctl_boot clk tree + osc24m----------------->|-->pll0----->|--------->pll0 clk output--->to sysctl_clock module + | |--div2--->pll0_div2 clk output--->to sysctl_clock module + | |--div3--->pll0_div3 clk output--->to sysctl_clock module + | |--div4--->pll0_div4 clk output--->to sysctl_clock module + | + |-->pll1----->|--------->pll1 clk output--->to sysctl_clock module + | |--div2--->pll1_div2 clk output--->to sysctl_clock module + | |--div3--->pll1_div3 clk output--->to sysctl_clock module + | |--div4--->pll1_div4 clk output--->to sysctl_clock module + | + |-->pll2----->|--------->pll2 clk output--->to sysctl_clock module + | |--div2--->pll2_div2 clk output--->to sysctl_clock module + | |--div3--->pll2_div3 clk output--->to sysctl_clock module + | |--div4--->pll2_div4 clk output--->to sysctl_clock module + | + |-->pll3----->|--------->pll3 clk output--->to sysctl_clock module + | |--div2--->pll3_div2 clk output--->to sysctl_clock module + | |--div3--->pll3_div3 clk output--->to sysctl_clock module + | |--div4--->pll3_div4 clk output--->to sysctl_clock module + | + |----------------------------------------------->to sysctl_clock module + */ + SYSCTL_CLK_ROOT_OSC_IN = 0, /* 24M */ + SYSCTL_CLK_ROOT_TIMERX_PULSE_IN, /* 50M */ + SYSCTL_CLK_ROOT_PLL0, /* 1.6G */ + SYSCTL_CLK_ROOT_PLL0_DIV_2, /* 800M */ + SYSCTL_CLK_ROOT_PLL0_DIV_3, /* 533M */ + SYSCTL_CLK_ROOT_PLL0_DIV_4, /* 400M */ + SYSCTL_CLK_ROOT_PLL1, /* 2.376G */ + SYSCTL_CLK_ROOT_PLL1_DIV_2, /* 1.188G */ + SYSCTL_CLK_ROOT_PLL1_DIV_3, /* 792M */ + SYSCTL_CLK_ROOT_PLL1_DIV_4, /* 594M */ + SYSCTL_CLK_ROOT_PLL2, /* 2.667G */ + SYSCTL_CLK_ROOT_PLL2_DIV_2, /* 1.3335G */ + SYSCTL_CLK_ROOT_PLL2_DIV_3, /* 889M */ + SYSCTL_CLK_ROOT_PLL2_DIV_4, /* 666.75M */ + SYSCTL_CLK_ROOT_PLL3, /* 1.6G */ + SYSCTL_CLK_ROOT_PLL3_DIV_2, /* 800M */ + SYSCTL_CLK_ROOT_PLL3_DIV_3, /* 533M */ + SYSCTL_CLK_ROOT_PLL3_DIV_4, /* 400M */ + SYSCTL_CLK_ROOT_MAX, + + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /********************************************CPU0 clock***************************************************/ + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /* cpu0 clock tree + pll0_div2--->DIV--->GATE--->|--------------------->cpu0 core clk + |---GATE--->|---DIV--->cpu0 plic clk + |---------->|---DIV--->cpu0 axi clk + |---GATE--->|--------->noc & ddrc p4 clk + + pll0_div4--->DIV--->|---GATE--->apb clk + + // root node: pll0_div2 + 1. cpu0_src -->cpu0 core DIV & GATE + 2. cpu0_plic -->cpu0 plic clk gate & div + 3. cpu0_aclk -->cpu0 axi clk div + 4. cpu0_noc_ddrcp4 -->ddrc axi4clk & noc AXI clock gate + + // root node: pll0_div4 + 1. cpu0_pclk -->cpu0 apb pclk, DIV & GATE + */ + SYSCTL_CLK_CPU_0_SRC, /* defualt 800MHz ---> select pll0_div_2 */ + SYSCTL_CLK_CPU_0_PLIC, /* 400MHz */ + SYSCTL_CLK_CPU_0_ACLK, /* 400MHz */ + SYSCTL_CLK_CPU_0_NOC_DDRCP4, /* 400MHz */ + + SYSCTL_CLK_CPU_0_PCLK, /* 200MHz */ + + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /********************************************pmu clock****************************************************/ + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /* pmu system clock tree + osc24m--->GATE--->pmu apb clk + + //root node: osc24m + 1. pmu_pclk: pmu apb clk gate + */ + SYSCTL_CLK_PMU_PCLK, + + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /********************************************hs clock*****************************************************/ + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /* hs system clock tree + pll0_div4-------->DIV------>|--->GATE--->hs hclk high + |--->DIV--->GATE--->|---hs ahb clk--->|---GATE--->sd0 ahb clk + |---GATE--->sd1 ahb clk + |---GATE--->usb0 ahb clk + |---GATE--->usb1 ahb clk + |---GATE--->ssi1 ahb clk + |---GATE--->ssi2 ahb clk + + pll0_div4---->|---DIV--->GATE--->ssi0 axi clk + |---DIV--->GATE--->ssi1 clk + |---DIV--->GATE--->ssi2 clk + |---DIV--->GATE--->qspi axi clk--->|---GATE--->ssi1 axi clk + |---GATE--->ssi2 axi clk + + +-+ + pll0_div2-->|M \ + |U |--->GATE-->ospi core clk + pll2_div4-->|X / + +-+ + + pll2_div4--->DIV--->GATE--->sd axi clk--->|---GATE--->sd0 axi clk + |---GATE--->sd1 axi clk + |---GATE--->sd0 base clk + |---GATE--->sd1 base clk + + pll0_div4--->DIV--->GATE--->sd card clk---->|---GATE--->sd0 card clk tx + |---GATE--->sd1 card clk tx + + +-+ + osc24m----------------------------->|M \ + |U |--->|---GATE--->usb0 reference clk + pll0-------->DIV16--->DIV---------->|X / |---GATE--->usb1 reference clk + +-+ + + osc24m--->DIV--->GATE---sd timer clk--->|---GATE--->sd0 timer clk + |---GATE--->sd1 timer clk + + //root node: pll0_div4 + 0. hs_hclk_high_src: hs hclk high DIV + 1. hs_hclk_high: hs hclk high GATE; + 2. hs_hclk_src: hs ahb clk DIV & GATE; + 3. sd0_hclk_gate: sd0 ahb clk gate; + 4. sd1_hclk_gate: sd1 ahb clk gate; + 5. usb0_hclk_gate: usb0 ahb clk gate; + 6. usb1_hclk_gate: usb1 ahb clk gate; + 7. ssi1_hclk_gate: ssi1 ahb clk gate; + 8. ssi2_hclk_gate: ssi2 ahb clk gate; + + //root node: pll0_div4 + 1. ssi0_aclk: ssi0 axi clk DIV & GATE; + 2. ssi1_clk: ssi1 clk DIV & GATE; + 3. ssi2_clk: ssi2 clk DIV & GATE; + 4. qspi_aclk_src: qspi sxi clk DIV & GATE; + 5. ssi1_aclk_gate: ssi1 axi clk gate; + 6. ssi2_aclk_gate: ssi2 axi clk gate; + + //root node: pll0_div2 & pll2_div4 + 1. ssi0_clk: ospi core clk MUX & GATE; + + //root node: pll2_div4 + 1. sd_aclk_src: sd axi clk DIV & GATE; + 2. sd0_aclk_gate: sd0 axi clk gate; + 3. sd1_aclk_gate: sd1 axi clk gate; + 4. sd0_bclk_gate: sd0 base clk gate; + 5. sd1_bclk_gate: sd1 base clk gate; + + //root node: pll0_div4 + 1. sd_cclk_src: sd card clk gate & div; + 2. sd0_cclk_gate: sd0 card clk gate; + 3. sd1_cclk_gate: sd1 card clk gate; + + //需要修改,linux部分已经修改了 + //root node: pll0 + 1. pll0_div16 + //root node: pll0_div16 + 1. usb_ref_50m: usbx reference clk DIV; + //root node: osc24m & usb_ref_50m + 2. usb0_ref_clk: usb0 reference clk gate & MUX; + 3. usb1_ref_clk: usb1 reference clk gate & MUX; + + //root node: osc24m + 1. sd_tmclk_src: sdx timer clk DIV & GATE; + 2. sd0_tmclk_gate: sd0 timer clk gate; + 3. sd1_tmclk_gate: sd1 timer clk gate; + */ + SYSCTL_CLK_HS_HCLK_HIGH_SRC, + SYSCTL_CLK_HS_HCLK_HIGH_GATE, + SYSCTL_CLK_HS_HCLK_SRC, + SYSCTL_CLK_SD_0_HCLK_GATE, + SYSCTL_CLK_SD_1_HCLK_GATE, + SYSCTL_CLK_USB_0_HCLK_GATE, + SYSCTL_CLK_USB_1_HCLK_GATE, + SYSCTL_CLK_SSI_1_HCLK_GATE, + SYSCTL_CLK_SSI_2_HCLK_GATE, + + SYSCTL_CLK_SSI_0_ACLK, + SYSCTL_CLK_SSI_1_CLK, + SYSCTL_CLK_SSI_2_CLK, + SYSCTL_CLK_QSPI_ACLK_SRC, + SYSCTL_CLK_SSI_1_ACLK_GATE, + SYSCTL_CLK_SSI_2_ACLK_GATE, + + SYSCTL_CLK_SSI_0_CLK, + + SYSCTL_CLK_SD_ACLK_SRC, + SYSCTL_CLK_SD_0_ACLK_GATE, + SYSCTL_CLK_SD_1_ACLK_GATE, + SYSCTL_CLK_SD_0_BCLK_GATE, + SYSCTL_CLK_SD_1_BCLK_GATE, + + SYSCTL_CLK_SD_CCLK_SRC, + SYSCTL_CLK_SD_0_CCLK_GATE, + SYSCTL_CLK_SD_1_CCLK_GATE, + + + SYSCTL_CLK_PLL0_DIV_16, + SYSCTL_CLK_USB_REF_50M, + SYSCTL_CLK_USB_0_REF_CLK, + SYSCTL_CLK_USB_1_REF_CLK, + + SYSCTL_CLK_SD_TMCLK_SRC, + SYSCTL_CLK_SD_0_TMCLK_GATE, + SYSCTL_CLK_SD_1_TMCLK_GATE, + + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /********************************************ls clock*****************************************************/ + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /* ls system clock tree + pll0_div4---------->DIV----->-----GATE--->ls apb clk--->|---GATE--->uart0 apb clk + |---GATE--->uart1 apb clk + |---GATE--->uart2 apb clk + |---GATE--->uart3 apb clk + |---GATE--->uart4 apb clk + |---GATE--->i2c0 apb clk + |---GATE--->i2c1 apb clk + |---GATE--->i2c2 apb clk + |---GATE--->i2c3 apb clk + |---GATE--->i2c4 apb clk + |---GATE--->gpio apb clk + |---GATE--->pwm apb clk + |---GATE--->jamlink0 apb clk + |---GATE--->jamlink1 apb clk + |---GATE--->jamlink2 apb clk + |---GATE--->jamlink3 apb clk + |---GATE--->audio apb clk + |---GATE--->adc apb clk + |---GATE--->codec apb clk + + pll0_div16----->|---DIV--->GATE--->uart0 core clk + |---DIV--->GATE--->uart1 core clk + |---DIV--->GATE--->uart2 core clk + |---DIV--->GATE--->uart3 core clk + |---DIV--->GATE--->uart4 core clk + + pll0_div16----->DIV---->|---GATE--->jamlink0 CO clk + |---GATE--->jamlink1 CO clk + |---GATE--->jamlink2 CO clk + |---GATE--->jamlink3 CO clk + + pll0_div4------>|---DIV--->GATE--->i2c0 core clk + |---DIV--->GATE--->i2c1 core clk + |---DIV--->GATE--->i2c2 core clk + |---DIV--->GATE--->i2c3 core clk + |---DIV--->GATE--->i2c4 core clk + + pll0_div4------>|---fraDIV--->GATE--->codec adc mclk + |---fraDIV--->GATE--->codec dac mclk + |---fraDIV--->GATE--->audio dev clk + |---fraDIV--->GATE--->pdm clk + |---DIV--->GATE--->adc clk + + osc24m----->DIV--->GATE--->gpio debounce clk + + //root node: pll0_div4 clock tree有误 + 1. ls_pclk_src: low system apb clk div & gate; + 2. uart0_pclk_gate: uart0 apb clk gate; + 3. uart1_pclk_gate: uart1 apb clk gate; + 4. uart2_pclk_gate: uart2 apb clk gate; + 5. uart3_pclk_gate: uart3 apb clk gate; + 6. uart4_pclk_gate: uart4 apb clk gate; + 7. i2c0_pclk_gate: i2c0 apb clk gate; + 8. i2c1_pclk_gate: i2c1 apb clk gate; + 9. i2c2_pclk_gate: i2c2 apb clk gate; + 10. i2c3_pclk_gate: i2c3 apb clk gate; + 11. i2c4_pclk_gate: i2c4 apb clk gate; + 12. gpio_pclk_gate: gpio apb clk gate; + 13. pwm_pclk_gate: pwm apb clk gate; + 14. jamlink0_pclk_gate: jamlink0 apb clk gate; + 15. jamlink1_pclk_gate: jamlink1 apb clk gate; + 16. jamlink2_pclk_gate: jamlink2 apb clk gate; + 17. jamlink3_pclk_gate: jamlink3 apb clk gate; + 18. audio_pclk_gate: audio apb clk gate; + 19. adc_pclk_gate: adc apb clk gate; + 20. codec_pclk_gate: codec apb clk gate; + + //root node: pll0_div16 + 1. uart0_clk: uart0 core clk div & gate; + 2. uart1_clk: uart1 core clk div & gate; + 3. uart2_clk: uart2 core clk div & gate; + 4. uart3_clk: uart3 core clk div & gate; + 5. uart4_clk: uart4 core clk div & gate; + + //root node: pll0_div16 + 1. jamlinkCO_div: jamlinkx CO div; + 2. jamlink0CO_gate: jamlink0 CO clk gate; + 3. jamlink1CO_gate: jamlink1 CO clk gate; + 4. jamlink2CO_gate: jamlink2 CO clk gate; + 5. jamlink3CO_gate: jamlink3 CO clk gate; + + //root node: pll0_div4 + 1. i2c0_clk: i2c0 core clk div & gate; + 2. i2c1_clk: i2c1 core clk div & gate; + 3. i2c2_clk: i2c2 core clk div & gate; + 4. i2c3_clk: i2c3 core clk div & gate; + 5. i2c4_clk: i2c4 core clk div & gate; + + //root node: pll0_div4 + 1. codec_adc_mclk: codec adc mclk fradiv & gate; + 2. codec_dac_mclk: codec dac mclk fradiv & gate; + 3. audio_dev_clk: audio dev clk fradiv & gate; + 4. pdm_clk: pdm clk fradiv & gate; + 5. adc_clk: adc clk div & gate; + + //root node: osc24m + 1. gpio_dbclk: gpio debounce clk div & gate; + */ + SYSCTL_CLK_LS_PCLK_SRC, + SYSCTL_CLK_UART_0_PCLK_GATE, + SYSCTL_CLK_UART_1_PCLK_GATE, + SYSCTL_CLK_UART_2_PCLK_GATE, + SYSCTL_CLK_UART_3_PCLK_GATE, + SYSCTL_CLK_UART_4_PCLK_GATE, + SYSCTL_CLK_I2C_0_PCLK_GATE, + SYSCTL_CLK_I2C_1_PCLK_GATE, + SYSCTL_CLK_I2C_2_PCLK_GATE, + SYSCTL_CLK_I2C_3_PCLK_GATE, + SYSCTL_CLK_I2C_4_PCLK_GATE, + SYSCTL_CLK_GPIO_PCLK_GATE, + SYSCTL_CLK_PWM_PCLK_GATE, + SYSCTL_CLK_JAMLINK_0_PCLK_GATE, + SYSCTL_CLK_JAMLINK_1_PCLK_GATE, + SYSCTL_CLK_JAMLINK_2_PCLK_GATE, + SYSCTL_CLK_JAMLINK_3_PCLK_GATE, + SYSCTL_CLK_ADC_PCLK_GATE, + + SYSCTL_CLK_UART_0_CLK, + SYSCTL_CLK_UART_1_CLK, + SYSCTL_CLK_UART_2_CLK, + SYSCTL_CLK_UART_3_CLK, + SYSCTL_CLK_UART_4_CLK, + + SYSCTL_CLK_JAMLINKCO_DIV, + SYSCTL_CLK_JAMLINK_0_CO_GATE, + SYSCTL_CLK_JAMLINK_1_CO_GATE, + SYSCTL_CLK_JAMLINK_2_CO_GATE, + SYSCTL_CLK_JAMLINK_3_CO_GATE, + + SYSCTL_CLK_I2C_0_CLK, + SYSCTL_CLK_I2C_1_CLK, + SYSCTL_CLK_I2C_2_CLK, + SYSCTL_CLK_I2C_3_CLK, + SYSCTL_CLK_I2C_4_CLK, + + // SYSCTL_CLK_SUM_DIV, + // SYSCTL_CLK_STEP_DIV, + // SYSCTL_CLK_PDM_CLK_GATE, + SYSCTL_CLK_ADC_CLK, + + SYSCTL_CLK_GPIO_DBCLK, + + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /********************************************sysctl clock*************************************************/ + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /* sysctl clock tree + pll0_div16----------------->sysctl apb clk----->|---GATE--->wdt0 apb clk + |---GATE--->wdt1 apb clk + |---GATE--->timer apb clk + |---GATE--->iomux apb clk + |---GATE--->mailbox apb clk + + pll0_div4--->DIV---GATE--->hdi core clk + pll1_div4--->DIV--->GATE--->time stamp clk + osc24m------>DIV----------->temp sensor clk + + //root node: pll0_div16 + 1. sysctl_pclk: sysctl apb clk; //sysctl_pclk have no gate & div. + 2. wdt0_pclk_gate: wdt0 apb clk gate; + 3. wdt1_pclk_gate: wdt1 apb clk gate; + 4. timer_pclk_gate: timer apb clk gate; + 5. iomux_pclk_gate: iomux apb clk gate; + 6. mailbox_pclk_gate: mailbox apb clk gate; + + //root node: pll0_div4 + 1. hdi_clk: hdi core clk div & gate; + + //root node: pll1_div4 + 1. stc_clk: time stamp clk div & gate; + + //root node: osc24m + 1. ts_clk: temp sensor clk div; + */ + SYSCTL_CLK_PCLK, + SYSCTL_CLK_WDT_0_PCLK_GATE, + SYSCTL_CLK_WDT_1_PCLK_GATE, + SYSCTL_CLK_TIMER_PCLK_GATE, + SYSCTL_CLK_IOMUX_PCLK_GATE, + SYSCTL_CLK_MAILBOX_PCLK_GATE, + + SYSCTL_CLK_HDI_CLK, + + SYSCTL_CLK_STC_CLK, + + SYSCTL_CLK_TS_CLK, + + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /********************************************timer clock**************************************************/ + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /* timer clock tree + +-+ + pll0_div16----->DIV---->|M \ + |U |---GATE--->timer0 core clk + timerx_pulse_in-------->|X / + +-+ + + +-+ + pll0_div16----->DIV---->|M \ + |U |---GATE--->timer1 core clk + timerx_pulse_in-------->|X / + +-+ + + +-+ + pll0_div16----->DIV---->|M \ + |U |---GATE--->timer2 core clk + timerx_pulse_in-------->|X / + +-+ + + +-+ + pll0_div16----->DIV---->|M \ + |U |---GATE--->timer3 core clk + timerx_pulse_in-------->|X / + +-+ + + +-+ + pll0_div16----->DIV---->|M \ + |U |---GATE--->timer4 core clk + timerx_pulse_in-------->|X / + +-+ + + //需要修改,linux已经修改 + //root node: pll0_div16 & timerx_pulse_in + 1. timerx_pulse_in: external input, maxsize is 1MHz; + + 2. timer0_clk_src: timer0 core clk DIV; + 3. timer0_clk: timer0 core clk GATE & MUX; + + 4. timer1_clk_src: timer1 core clk DIV; + 5. timer1_clk: timer1 core clk GATE & MUX; + + 6. timer2_clk_src: timer2 core clk DIV; + 7. timer2_clk: timer2 core clk GATE & MUX; + + 8. timer3_clk_src: timer3 core clk DIV; + 9. timer3_clk: timer3 core clk GATE & MUX; + + 10. timer4_clk_src: timer4 core clk DIV; + 11. timer4_clk: timer4 core clk GATE & MUX + */ + SYSCTL_CLK_TIMERX_PULSE_IN, + SYSCTL_CLK_TIMER_0_SRC, + SYSCTL_CLK_TIMER_0_CLK, + SYSCTL_CLK_TIMER_1_SRC, + SYSCTL_CLK_TIMER_1_CLK, + SYSCTL_CLK_TIMER_2_SRC, + SYSCTL_CLK_TIMER_2_CLK, + SYSCTL_CLK_TIMER_3_SRC, + SYSCTL_CLK_TIMER_3_CLK, + SYSCTL_CLK_TIMER_4_SRC, + SYSCTL_CLK_TIMER_4_CLK, + + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /********************************************shrm clock***************************************************/ + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /* shrm system clock tree + +-+ + pll0_div2-->|M \ + |U |---GATE--->shrm sram clk--->|---DIV2--->GATE--->shrm axi slave clk + pll3_div2-->|X / |---------->GATE--->decompress axi clk + +-+ + + pll0_div4--->DIV--->GATE---shrm apb clk + + pll0_div4--->GATE--->shrm axi master clk--->|---GATE--->gsdma axi clk + |---GATE--->nonai2d axi clk + |---GATE--->peri dma axi clk + + //root node: pll0_div2 & pll3_div2 + 1. shrm_src: MUX & GATE; + 2. shrm_div2: div2; + 3. shrm_axis_clk_gate: shrm axi slave clk gate; + 4. decompress_aclk_gate: decompress axi clk gate; + + //root node: pll0_div4 + 1. shrm_pclk: shrm apb clk div & gate; + + //root node: pll0_div4 + 1. shrm_axim_clk_gate: shrm axi master clk gate; + 2. gsdma_aclk_gate: gsdma axi clk gate; + 3. nonai2d_aclk_gate: nonai2d axi clk gate; + 4. pdma_aclk_gate: peri dma axi clk gate; + */ + SYSCTL_CLK_SHRM_SRC, + SYSCTL_CLK_SHRM_DIV_2, + SYSCTL_CLK_SHRM_AXIS_CLK_GATE, + SYSCTL_CLK_DECOMPRESS_ACLK_GATE, + + SYSCTL_CLK_SHRM_PCLK, + + SYSCTL_CLK_SHRM_AXIM_CLK_GATE, + SYSCTL_CLK_NONAI2D_ACLK_GATE, + + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /********************************************sec clock****************************************************/ + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /* sec system clock tree + pll0_div4-->---DIV--->GATE--->sec apb clk + pll1_div4--->---DIV--->GATE--->sec fix clk // clock tree有误 + pll1_div4--->DIV--->GATE--->sec axi clk + + //root node: pll0_div4 + 1. sec_pclk: sec apb clk DIV & GATE; + + //root node: pll1_div4 + 1. sec_aclk: sec axi clk DIV & GATE; + 2. sec_fixclk: sec fix clk DIV & GATE; + */ + SYSCTL_CLK_SEC_PCLK, + SYSCTL_CLK_SEC_FIXCLK, + + SYSCTL_CLK_SEC_ACLK, + + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /********************************************usb test mode clock******************************************/ + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /* usb test mode clock tree + pll1--->DIV--->GATE--->usb 480m clk + pll0_div4--->DIV--->GATE--->usb 100m clk + + //root node: pll1 + 1. usb_clk480: usb 480m clk DIV & GATE; + + //root node: pll0_div4 + 1. usb_clk100: usb 100m clk DIV & GATE; + */ + SYSCTL_CLK_USB_CLK_480, + SYSCTL_CLK_USB_CLK_100, + + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /********************************************dphy dft mode clock******************************************/ + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /* dphy dft mode clock tree + pll0--->DIV--->GATE--->dphy dft mode clk + + //root node: pll0 + 1. dphy_test_clk: dphy dft mode clk DIV & GATE; + */ + SYSCTL_CLK_DPHY_TEST_CLK, + + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /********************************************spi2axi clock************************************************/ + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /* spi2axi clock tree + pll0_div4--->DIV--->GATE--->spi2axi axi clk + + //root node: pll0_div4 + 1. spi2axi_aclk: spi2axi clk DIV & GATE; + */ + SYSCTL_CLK_SPI2AXI_ACLK, + + SYSCTL_CLK_MEDIA_CLK_START = 1000, + + + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /********************************************cpu1 clock***************************************************/ + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /* cpu1 clock tree + +-+ + pll0 --->|M \ + pll1_div2--->|U |--->DIV--->GATE--->|--------------------->cpu1 core clk + pll3 --->|X / |---GATE--->|---DIV--->cpu1 plic clk + +-+ |---------->|---DIV--->cpu1 axi clk + |---GATE--->|--------->noc & ddrc p0 clk + + pll0_div4--->DIV--->|---GATE--->apb clk + + //root node: pll0 & pll1_div2 & pll3 + 1. cpu1_src --> cpu1 core MUX & DIV & GATE + 2. cpu1_plic -->cpu1 plic clk gate & div + 3. cpu1_aclk -->cpu1 axi clk div + 4. cpu1_noc_ddrcp0 -->ddrc axi0clk & noc AXI clock gate + + //root node: pll0_div4 + 1. cpu1_pclk -->cpu1 apb pclk, DIV&GATE + */ + SYSCTL_CLK_CPU_1_SRC, /* defualt 800MHz ---> select pll0 */ + SYSCTL_CLK_CPU_1_PLIC, /* 400MHz */ + SYSCTL_CLK_CPU_1_ACLK, /* 400MHz */ + SYSCTL_CLK_CPU_1_NOC_DDRCP0, /* 400MHz */ + + SYSCTL_CLK_CPU_1_PCLK, /* 200MHz */ + + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /********************************************ai clock*****************************************************/ + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /* ai system clock tree + +-+ + pll0_div2-->|M \ + |U |-->DIV-->|---GATE--->ai system clk + pll3_div2-->|X / + +-+ + + pll0_div4--->|---GATE--->ai axi clk + |---GATE--->ddrc p3 clk + + //root node: pll0_div2 & pll3_div2 + 1. ai_src --> MUX & DIV & GATE + + //root node: pllo_div4 + 1. ai_aclk -->ai axi clk gate + 2. ai_ddrcp3 --->ai ddrc p3 clk gate + */ + SYSCTL_CLK_AI_SRC, /* defualt 800MHz ---> select pll0_div2 */ + SYSCTL_CLK_AI_ACLK, /* 400MHz */ + SYSCTL_CLK_AI_DDRCP3, /* 400MHz */ + + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /********************************************vpu clock****************************************************/ + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /* vpu system clock tree + pll0_div2--->DIV--->GATE--->|---------------------->vpu core clk + |--->DIV--->|---GATE--->vpu axi clk + |---GATE--->ddrc p2 clk + + pll0_div4--->DIV--->GATE--->vpu cfg clk + + //root node: pll0_div2 + 1. vpu_src: vpu core clk DIV & GATE; + 2. vpu_aclk_src: vpu aclk DIV; + 3. vpu_aclk: vpu aclk GATE; + 4. vpu_ddrcp2: ddrc p2 clk GATE; + + //root node: pll0_div4 + 1. vpu_cfg: vpu cfg clk DIV & GATE; + */ + SYSCTL_CLK_VPU_SRC, /* defualt 800MHz ---> select pll0_div2 */ + SYSCTL_CLK_VPU_ACLK_SRC, + SYSCTL_CLK_VPU_ACLK, + SYSCTL_CLK_VPU_DDRCP2, + + SYSCTL_CLK_VPU_CFG, + + /*audio pclk*/ + SYSCTL_CLK_AUDIO_PCLK_GATE, + /*audio codec pclk*/ + SYSCTL_CLK_CODEC_PCLK_GATE, + + /*audio clk*/ + SYSCTL_CLK_CODEC_ADC_MCLK, + SYSCTL_CLK_CODEC_DAC_MCLK, + SYSCTL_CLK_AUDIO_DEV_CLK, + SYSCTL_CLK_PDM_CLK, + + /*gsdma clk*/ + SYSCTL_CLK_GSDMA_ACLK_GATE, + + /*pdma clk*/ + SYSCTL_CLK_PDMA_ACLK_GATE, + + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /********************************************ddr clock****************************************************/ + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /* ddr system clock tree + +-+ + pll0_div2-------------->|M \ + pll0_div3-------------->|U |--->DIV--->GATE--->ddrc core clk + pll2_div4-------------->|X / + +-+ + + pll2_div4---------->GATE--->ddrc bypass gate + + pll0_div4--->DIV--->GATE--->ddrc apb clk + + // root node: pll0_div2 & pll0_div3 & pll2_div4 + 1. ddrc_core_clk: ddrc core clk MUX & DIV & GATE; + + //root node: pll2_div4 + 1. ddrc_bypass_gate: ddrc bypass gate; + + //root node: pll0_div4 + 1. ddrc_pclk: ddrc apb clk DIV & GATE; + */ + SYSCTL_CLK_DDRC_CORE_CLK, + SYSCTL_CLK_DDRC_BYPASS_GATE, + SYSCTL_CLK_DDRC_PCLK, + + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /********************************************isp clock****************************************************/ + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /* isp system clock tree + pll1_div4--->DIV--->GATE--->isp csiphy cfg clk + pll2_div4------>|---DIV--->GATE--->csi0 pixel clk + |---DIV--->GATE--->csi1 pixel clk + |---DIV--->GATE--->csi2 pixel clk + + +-+ + pll1_div3------>|M \ + pll1_div4------>|U |--->DIV--->GATE--->mclk0 + pll0_div4------>|X / + +-+ + + +-+ + pll1_div3------>|M \ + pll1_div4------>|U |--->DIV--->GATE--->mclk1 + pll0_div4------>|X / + +-+ + + +-+ + pll1_div3------>|M \ + pll1_div4------>|U |--->DIV--->GATE--->mclk2 + pll0_div4------>|X / + +-+ + + +-+ + pll0_div4------>|M \ + |U |--->DIV--->GATE--->isp clk--->|---GATE--->isp mem clk + pll2_div4------>|X / + +-+ + + pll0_div4--->DIV--->GATE--->isp ahb clk + pll0_div4------>|---GATE--->isp axi clk + |---GATE--->ddrc p1 clk + pll0_div3------>|---GATE--->isp dewarp clk + |---GATE--->isp scalar clk + + //root node: pll1_div4 + 1. isp_cfg_clk: isp csiphy cfg clk DIV & GATE; + + //root node: pll2_div4 + 1. csi0_pixel_clk: csi0 pixel clk DIV & GATE; + 2. csi1_pixel_clk: csi1 pixel clk DIV & GATE; + 3. csi2_pixel_clk: csi2 pixel clk DIV & GATE; + + //root node: pll1_div3 & pll1_div4 & pll0_div4 + 1. mclk0: mclk0 MUX & DIV & GATE; + 2. mclk1: mclk1 MUX & DIV & GATE; + 3. mclk2: mclk2 MUX & DIV & GATE; + + //root node: pll0_div4 & pll2_div4 + 1. isp_clk: isp clk MUX & DIV & GATE; + 2. isp_mem_clk_gate: isp mem clk gate; + + //root node: pll0_div4 + 1. isp_hclk: isp ahb clk DIV & GATE; + + //root node: pll0_div4 + 1. isp_aclk_gate: isp axi clk gate; + 2. ddrc_p1clk_gate: ddrc p1 clk gate; + + //root node: pll0_div3 + 1. isp_dweclk_gate: isp dewarp clk gate; + 2. isp_vseclk_gate: isp scalar clk gate; + */ + SYSCTL_CLK_ISP_CFG_CLK, + SYSCTL_CLK_CSI_0_PIXEL_CLK, + SYSCTL_CLK_CSI_1_PIXEL_CLK, + SYSCTL_CLK_CSI_2_PIXEL_CLK, + + SYSCTL_CLK_MCLK_0, + SYSCTL_CLK_MCLK_1, + SYSCTL_CLK_MCLK_2, + + SYSCTL_CLK_ISP_CLK, + SYSCTL_CLK_ISP_MEM_CLK_GATE, + + SYSCTL_CLK_ISP_HCLK, + + SYSCTL_CLK_ISP_ACLK_GATE, + SYSCTL_CLK_DDRC_P1CLK_GATE, + + SYSCTL_CLK_ISP_DWECLK_GATE, + SYSCTL_CLK_ISP_VSECLK_GATE, + + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /********************************************dpu clock****************************************************/ + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /* dpu clock tree + pll1_div4--->DIV--->GATE--->dpu core clk + pll0_div4---------->GATE--->dpu axi clk + pll0_div4--->DIV--->GATE--->dpu apb clk + + //root node: pll1_div4 + 1. dpu_clk: dpu core clk DIV & GATE; + + //root node: pll0_div4 + 1. dpu_aclk_gate: dpu axi clk gate; + + //root node: pll0_div4 + 1. dpu_pclk: dpu apb clk DIV & GATE; + */ + SYSCTL_CLK_DPU_CLK, + SYSCTL_CLK_DPU_ACLK_GATE, + SYSCTL_CLK_DPU_PCLK, + + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /********************************************display clock************************************************/ + /*********************************************************************************************************/ + /*********************************************************************************************************/ + /* display system clock tree + pll0_div4-->|---DIV--->GATE--->display ahb clk + |---GATE--->display axi clk + pll0_div3-->|---DIV--->GATE--->display clkext clk + |---DIV--->GATE--->display gpu clk + pll1_div4-->|---DIV--->GATE--->display dpipclk clk + |---DIV--->GATE--->display cfgclk clk + osc24m------------->GATE--->display refclk clk + + //root node: pll0_div4 + 1. disp_hclk: display ahb clk DIV & GATE; + 2. disp_aclk_gate: display axi clk gate; + + //root node: pll0_div3 + 1. disp_clkext: display clkext DIV & GATE; + 2. disp_gpu: display gpu clk DIV & GATE; + + //root node: pll1_div4 + 1. dpipclk: dpipclk clk DIV & GATE; + 2. disp_cfgclk: display cfgclk DIV & GATE; + + //root node: osc24m + 1. disp_refclk_gate: display refclk gate; + */ + SYSCTL_CLK_DISP_HCLK, + SYSCTL_CLK_DISP_ACLK_GATE, + + SYSCTL_CLK_DISP_CLKEXT, + SYSCTL_CLK_DISP_GPU, + + SYSCTL_CLK_DPIPCLK, + SYSCTL_CLK_DISP_CFGCLK, + + SYSCTL_CLK_DISP_REFCLK_GATE, + + SYSCTL_CLK_NODE_MAX, +}sysctl_media_clk_node_e; + +typedef enum +{ + SYSCTL_CLK_MUL_CHANGEABLE = 0, + SYSCTL_CLK_DIV_CHANGEABLE = 1, + SYSCTL_CLK_MUL_DIV_CHANGEABLE = 2, +}sysctl_media_clk_mul_div_methord_e; + +/********************************************************************************************************************** +* +* 针对时钟树中trunk和leaf节点的API。即,除了5个根时钟之外的其它时钟。 +* +**********************************************************************************************************************/ +/* 设置时钟数上叶子节点时钟源, 请根据时钟树来设置, 很多时钟节点只有一个时钟源,因此设置会返回false */ +bool sysctl_media_clk_set_leaf_parent(sysctl_media_clk_node_e leaf, sysctl_media_clk_node_e parent); +/* 获取时钟树上叶子节点时钟源 */ +sysctl_media_clk_node_e sysctl_media_clk_get_leaf_parent(sysctl_media_clk_node_e leaf); + +/* 设置时钟节点enable,注意:只设置本时钟节点的enable,不会设置上游时钟的enable。 + 同linux kernel的区别: linux kernel clock framework 会自动设置上游时钟的enable,测试代码没有kernel框架,因此只设置本节点时钟的enable */ +void sysctl_media_clk_set_leaf_en(sysctl_media_clk_node_e leaf, bool enable); + +/* 获取本时钟节点的enable状态 */ +bool sysctl_media_clk_get_leaf_en(sysctl_media_clk_node_e leaf); + +/* 设置本时钟节点的分频系数 */ +bool sysctl_media_clk_set_leaf_div(sysctl_media_clk_node_e leaf, uint32_t numerator, uint32_t denominator); + +/* 获取本时钟节点的分频系数 */ +double sysctl_media_clk_get_leaf_div(sysctl_media_clk_node_e leaf); + +/* calc clock freqency */ +/* 计算当前时钟节点的频率, 这个API会搜索整个时钟路径,从时钟源开始计算每一级的分频,最终得出当前时钟频率 */ +uint32_t sysctl_media_clk_get_leaf_freq(sysctl_media_clk_node_e leaf); + +/* 辅助计算函数,本函数会根据父节点时钟/实际需要输出的时钟/分频配置方法 计算出最合适的分频系数 */ +int sysctl_media_clk_find_approximate(sysctl_media_clk_node_e leaf, + uint32_t mul_min, + uint32_t mul_max, + uint32_t div_min, + uint32_t div_max, + sysctl_media_clk_mul_div_methord_e method, + unsigned long rate, + unsigned long parent_rate, + uint32_t *div, + uint32_t *mul); + +/* 设置本时钟节点的时钟源和分频系数 */ +bool sysctl_media_clk_set_leaf_parent_div(sysctl_media_clk_node_e leaf, sysctl_media_clk_node_e parent, uint32_t numerator, uint32_t denominator); + +/* 设置时钟节点enable,注意:只设置本时钟节点的enable,不会设置上游时钟的enable。 + 同linux kernel的区别: linux kernel clock framework 会自动设置上游时钟的enable,测试代码没有kernel框架,因此只设置本节点时钟的enable。 + 添加引用计数*/ +void sysctl_media_clk_set_leaf_en_multi(sysctl_media_clk_node_e leaf, bool enable); + +#endif diff --git a/src/big/mpp/kernel/pm/Makefile b/src/big/mpp/kernel/pm/Makefile new file mode 100755 index 000000000..bc6adb943 --- /dev/null +++ b/src/big/mpp/kernel/pm/Makefile @@ -0,0 +1,30 @@ + +include $(MPP_SRC_DIR)/kernel/mpp.mk +include $(MPP_SRC_DIR)/kernel/rt-smart.mk + +CURRECT_DIR_NAME=$(shell basename `pwd`) +LOCAL_SRC_DIR = $(shell pwd) +LIB = $(MPP_SRC_DIR)/kernel/lib/lib$(CURRECT_DIR_NAME).a + +LOCAL_CFLAGS = -I$(LOCAL_SRC_DIR)/src/ + +SRCS = $(wildcard $(LOCAL_SRC_DIR)/src/*.c) + +OBJS = $(patsubst %.c,%.o,$(SRCS)) + +all: $(LIB) + @-rm -f $(OBJS) + echo "${PWD}/Makefile all" + +$(OBJS): %.o : %.c + @$(CC) $(CC_CFLAGS) $(LOCAL_CFLAGS) $(BSP_CFLGAS) $(RTSMART_CFLAGS) $(MPP_DRIVER_CFLGAS) -c $< -o $@ + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +clean: + echo "${PWD}/Makefile clean" + -rm -rf $(LIB) + -rm -f $(OBJS) + +.PHONY: all clean diff --git a/src/big/mpp/kernel/pm/src/pm_core.c b/src/big/mpp/kernel/pm/src/pm_core.c new file mode 100644 index 000000000..23f6ec14a --- /dev/null +++ b/src/big/mpp/kernel/pm/src/pm_core.c @@ -0,0 +1,551 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include "k_pm_ioctl.h" +#include "pm_domain.h" +#define DBG_TAG "pm_core" +#ifdef RT_DEBUG +#define DBG_LVL DBG_LOG +#else +#define DBG_LVL DBG_WARNING +#endif +#define DBG_COLOR +#include + +#define COPY_FROM_USER(dst, src, size) \ + (size != lwp_get_from_user(dst, src, size)) +#define COPY_TO_USER(dst, src, size) \ + (size != lwp_put_to_user(dst, src, size)) + +#define THERMAL_DETECT_POLL_TIME 5000 // ms + +struct pm_dev { + struct rt_device parent; + struct rt_mutex mutex; + struct pm_domain_dev *dev[PM_DOMAIN_NR]; + int32_t thermal_shutdown_temp; +}; + +static struct pm_dev pm_device = { + .dev[PM_DOMAIN_CPU] = &pm_domain_cpu, + .dev[PM_DOMAIN_KPU] = &pm_domain_kpu, + .dev[PM_DOMAIN_DPU] = &pm_domain_dpu, + .dev[PM_DOMAIN_VPU] = &pm_domain_vpu, + .dev[PM_DOMAIN_DISPLAY] = &pm_domain_disp, +}; + +static int pm_core_default(void) +{ + pm_device.thermal_shutdown_temp = 20000; + + pm_device.dev[PM_DOMAIN_CPU]->expect_profile_idx = 0; + pm_device.dev[PM_DOMAIN_CPU]->actual_profile_idx = 0; + pm_device.dev[PM_DOMAIN_CPU]->governor = PM_GOVERNOR_MANUAL; + pm_device.dev[PM_DOMAIN_CPU]->thermal_protect_temp = 20000; + pm_device.dev[PM_DOMAIN_CPU]->thermal_protect_idx = 0; + + pm_device.dev[PM_DOMAIN_KPU]->expect_profile_idx = 0; + pm_device.dev[PM_DOMAIN_KPU]->actual_profile_idx = 0; + pm_device.dev[PM_DOMAIN_KPU]->governor = PM_GOVERNOR_MANUAL; + pm_device.dev[PM_DOMAIN_KPU]->thermal_protect_temp = 20000; + pm_device.dev[PM_DOMAIN_KPU]->thermal_protect_idx = 0; + + return 0; +} + +static int pm_core_domain_check(k_pm_domain domain) +{ + if (domain >= PM_DOMAIN_NR) + return K_ERR_PM_ILLEGAL_PARAM; + + if (!pm_device.dev[domain]) + return K_ERR_PM_UNEXIST; + + return 0; +} + +static int pm_core_get_reg(void *args) +{ + return 0; +} + +static int pm_core_set_reg(void *args) +{ + return 0; +} + +static int pm_core_get_stat(void *args) +{ + return 0; +} + +static int pm_core_get_profiles(void *args) +{ + int ret; + _k_pm_domain_profiles profiles; + + if (COPY_FROM_USER(&profiles, args, sizeof(_k_pm_domain_profiles))) + return K_ERR_PM_ILLEGAL_PARAM; + + ret = pm_core_domain_check(profiles.domain); + if (ret) + return ret; + + if (profiles.number == 0) { + profiles.number = pm_device.dev[profiles.domain]->profile_nr; + if (COPY_TO_USER(args, &profiles, sizeof(_k_pm_domain_profiles))) + return K_ERR_PM_ILLEGAL_PARAM; + } else { + if (profiles.number > pm_device.dev[profiles.domain]->profile_nr) + profiles.number = pm_device.dev[profiles.domain]->profile_nr; + if (COPY_TO_USER(args, &profiles, sizeof(_k_pm_domain_profiles))) + return K_ERR_PM_ILLEGAL_PARAM; + if (COPY_TO_USER(((_k_pm_domain_profiles *)args)->profiles, + pm_device.dev[profiles.domain]->profiles, + sizeof(k_pm_profile) * profiles.number)) + return K_ERR_PM_ILLEGAL_PARAM; + } + + return 0; +} + +static int pm_core_set_governor(void *args) +{ + int ret; + _k_pm_domain_governor governor; + + if (COPY_FROM_USER(&governor, args, sizeof(_k_pm_domain_governor))) + return K_ERR_PM_ILLEGAL_PARAM; + + ret = pm_core_domain_check(governor.domain); + if (ret) + return ret; + + ret = pm_domain_set_governor(pm_device.dev[governor.domain], + governor.governor); + if (ret) + return ret; + + ret = pm_domain_get_expect_profile(pm_device.dev[governor.domain]); + if (ret) + return ret; + + ret = pm_domain_set_actual_profile(pm_device.dev[governor.domain]); + + return ret; +} + +static int pm_core_get_governor(void *args) +{ + int ret; + _k_pm_domain_governor governor; + + if (COPY_FROM_USER(&governor, args, sizeof(_k_pm_domain_governor))) + return K_ERR_PM_ILLEGAL_PARAM; + + ret = pm_core_domain_check(governor.domain); + if (ret) + return ret; + + governor.governor = pm_device.dev[governor.domain]->governor; + + if (COPY_TO_USER(args, &governor, sizeof(_k_pm_domain_governor))) + return K_ERR_PM_ILLEGAL_PARAM; + + return 0; +} + +static int pm_core_set_profile(void *args) +{ + int ret; + _k_pm_domain_profile profile; + + if (COPY_FROM_USER(&profile, args, sizeof(_k_pm_domain_profile))) + return K_ERR_PM_ILLEGAL_PARAM; + + ret = pm_core_domain_check(profile.domain); + if (ret) + return ret; + + ret = pm_domain_set_expect_profile(pm_device.dev[profile.domain], + profile.index); + if (ret) + return ret; + + ret = pm_domain_set_actual_profile(pm_device.dev[profile.domain]); + if (ret) + return ret; + + if (COPY_TO_USER(args, &profile, sizeof(_k_pm_domain_profile))) + return K_ERR_PM_ILLEGAL_PARAM; + + return 0; +} + +static int pm_core_get_profile(void *args) +{ + int ret; + _k_pm_domain_profile profile; + + if (COPY_FROM_USER(&profile, args, sizeof(_k_pm_domain_profile))) + return K_ERR_PM_ILLEGAL_PARAM; + + ret = pm_core_domain_check(profile.domain); + if (ret) + return ret; + + ret = pm_domain_get_actual_profile(pm_device.dev[profile.domain], + &profile.index); + if (ret) + return ret; + + if (COPY_TO_USER(args, &profile, sizeof(_k_pm_domain_profile))) + return K_ERR_PM_ILLEGAL_PARAM; + + return 0; +} + +static int pm_core_set_profile_lock(void *args) +{ + int ret; + _k_pm_domain_profile profile; + + if (COPY_FROM_USER(&profile, args, sizeof(_k_pm_domain_profile))) + return K_ERR_PM_ILLEGAL_PARAM; + + ret = pm_core_domain_check(profile.domain); + if (ret) + return ret; + + ret = pm_domain_set_expect_profile_lock(pm_device.dev[profile.domain], + profile.index); + if (ret) + return ret; + + ret = pm_domain_set_actual_profile(pm_device.dev[profile.domain]); + + return ret; +} + +static int pm_core_set_profile_unlock(void *args) +{ + int ret; + _k_pm_domain_profile profile; + + if (COPY_FROM_USER(&profile, args, sizeof(_k_pm_domain_profile))) + return K_ERR_PM_ILLEGAL_PARAM; + + ret = pm_core_domain_check(profile.domain); + if (ret) + return ret; + + ret = pm_domain_set_expect_profile_unlock(pm_device.dev[profile.domain], + profile.index); + if (ret) + return ret; + + ret = pm_domain_set_actual_profile(pm_device.dev[profile.domain]); + + return ret; +} + +static int pm_core_set_thermal_protect(void *args) +{ + int ret; + _k_pm_domain_thermal_protect thermal; + + if (COPY_FROM_USER(&thermal, args, sizeof(_k_pm_domain_thermal_protect))) + return K_ERR_PM_ILLEGAL_PARAM; + + ret = pm_core_domain_check(thermal.domain); + if (ret) + return ret; + + if (thermal.domain != PM_DOMAIN_CPU && thermal.domain != PM_DOMAIN_KPU) + return K_ERR_PM_NOT_SUPPORT; + + pm_device.dev[thermal.domain]->thermal_protect_temp = thermal.temp; + pm_device.dev[thermal.domain]->thermal_protect_idx = thermal.index; + + return 0; +} + +static int pm_core_get_thermal_protect(void *args) +{ + int ret; + _k_pm_domain_thermal_protect thermal; + + if (COPY_FROM_USER(&thermal, args, sizeof(_k_pm_domain_thermal_protect))) + return K_ERR_PM_ILLEGAL_PARAM; + + ret = pm_core_domain_check(thermal.domain); + if (ret) + return ret; + + if (thermal.domain != PM_DOMAIN_CPU && thermal.domain != PM_DOMAIN_KPU) + return K_ERR_PM_NOT_SUPPORT; + + thermal.temp = pm_device.dev[thermal.domain]->thermal_protect_temp; + thermal.index = pm_device.dev[thermal.domain]->thermal_protect_idx; + + if (COPY_TO_USER(args, &thermal, sizeof(_k_pm_domain_thermal_protect))) + return K_ERR_PM_ILLEGAL_PARAM; + + return 0; +} + +static int pm_core_set_thermal_shutdown(void *args) +{ + int ret; + int32_t temp; + + if (COPY_FROM_USER(&temp, args, sizeof(int32_t))) + return K_ERR_PM_ILLEGAL_PARAM; + + pm_device.thermal_shutdown_temp = temp; + + return 0; +} + +static int pm_core_get_thermal_shutdown(void *args) +{ + int ret; + int32_t temp; + + if (COPY_FROM_USER(&temp, args, sizeof(int32_t))) + return K_ERR_PM_ILLEGAL_PARAM; + + temp = pm_device.thermal_shutdown_temp; + + if (COPY_TO_USER(args, &temp, sizeof(int32_t))) + return K_ERR_PM_ILLEGAL_PARAM; + + return 0; +} + +static int pm_core_set_clock(void *args) +{ + int ret; + _k_pm_domain_bool enable; + + if (COPY_FROM_USER(&enable, args, sizeof(_k_pm_domain_bool))) + return K_ERR_PM_ILLEGAL_PARAM; + + ret = pm_domain_enable_clock(pm_device.dev[enable.domain], enable.enable); + + return ret; +} + +static int pm_core_set_power(void *args) +{ + int ret; + _k_pm_domain_bool enable; + + if (COPY_FROM_USER(&enable, args, sizeof(_k_pm_domain_bool))) + return K_ERR_PM_ILLEGAL_PARAM; + + ret = pm_domain_enable_power(pm_device.dev[enable.domain], enable.enable); + + return ret; +} + +static int pm_core_open(struct dfs_fd *file) +{ + return 0; +} + +static int pm_core_close(struct dfs_fd *file) +{ + return 0; +} + +static int pm_core_ioctl(struct dfs_fd *file, int cmd, void *args) +{ + int ret; + + rt_mutex_take(&pm_device.mutex, RT_WAITING_FOREVER); + switch (cmd) { + case K_IOC_PM_SET_REG: + ret = pm_core_get_reg(args); + break; + case K_IOC_PM_GET_REG: + ret = pm_core_set_reg(args); + break; + case K_IOC_PM_GET_PROFILES: + ret = pm_core_get_profiles(args); + break; + case K_IOC_PM_GET_STAT: + ret = pm_core_get_stat(args); + break; + case K_IOC_PM_SET_GOVERNOR: + ret = pm_core_set_governor(args); + break; + case K_IOC_PM_GET_GOVERNOR: + ret = pm_core_get_governor(args); + break; + case K_IOC_PM_SET_PROFILE: + ret = pm_core_set_profile(args); + break; + case K_IOC_PM_GET_PROFILE: + ret = pm_core_get_profile(args); + break; + case K_IOC_PM_SET_PROFILE_LOCK: + ret = pm_core_set_profile_lock(args); + break; + case K_IOC_PM_SET_PROFILE_UNLOCK: + ret = pm_core_set_profile_unlock(args); + break; + case K_IOC_PM_SET_THERMAL_PROTECT: + ret = pm_core_set_thermal_protect(args); + break; + case K_IOC_PM_GET_THERMAL_PROTECT: + ret = pm_core_get_thermal_protect(args); + break; + case K_IOC_PM_SET_THERMAL_SHUTDOWN: + ret = pm_core_set_thermal_shutdown(args); + break; + case K_IOC_PM_GET_THERMAL_SHUTDOWN: + ret = pm_core_get_thermal_shutdown(args); + break; + case K_IOC_PM_SET_CLOCK: + ret = pm_core_set_clock(args); + break; + case K_IOC_PM_SET_POWER: + ret = pm_core_set_power(args); + break; + default: + ret = -EPERM; + break; + } + rt_mutex_release(&pm_device.mutex); + + return ret; +} + +static const struct dfs_file_ops pm_core_fops = { + .open = pm_core_open, + .close = pm_core_close, + .ioctl = pm_core_ioctl, +}; + +static int32_t get_temperature(void) +{ + // todo get temperature + return 0; +} + +static void shutdown(void) +{ + pm_domain_enable_power(pm_device.dev[PM_DOMAIN_KPU], false); + pm_domain_enable_power(pm_device.dev[PM_DOMAIN_DPU], false); + pm_domain_enable_power(pm_device.dev[PM_DOMAIN_VPU], false); + // todo poweroff +} + +static void thermal_detect_thread(void *arg) +{ + while (1) { + rt_thread_mdelay(THERMAL_DETECT_POLL_TIME); + + int32_t temp = get_temperature(); + + for (int i = PM_DOMAIN_CPU; i < PM_DOMAIN_NR; i++) { + if (pm_device.dev[i] == NULL) + continue; + if (i != PM_DOMAIN_CPU && i != PM_DOMAIN_KPU) + continue; + pm_device.dev[i]->thermal_over = + temp > pm_device.dev[i]->thermal_protect_temp ? true : false; + pm_domain_set_actual_profile(pm_device.dev[i]); + } + + if (temp > pm_device.thermal_shutdown_temp) + shutdown(); + } +} + +int pm_core_init(void) +{ + int ret; + rt_thread_t tid; + + ret = pm_core_default(); + if (ret) { + LOG_E("pm_core_default error\n"); + return K_ERR_PM_ILLEGAL_PARAM; + } + + for (int i = PM_DOMAIN_CPU; i < PM_DOMAIN_NR; i++) { + if (pm_device.dev[i] == NULL) + continue; + ret = pm_domain_init(pm_device.dev[i]); + if (ret !=0) { + LOG_E("domain %d init error\n", i); + return ret; + } + rt_mutex_init(&pm_device.dev[i]->mutex, "pm_mutex", RT_IPC_FLAG_PRIO); + if (pm_device.dev[i]->regulator_name) { + pm_device.dev[i]->regulator = (struct regulator_dev *) + rt_device_find(pm_device.dev[i]->regulator_name); + if (pm_device.dev[i]->regulator == RT_NULL) { + LOG_E("Can't find %s device\n", + pm_device.dev[i]->regulator_name); + return K_ERR_PM_UNEXIST; + } + } + ret = pm_domain_set_governor(pm_device.dev[i], + pm_device.dev[i]->governor); + if (ret !=0 && ret != K_ERR_PM_NOT_SUPPORT) { + LOG_E("domain %d set_governor error\n", i); + return ret; + } + } + + ret = rt_device_register(&pm_device.parent, "pm", RT_DEVICE_FLAG_RDWR); + if (ret) { + LOG_E("regulator register fail: %d\n", ret); + return -1; + } + + pm_device.parent.fops = &pm_core_fops; + ret = rt_mutex_init(&pm_device.mutex, "pm_mutex", RT_IPC_FLAG_PRIO); + + tid = rt_thread_create("thermal_detect_thread", thermal_detect_thread, + RT_NULL, 1024 * 10, RT_THREAD_PRIORITY_MAX / 2, + rt_tick_from_millisecond(10)); + rt_thread_startup(tid); + + // temporary fix + pm_domain_enable_clock(pm_device.dev[PM_DOMAIN_KPU], true); + pm_domain_enable_power(pm_device.dev[PM_DOMAIN_KPU], true); + + return ret; +} diff --git a/src/big/mpp/kernel/pm/src/pm_domain.c b/src/big/mpp/kernel/pm/src/pm_domain.c new file mode 100644 index 000000000..8d59e472b --- /dev/null +++ b/src/big/mpp/kernel/pm/src/pm_domain.c @@ -0,0 +1,223 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "pm_domain.h" + +#define PROFILE_IS_UP(from, to) (from > to) + +static int pm_domain_profile_index_transform(struct pm_domain_dev *pdev, + int32_t index) +{ + if (index < 0) + index = pdev->profile_nr + index; + + if (index < 0) + index = 0; + else if (index >= pdev->profile_nr) + index = pdev->profile_nr - 1; + + return index; +} + +int pm_domain_init(struct pm_domain_dev *pdev) +{ + if (pdev->ops && pdev->ops->init) + return pdev->ops->init(); + + return 0; +} + +int pm_domain_set_governor(struct pm_domain_dev *pdev, k_pm_governor governor) +{ + int ret; + + if (pdev->governor == governor) + return 0; + + if (!pdev->ops || !pdev->ops->set_governor) + return K_ERR_PM_NOT_SUPPORT; + + ret = pdev->ops->set_governor(governor); + + return ret; +} + +int pm_domain_set_expect_profile(struct pm_domain_dev *pdev, int32_t index) +{ + int ret; + + if (pdev->governor != PM_GOVERNOR_MANUAL) + return K_ERR_PM_NOT_SUPPORT; + + pdev->expect_profile_idx = index; + + return 0; +} + +int pm_domain_set_expect_profile_lock(struct pm_domain_dev *pdev, + int32_t index) +{ + int ret; + + if (pdev->governor != PM_GOVERNOR_MANUAL) + return K_ERR_PM_NOT_SUPPORT; + + index = pm_domain_profile_index_transform(pdev, index); + + if (pdev->profile_lock[index] >= UINT32_MAX) + return K_ERR_PM_BUSY; + + pdev->profile_lock[index]++; + for (int i = 0; i < pdev->profile_nr; i++) { + if (pdev->profile_lock[i]) { + pdev->expect_profile_idx = i; + break; + } + } + + return 0; +} + +int pm_domain_set_expect_profile_unlock(struct pm_domain_dev *pdev, + int32_t index) +{ + int ret; + + if (pdev->governor != PM_GOVERNOR_MANUAL) + return K_ERR_PM_NOT_SUPPORT; + + index = pm_domain_profile_index_transform(pdev, index); + + if (pdev->profile_lock[index] == 0) + return K_ERR_PM_BUSY; + + pdev->profile_lock[index]--; + for (int i = 0; i < pdev->profile_nr; i++) { + if (pdev->profile_lock[i]) { + pdev->expect_profile_idx = i; + break; + } + } + + return 0; +} + +int pm_domain_get_expect_profile(struct pm_domain_dev *pdev) +{ + if (pdev->governor == PM_GOVERNOR_PERFORMANCE) + pdev->expect_profile_idx = 0; + else if (pdev->governor == PM_GOVERNOR_ENERGYSAVING) + pdev->expect_profile_idx = pdev->profile_nr - 1; + + if (pdev->ops && pdev->ops->get_expect_profile) + pdev->ops->get_expect_profile(); + + return 0; +} + +int pm_domain_set_actual_profile(struct pm_domain_dev *pdev) +{ + int ret; + int32_t from_idx_cvt; + int32_t to_idx, to_idx_cvt; + int32_t expect_profile_idx, expect_profile_idx_cvt; + int32_t thermal_protect_idx, thermal_protect_idx_cvt; + + if (!pdev->ops || !pdev->ops->set_clock) + return K_ERR_PM_NOT_SUPPORT; + + rt_mutex_take(&pdev->mutex, RT_WAITING_FOREVER); + thermal_protect_idx = pdev->thermal_protect_idx; + expect_profile_idx = pdev->expect_profile_idx; + thermal_protect_idx_cvt = pm_domain_profile_index_transform(pdev, + thermal_protect_idx); + expect_profile_idx_cvt = pm_domain_profile_index_transform(pdev, + expect_profile_idx); + if (pdev->thermal_over && + PROFILE_IS_UP(thermal_protect_idx_cvt, expect_profile_idx_cvt)) { + to_idx = thermal_protect_idx; + to_idx_cvt = thermal_protect_idx_cvt; + } else { + to_idx = expect_profile_idx; + to_idx_cvt = expect_profile_idx_cvt; + } + from_idx_cvt = pm_domain_profile_index_transform(pdev, + pdev->actual_profile_idx); + if (from_idx_cvt == to_idx_cvt) { + rt_mutex_release(&pdev->mutex); + return 0; + } + + if (pdev->regulator == NULL) { + ret = pdev->ops->set_clock(pdev->profiles[to_idx_cvt].freq); + } else if (PROFILE_IS_UP(from_idx_cvt, to_idx_cvt)) { + if (pdev->profiles[from_idx_cvt].volt == + pdev->profiles[to_idx_cvt].volt) { + ret = 0; + } else { + ret = regulator_set_voltage(pdev->regulator, + pdev->profiles[to_idx_cvt].volt); + rt_thread_mdelay(1); + } + if (ret == 0) + ret = pdev->ops->set_clock(pdev->profiles[to_idx_cvt].freq); + } else { + ret = pdev->ops->set_clock(pdev->profiles[to_idx_cvt].freq); + if (ret == 0 && pdev->profiles[from_idx_cvt].volt != + pdev->profiles[to_idx_cvt].volt) + ret = regulator_set_voltage(pdev->regulator, + pdev->profiles[to_idx_cvt].volt); + } + + if (ret == 0) + pdev->actual_profile_idx = to_idx; + + rt_mutex_release(&pdev->mutex); + + return ret; +} + +int pm_domain_get_actual_profile(struct pm_domain_dev *pdev, int32_t *pindex) +{ + *pindex = pm_domain_profile_index_transform(pdev, pdev->actual_profile_idx); + + return 0; +} + +int pm_domain_enable_clock(struct pm_domain_dev *pdev, bool enable) +{ + if (!pdev->ops || !pdev->ops->enable_clock) + return K_ERR_PM_NOT_SUPPORT; + + return pdev->ops->enable_clock(enable); +} + +int pm_domain_enable_power(struct pm_domain_dev *pdev, bool enable) +{ + if (!pdev->ops || !pdev->ops->enable_power) + return K_ERR_PM_NOT_SUPPORT; + + return pdev->ops->enable_power(enable); +} diff --git a/src/big/mpp/kernel/pm/src/pm_domain.h b/src/big/mpp/kernel/pm/src/pm_domain.h new file mode 100644 index 000000000..b7a788cfd --- /dev/null +++ b/src/big/mpp/kernel/pm/src/pm_domain.h @@ -0,0 +1,81 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __PM_DOMAIN_H__ +#define __PM_DOMAIN_H__ + +#include "k_pm_comm.h" +#include "regulator.h" +#include "sysctl_media_clk.h" +#include "sysctl_pwr.h" + +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + +struct pm_domain_ops { + int (*init)(void); + int (*set_governor)(k_pm_governor governor); + int (*get_expect_profile)(void); + int (*enable_clock)(bool enable); + int (*set_clock)(int32_t freq); + int (*enable_power)(bool enable); + int (*get_stat)(void); +}; + +struct pm_domain_dev { + struct rt_mutex mutex; + k_pm_profile *profiles; + uint32_t *profile_lock; + uint32_t profile_nr; + int32_t expect_profile_idx; + int32_t actual_profile_idx; + k_pm_governor governor; + int32_t thermal_protect_temp; + int32_t thermal_protect_idx; + bool thermal_over; + const char *regulator_name; + struct regulator_dev *regulator; + struct pm_domain_ops *ops; +}; + +extern struct pm_domain_dev pm_domain_cpu; +extern struct pm_domain_dev pm_domain_kpu; +extern struct pm_domain_dev pm_domain_vpu; +extern struct pm_domain_dev pm_domain_dpu; +extern struct pm_domain_dev pm_domain_disp; + +int pm_domain_init(struct pm_domain_dev *pdev); +int pm_domain_set_governor(struct pm_domain_dev *pdev, k_pm_governor governor); +int pm_domain_set_expect_profile(struct pm_domain_dev *pdev, int32_t index); +int pm_domain_set_expect_profile_lock(struct pm_domain_dev *pdev, + int32_t index); +int pm_domain_set_expect_profile_unlock(struct pm_domain_dev *pdev, + int32_t index); +int pm_domain_get_expect_profile(struct pm_domain_dev *pdev); +int pm_domain_set_actual_profile(struct pm_domain_dev *pdev); +int pm_domain_get_actual_profile(struct pm_domain_dev *pdev, int32_t *pindex); +int pm_domain_enable_clock(struct pm_domain_dev *pdev, bool enable); +int pm_domain_enable_power(struct pm_domain_dev *pdev, bool enable); + +#endif /* __PM_DOMAIN_H__ */ diff --git a/src/big/mpp/kernel/pm/src/pm_domain_cpu.c b/src/big/mpp/kernel/pm/src/pm_domain_cpu.c new file mode 100644 index 000000000..10650ee3b --- /dev/null +++ b/src/big/mpp/kernel/pm/src/pm_domain_cpu.c @@ -0,0 +1,185 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "pm_domain.h" + +#define AUTO_GOVERNOR_POLL_TIME 100 // ms + +static k_pm_profile profiles[] = { + {1.6e9, 0.8e6}, + {1.188e9, 0.7e6}, + {0.8e9, 0.68e6}, + {0.594e9, 0.66e6}, + {0.4e9, 0.64e6}, + {0.2e9, 0.62e6}, +}; + +static uint32_t profile_lock[ARRAY_SIZE(profiles)]; +static bool auto_load_enable; +static uint8_t load_table[ARRAY_SIZE(profiles)][ARRAY_SIZE(profiles)] = { + {64, 43, 31, 20, 10}, + {90, 58, 43, 28, 14}, + {90, 99, 64, 43, 20}, + {90, 99, 99, 58, 28}, + {90, 99, 99, 99, 43}, + {90, 99, 99, 99, 99}, +}; + +static int get_expect_profile(void); + +extern rt_uint8_t sys_cpu_usage(rt_uint8_t cpu_id); +static int32_t auto_governor_get_profile(void) +{ + int load; + int32_t index; + uint8_t *table; + + load = sys_cpu_usage(0); + pm_domain_get_actual_profile(&pm_domain_cpu, &index); + + table = load_table[index]; + + index = -1; + for (int i = 0; i < ARRAY_SIZE(profiles); i++) { + if (load > table[i]) { + index = i; + break; + } + } + + return index; +} + +static void auto_load_thread(void *arg) +{ + while (1) { + rt_thread_mdelay(AUTO_GOVERNOR_POLL_TIME); + if (!auto_load_enable) + continue; + get_expect_profile(); + pm_domain_set_actual_profile(&pm_domain_cpu); + } +} + +static int init(void) +{ + rt_thread_t tid; + + tid = rt_thread_create("auto_load_thread", auto_load_thread, + RT_NULL, 1024 * 10, RT_THREAD_PRIORITY_MAX / 2, + rt_tick_from_millisecond(10)); + rt_thread_startup(tid); + + return 0; +} + +static int set_governor(k_pm_governor governor) +{ + if (governor == PM_GOVERNOR_MANUAL || + governor == PM_GOVERNOR_PERFORMANCE || + governor == PM_GOVERNOR_ENERGYSAVING || + governor == PM_GOVERNOR_AUTO) { + pm_domain_cpu.governor = governor; + + auto_load_enable = governor == PM_GOVERNOR_AUTO ? true : false; + + if (governor == PM_GOVERNOR_MANUAL) + memset(profile_lock, 0, sizeof(profile_lock)); + + return 0; + } + + return K_ERR_PM_ILLEGAL_PARAM; +} + +static int get_expect_profile(void) +{ + if (pm_domain_cpu.governor != PM_GOVERNOR_AUTO) + return -1; + + pm_domain_cpu.expect_profile_idx = auto_governor_get_profile(); + + return 0; +} + +static int set_clock(int32_t freq) +{ + int ret; + + switch (freq) { + case (int)1.6e9: + ret = sysctl_media_clk_set_leaf_parent_div(SYSCTL_CLK_CPU_1_SRC, + SYSCTL_CLK_ROOT_PLL0, 1, 1); + break; + case (int)1.188e9: + ret = sysctl_media_clk_set_leaf_parent_div(SYSCTL_CLK_CPU_1_SRC, + SYSCTL_CLK_ROOT_PLL1_DIV_2, 1, 1); + break; + case (int)0.8e9: + ret = sysctl_media_clk_set_leaf_parent_div(SYSCTL_CLK_CPU_1_SRC, + SYSCTL_CLK_ROOT_PLL0, 1, 2); + break; + case (int)0.594e9: + ret = sysctl_media_clk_set_leaf_parent_div(SYSCTL_CLK_CPU_1_SRC, + SYSCTL_CLK_ROOT_PLL1_DIV_2, 1, 2); + break; + case (int)0.4e9: + ret = sysctl_media_clk_set_leaf_parent_div(SYSCTL_CLK_CPU_1_SRC, + SYSCTL_CLK_ROOT_PLL0, 1, 4); + break; + case (int)0.2e9: + ret = sysctl_media_clk_set_leaf_parent_div(SYSCTL_CLK_CPU_1_SRC, + SYSCTL_CLK_ROOT_PLL0, 1, 8); + break; + default: + ret = K_ERR_PM_ILLEGAL_PARAM; + break; + } + + return ret ? 0 : K_ERR_PM_ILLEGAL_PARAM; +} + +static int get_stat(void) +{ + +} + +static struct pm_domain_ops ops = { + .init = init, + .set_governor = set_governor, + .get_expect_profile = get_expect_profile, + .set_clock = set_clock, + .get_stat = get_stat, +}; + +struct pm_domain_dev pm_domain_cpu = { + .profiles = profiles, + .profile_nr = ARRAY_SIZE(profiles), + .profile_lock = profile_lock, + .regulator_name = "regulator_cpu", + .ops = &ops, +}; diff --git a/src/big/mpp/kernel/pm/src/pm_domain_disp.c b/src/big/mpp/kernel/pm/src/pm_domain_disp.c new file mode 100644 index 000000000..be2f78141 --- /dev/null +++ b/src/big/mpp/kernel/pm/src/pm_domain_disp.c @@ -0,0 +1,56 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "pm_domain.h" + +static k_pm_profile profiles[] = { + {30, 0}, +}; + +static uint32_t profile_lock[ARRAY_SIZE(profiles)]; + +static int enable_power(bool enable) +{ + int ret; + + if (enable) + ret = sysctl_pwr_up(SYSCTL_PD_DISP); + else + ret = sysctl_pwr_off(SYSCTL_PD_DISP); + + return ret ? 0 : K_ERR_PM_BUSY; +} + +static struct pm_domain_ops ops = { + .enable_power = enable_power, +}; + +struct pm_domain_dev pm_domain_disp = { + .profiles = profiles, + .profile_nr = ARRAY_SIZE(profiles), + .profile_lock = profile_lock, + .ops = &ops, +}; diff --git a/src/big/mpp/kernel/pm/src/pm_domain_dpu.c b/src/big/mpp/kernel/pm/src/pm_domain_dpu.c new file mode 100644 index 000000000..9a4e2e344 --- /dev/null +++ b/src/big/mpp/kernel/pm/src/pm_domain_dpu.c @@ -0,0 +1,98 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "pm_domain.h" + +static k_pm_profile profiles[] = { + {0.594e9, 0}, +}; + +static uint32_t profile_lock[ARRAY_SIZE(profiles)]; + +static int set_governor(k_pm_governor governor) +{ + if (governor == PM_GOVERNOR_MANUAL || + governor == PM_GOVERNOR_PERFORMANCE || + governor == PM_GOVERNOR_ENERGYSAVING) { + pm_domain_kpu.governor = governor; + + if (governor == PM_GOVERNOR_MANUAL) + memset(profile_lock, 0, sizeof(profile_lock)); + + return 0; + } + + return K_ERR_PM_ILLEGAL_PARAM; +} + +static int enable_clock(bool enable) +{ + sysctl_media_clk_set_leaf_en_multi(SYSCTL_CLK_DPU_CLK, enable); + + return 0; +} + +static int set_clock(int32_t freq) +{ + int ret; + + switch (freq) { + case (int)0.8e9: + ret = sysctl_media_clk_set_leaf_div(SYSCTL_CLK_DPU_CLK, 16, 16); + break; + default: + ret = K_ERR_PM_ILLEGAL_PARAM; + break; + } + + return ret ? 0 : K_ERR_PM_ILLEGAL_PARAM; +} + +static int enable_power(bool enable) +{ + int ret; + + if (enable) + ret = sysctl_pwr_up(SYSCTL_PD_DPU); + else + ret = sysctl_pwr_off(SYSCTL_PD_DPU); + + return ret ? 0 : K_ERR_PM_BUSY; +} + +static struct pm_domain_ops ops = { + .set_governor = set_governor, + .enable_clock = enable_clock, + .set_clock = set_clock, + .enable_power = enable_power, +}; + +struct pm_domain_dev pm_domain_dpu = { + .profiles = profiles, + .profile_nr = ARRAY_SIZE(profiles), + .profile_lock = profile_lock, + .ops = &ops, +}; diff --git a/src/big/mpp/kernel/pm/src/pm_domain_kpu.c b/src/big/mpp/kernel/pm/src/pm_domain_kpu.c new file mode 100644 index 000000000..ae39f961d --- /dev/null +++ b/src/big/mpp/kernel/pm/src/pm_domain_kpu.c @@ -0,0 +1,115 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "pm_domain.h" + +static k_pm_profile profiles[] = { + {0.8e9, 0.8e6}, + {0.4e9, 0.8e6}, + {0.2e9, 0.8e6}, + {0.1e9, 0.8e6}, +}; + +static uint32_t profile_lock[ARRAY_SIZE(profiles)]; + +static int set_governor(k_pm_governor governor) +{ + if (governor == PM_GOVERNOR_MANUAL || + governor == PM_GOVERNOR_PERFORMANCE || + governor == PM_GOVERNOR_ENERGYSAVING) { + pm_domain_kpu.governor = governor; + + if (governor == PM_GOVERNOR_MANUAL) + memset(profile_lock, 0, sizeof(profile_lock)); + + return 0; + } + + return K_ERR_PM_ILLEGAL_PARAM; +} + +static int enable_clock(bool enable) +{ + sysctl_media_clk_set_leaf_en_multi(SYSCTL_CLK_AI_SRC, enable); + + return 0; +} + +static int set_clock(int32_t freq) +{ + int ret; + + switch (freq) { + case (int)0.8e9: + ret = sysctl_media_clk_set_leaf_parent_div(SYSCTL_CLK_AI_SRC, + SYSCTL_CLK_ROOT_PLL3_DIV_2, 1, 1); + break; + case (int)0.4e9: + ret = sysctl_media_clk_set_leaf_parent_div(SYSCTL_CLK_AI_SRC, + SYSCTL_CLK_ROOT_PLL3_DIV_2, 1, 2); + break; + case (int)0.2e9: + ret = sysctl_media_clk_set_leaf_parent_div(SYSCTL_CLK_AI_SRC, + SYSCTL_CLK_ROOT_PLL3_DIV_2, 1, 4); + break; + case (int)0.1e9: + ret = sysctl_media_clk_set_leaf_parent_div(SYSCTL_CLK_AI_SRC, + SYSCTL_CLK_ROOT_PLL3_DIV_2, 1, 8); + break; + default: + ret = K_ERR_PM_ILLEGAL_PARAM; + break; + } + + return ret ? 0 : K_ERR_PM_ILLEGAL_PARAM; +} + +static int enable_power(bool enable) +{ + int ret; + + if (enable) + ret = sysctl_pwr_up(SYSCTL_PD_AI); + else + ret = sysctl_pwr_off(SYSCTL_PD_AI); + + return ret ? 0 : K_ERR_PM_BUSY; +} + +static struct pm_domain_ops ops = { + .set_governor = set_governor, + .enable_clock = enable_clock, + .set_clock = set_clock, + .enable_power = enable_power, +}; + +struct pm_domain_dev pm_domain_kpu = { + .profiles = profiles, + .profile_nr = ARRAY_SIZE(profiles), + .profile_lock = profile_lock, + .regulator_name = "regulator_kpu", + .ops = &ops, +}; diff --git a/src/big/mpp/kernel/pm/src/pm_domain_vpu.c b/src/big/mpp/kernel/pm/src/pm_domain_vpu.c new file mode 100644 index 000000000..67711c814 --- /dev/null +++ b/src/big/mpp/kernel/pm/src/pm_domain_vpu.c @@ -0,0 +1,98 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "pm_domain.h" + +static k_pm_profile profiles[] = { + {0.8e9, 0}, +}; + +static uint32_t profile_lock[ARRAY_SIZE(profiles)]; + +static int set_governor(k_pm_governor governor) +{ + if (governor == PM_GOVERNOR_MANUAL || + governor == PM_GOVERNOR_PERFORMANCE || + governor == PM_GOVERNOR_ENERGYSAVING) { + pm_domain_kpu.governor = governor; + + if (governor == PM_GOVERNOR_MANUAL) + memset(profile_lock, 0, sizeof(profile_lock)); + + return 0; + } + + return K_ERR_PM_ILLEGAL_PARAM; +} + +static int enable_clock(bool enable) +{ + sysctl_media_clk_set_leaf_en_multi(SYSCTL_CLK_VPU_SRC, enable); + + return 0; +} + +static int set_clock(int32_t freq) +{ + int ret; + + switch (freq) { + case (int)0.8e9: + ret = sysctl_media_clk_set_leaf_div(SYSCTL_CLK_VPU_SRC, 16, 16); + break; + default: + ret = K_ERR_PM_ILLEGAL_PARAM; + break; + } + + return ret ? 0 : K_ERR_PM_ILLEGAL_PARAM; +} + +static int enable_power(bool enable) +{ + int ret; + + if (enable) + ret = sysctl_pwr_up(SYSCTL_PD_VPU); + else + ret = sysctl_pwr_off(SYSCTL_PD_VPU); + + return ret ? 0 : K_ERR_PM_BUSY; +} + +static struct pm_domain_ops ops = { + .set_governor = set_governor, + .enable_clock = enable_clock, + .set_clock = set_clock, + .enable_power = enable_power, +}; + +struct pm_domain_dev pm_domain_vpu = { + .profiles = profiles, + .profile_nr = ARRAY_SIZE(profiles), + .profile_lock = profile_lock, + .ops = &ops, +}; diff --git a/src/big/mpp/userapps/api/mpi_connector_api.h b/src/big/mpp/userapps/api/mpi_connector_api.h index da2be6d12..fce317138 100755 --- a/src/big/mpp/userapps/api/mpi_connector_api.h +++ b/src/big/mpp/userapps/api/mpi_connector_api.h @@ -55,6 +55,10 @@ k_s32 kd_mpi_connector_close(k_s32 fd); k_s32 kd_mpi_connector_open(const char *connector_name); +k_s32 kd_mpi_connector_get_negotiated_data(k_s32 fd, k_connector_negotiated_data *negotiated_data); + +k_s32 kd_mpi_connector_adapt_resolution(k_connector_type connector_type, k_connector_negotiated_data *negotiated_data); + k_s32 kd_mpi_get_connector_info(k_connector_type connector_type, k_connector_info *connector_info); diff --git a/src/big/mpp/userapps/lib/lib3a.a b/src/big/mpp/userapps/lib/lib3a.a index 582dd3e50..321e97f11 100644 Binary files a/src/big/mpp/userapps/lib/lib3a.a and b/src/big/mpp/userapps/lib/lib3a.a differ diff --git a/src/big/mpp/userapps/lib/libadec.a b/src/big/mpp/userapps/lib/libadec.a index a3e277c78..fa7ef99ce 100644 Binary files a/src/big/mpp/userapps/lib/libadec.a and b/src/big/mpp/userapps/lib/libadec.a differ diff --git a/src/big/mpp/userapps/lib/libaenc.a b/src/big/mpp/userapps/lib/libaenc.a index 183ca0234..4aac73ef3 100644 Binary files a/src/big/mpp/userapps/lib/libaenc.a and b/src/big/mpp/userapps/lib/libaenc.a differ diff --git a/src/big/mpp/userapps/lib/libai.a b/src/big/mpp/userapps/lib/libai.a index 29c25a4c2..a8672e8bd 100644 Binary files a/src/big/mpp/userapps/lib/libai.a and b/src/big/mpp/userapps/lib/libai.a differ diff --git a/src/big/mpp/userapps/lib/libao.a b/src/big/mpp/userapps/lib/libao.a index 986b3a635..377e90d0e 100644 Binary files a/src/big/mpp/userapps/lib/libao.a and b/src/big/mpp/userapps/lib/libao.a differ diff --git a/src/big/mpp/userapps/lib/libauto_ctrol.a b/src/big/mpp/userapps/lib/libauto_ctrol.a index ab8338e81..774a5a685 100644 Binary files a/src/big/mpp/userapps/lib/libauto_ctrol.a and b/src/big/mpp/userapps/lib/libauto_ctrol.a differ diff --git a/src/big/mpp/userapps/lib/libbinder.a b/src/big/mpp/userapps/lib/libbinder.a index 0859af5c0..05bccd296 100644 Binary files a/src/big/mpp/userapps/lib/libbinder.a and b/src/big/mpp/userapps/lib/libbinder.a differ diff --git a/src/big/mpp/userapps/lib/libbuffer_management.a b/src/big/mpp/userapps/lib/libbuffer_management.a index aa81895aa..1da0a1e70 100644 Binary files a/src/big/mpp/userapps/lib/libbuffer_management.a and b/src/big/mpp/userapps/lib/libbuffer_management.a differ diff --git a/src/big/mpp/userapps/lib/libcam_caldb.a b/src/big/mpp/userapps/lib/libcam_caldb.a index 8463a112b..378233207 100644 Binary files a/src/big/mpp/userapps/lib/libcam_caldb.a and b/src/big/mpp/userapps/lib/libcam_caldb.a differ diff --git a/src/big/mpp/userapps/lib/libcam_device.a b/src/big/mpp/userapps/lib/libcam_device.a index b79aa53c0..ec4f49ff6 100644 Binary files a/src/big/mpp/userapps/lib/libcam_device.a and b/src/big/mpp/userapps/lib/libcam_device.a differ diff --git a/src/big/mpp/userapps/lib/libcam_engine.a b/src/big/mpp/userapps/lib/libcam_engine.a index da34c2944..389e36e92 100644 Binary files a/src/big/mpp/userapps/lib/libcam_engine.a and b/src/big/mpp/userapps/lib/libcam_engine.a differ diff --git a/src/big/mpp/userapps/lib/libcameric_drv.a b/src/big/mpp/userapps/lib/libcameric_drv.a index 0968165a8..537309b94 100644 Binary files a/src/big/mpp/userapps/lib/libcameric_drv.a and b/src/big/mpp/userapps/lib/libcameric_drv.a differ diff --git a/src/big/mpp/userapps/lib/libcameric_reg_drv.a b/src/big/mpp/userapps/lib/libcameric_reg_drv.a index b40b0b3b7..fae470a65 100644 Binary files a/src/big/mpp/userapps/lib/libcameric_reg_drv.a and b/src/big/mpp/userapps/lib/libcameric_reg_drv.a differ diff --git a/src/big/mpp/userapps/lib/libcmd_buffer.a b/src/big/mpp/userapps/lib/libcmd_buffer.a index b21938890..d74713f43 100644 Binary files a/src/big/mpp/userapps/lib/libcmd_buffer.a and b/src/big/mpp/userapps/lib/libcmd_buffer.a differ diff --git a/src/big/mpp/userapps/lib/libcommon.a b/src/big/mpp/userapps/lib/libcommon.a index 25ffaf8d5..82f176450 100644 Binary files a/src/big/mpp/userapps/lib/libcommon.a and b/src/big/mpp/userapps/lib/libcommon.a differ diff --git a/src/big/mpp/userapps/lib/libdma.a b/src/big/mpp/userapps/lib/libdma.a index 47c08197e..ecf001afa 100644 Binary files a/src/big/mpp/userapps/lib/libdma.a and b/src/big/mpp/userapps/lib/libdma.a differ diff --git a/src/big/mpp/userapps/lib/libdpu.a b/src/big/mpp/userapps/lib/libdpu.a index d37861846..452b3d102 100644 Binary files a/src/big/mpp/userapps/lib/libdpu.a and b/src/big/mpp/userapps/lib/libdpu.a differ diff --git a/src/big/mpp/userapps/lib/libebase.a b/src/big/mpp/userapps/lib/libebase.a index 1ef59213b..60c3ccbf9 100644 Binary files a/src/big/mpp/userapps/lib/libebase.a and b/src/big/mpp/userapps/lib/libebase.a differ diff --git a/src/big/mpp/userapps/lib/libfpga.a b/src/big/mpp/userapps/lib/libfpga.a index 897c35736..ae383c6ce 100644 Binary files a/src/big/mpp/userapps/lib/libfpga.a and b/src/big/mpp/userapps/lib/libfpga.a differ diff --git a/src/big/mpp/userapps/lib/libhal.a b/src/big/mpp/userapps/lib/libhal.a index 965d665eb..3aae2d13a 100644 Binary files a/src/big/mpp/userapps/lib/libhal.a and b/src/big/mpp/userapps/lib/libhal.a differ diff --git a/src/big/mpp/userapps/lib/libisi.a b/src/big/mpp/userapps/lib/libisi.a index 62208442e..87ca8e4f1 100644 Binary files a/src/big/mpp/userapps/lib/libisi.a and b/src/big/mpp/userapps/lib/libisi.a differ diff --git a/src/big/mpp/userapps/lib/libisp_drv.a b/src/big/mpp/userapps/lib/libisp_drv.a index 13e5aa961..e51971a0d 100644 Binary files a/src/big/mpp/userapps/lib/libisp_drv.a and b/src/big/mpp/userapps/lib/libisp_drv.a differ diff --git a/src/big/mpp/userapps/lib/liboslayer.a b/src/big/mpp/userapps/lib/liboslayer.a index 8e9e88836..e8a0abba0 100644 Binary files a/src/big/mpp/userapps/lib/liboslayer.a and b/src/big/mpp/userapps/lib/liboslayer.a differ diff --git a/src/big/mpp/userapps/lib/libpm.a b/src/big/mpp/userapps/lib/libpm.a deleted file mode 100644 index 2df93f2b7..000000000 Binary files a/src/big/mpp/userapps/lib/libpm.a and /dev/null differ diff --git a/src/big/mpp/userapps/lib/libsom_ctrl.a b/src/big/mpp/userapps/lib/libsom_ctrl.a index ba321fa46..f1c146dfa 100644 Binary files a/src/big/mpp/userapps/lib/libsom_ctrl.a and b/src/big/mpp/userapps/lib/libsom_ctrl.a differ diff --git a/src/big/mpp/userapps/lib/libstart_engine.a b/src/big/mpp/userapps/lib/libstart_engine.a index a5e35d19d..5b82b2174 100644 Binary files a/src/big/mpp/userapps/lib/libstart_engine.a and b/src/big/mpp/userapps/lib/libstart_engine.a differ diff --git a/src/big/mpp/userapps/lib/libswitch.a b/src/big/mpp/userapps/lib/libswitch.a index c5eeb386a..01c633d2b 100644 Binary files a/src/big/mpp/userapps/lib/libswitch.a and b/src/big/mpp/userapps/lib/libswitch.a differ diff --git a/src/big/mpp/userapps/lib/libsys.a b/src/big/mpp/userapps/lib/libsys.a index f6fb7b68a..a5509ef3e 100644 Binary files a/src/big/mpp/userapps/lib/libsys.a and b/src/big/mpp/userapps/lib/libsys.a differ diff --git a/src/big/mpp/userapps/lib/libt_common_c.a b/src/big/mpp/userapps/lib/libt_common_c.a index 2007357ff..91d27cc94 100644 Binary files a/src/big/mpp/userapps/lib/libt_common_c.a and b/src/big/mpp/userapps/lib/libt_common_c.a differ diff --git a/src/big/mpp/userapps/lib/libt_database_c.a b/src/big/mpp/userapps/lib/libt_database_c.a index 3809480be..8cc5fe7f6 100644 Binary files a/src/big/mpp/userapps/lib/libt_database_c.a and b/src/big/mpp/userapps/lib/libt_database_c.a differ diff --git a/src/big/mpp/userapps/lib/libt_json_c.a b/src/big/mpp/userapps/lib/libt_json_c.a index b7e3c6204..c076dfd59 100644 Binary files a/src/big/mpp/userapps/lib/libt_json_c.a and b/src/big/mpp/userapps/lib/libt_json_c.a differ diff --git a/src/big/mpp/userapps/lib/libt_mxml_c.a b/src/big/mpp/userapps/lib/libt_mxml_c.a index 34486737f..58793e3c9 100644 Binary files a/src/big/mpp/userapps/lib/libt_mxml_c.a and b/src/big/mpp/userapps/lib/libt_mxml_c.a differ diff --git a/src/big/mpp/userapps/lib/libvb.a b/src/big/mpp/userapps/lib/libvb.a index 1d757003f..e283cc931 100644 Binary files a/src/big/mpp/userapps/lib/libvb.a and b/src/big/mpp/userapps/lib/libvb.a differ diff --git a/src/big/mpp/userapps/lib/libvdec.a b/src/big/mpp/userapps/lib/libvdec.a index 7da13d70a..2e9a9de61 100644 Binary files a/src/big/mpp/userapps/lib/libvdec.a and b/src/big/mpp/userapps/lib/libvdec.a differ diff --git a/src/big/mpp/userapps/lib/libvdss.a b/src/big/mpp/userapps/lib/libvdss.a index c62854b71..9eac37829 100644 Binary files a/src/big/mpp/userapps/lib/libvdss.a and b/src/big/mpp/userapps/lib/libvdss.a differ diff --git a/src/big/mpp/userapps/lib/libvenc.a b/src/big/mpp/userapps/lib/libvenc.a index c842ee3e0..505f20a4f 100644 Binary files a/src/big/mpp/userapps/lib/libvenc.a and b/src/big/mpp/userapps/lib/libvenc.a differ diff --git a/src/big/mpp/userapps/lib/libvicap.a b/src/big/mpp/userapps/lib/libvicap.a index 7e9c60a7b..7b4ea6102 100644 Binary files a/src/big/mpp/userapps/lib/libvicap.a and b/src/big/mpp/userapps/lib/libvicap.a differ diff --git a/src/big/mpp/userapps/lib/libvideo_in.a b/src/big/mpp/userapps/lib/libvideo_in.a index 3b4a9fb15..5e477d3aa 100644 Binary files a/src/big/mpp/userapps/lib/libvideo_in.a and b/src/big/mpp/userapps/lib/libvideo_in.a differ diff --git a/src/big/mpp/userapps/lib/libvirtual_hal.a b/src/big/mpp/userapps/lib/libvirtual_hal.a index 5b3e03aa6..bed64186c 100644 Binary files a/src/big/mpp/userapps/lib/libvirtual_hal.a and b/src/big/mpp/userapps/lib/libvirtual_hal.a differ diff --git a/src/big/mpp/userapps/lib/libvo.a b/src/big/mpp/userapps/lib/libvo.a index 62b3c02b2..f1e09c81f 100644 Binary files a/src/big/mpp/userapps/lib/libvo.a and b/src/big/mpp/userapps/lib/libvo.a differ diff --git a/src/big/mpp/userapps/lib/libvvi.a b/src/big/mpp/userapps/lib/libvvi.a index be7a492ea..c18ff310d 100644 Binary files a/src/big/mpp/userapps/lib/libvvi.a and b/src/big/mpp/userapps/lib/libvvi.a differ diff --git a/src/big/mpp/userapps/sample/Makefile b/src/big/mpp/userapps/sample/Makefile index d73903a4c..57fc9848a 100644 --- a/src/big/mpp/userapps/sample/Makefile +++ b/src/big/mpp/userapps/sample/Makefile @@ -6,7 +6,7 @@ all: @cd sample_audio; make || exit 1 @cd sample_dma; make || exit 1 @cd sample_mmz; make || exit 1 -# @cd sample_nonai_2d; make || exit 1 + @cd sample_nonai_2d; make || exit 1 @cd sample_vb; make || exit 1 @cd sample_vdec; make || exit 1 @cd sample_venc; make || exit 1 diff --git a/src/big/mpp/userapps/sample/sample_audio/sample_audio.c b/src/big/mpp/userapps/sample/sample_audio/sample_audio.c index d7557d9cc..0ad6130a7 100644 --- a/src/big/mpp/userapps/sample/sample_audio/sample_audio.c +++ b/src/big/mpp/userapps/sample/sample_audio/sample_audio.c @@ -253,8 +253,11 @@ int main(int argc, char *argv[]) if (g_type >= 2 && g_type <= 12) { - printf("enter any key to exit\n"); - getchar(); + printf("enter q key to exit\n"); + while(getchar() != 'q') + { + usleep(100*1000); + } } audio_sample_exit(); pthread_join(g_pthread_handle, NULL); diff --git a/src/big/mpp/userapps/sample/sample_dpu/sample_dpu.c b/src/big/mpp/userapps/sample/sample_dpu/sample_dpu.c index 202877aa5..cc6367daf 100755 --- a/src/big/mpp/userapps/sample/sample_dpu/sample_dpu.c +++ b/src/big/mpp/userapps/sample/sample_dpu/sample_dpu.c @@ -55,6 +55,7 @@ #define DISP_OUT_XY "gb_init_sad_disp_out_xy_addr.bin" #define MAX_PATH_LENGTH 100 +#define ERROR_BYTES_THRESHOLD 5 char g_param_path[MAX_PATH_LENGTH]; char g_ref_path[MAX_PATH_LENGTH]; @@ -502,14 +503,15 @@ static void sample_vvi_stop(sample_vvi_pipe_conf_t* pipe_conf) static k_s32 result_check(k_u8 *data, k_u8 *golden, k_u32 length) { k_u32 i; + k_s32 err_cnt=0; for (i = 0; i < length; i++) { if (data[i] != golden[i]) { - printf("compare error! data[%-5d]:%02x, golden[%-5d]:%02x\n", i, data[i], i, golden[i]); - return K_FAILED; + //printf("compare error! data[%-5d]:%02x, golden[%-5d]:%02x\n", i, data[i], i, golden[i]); + err_cnt++; } } - return K_SUCCESS; + return err_cnt; } static k_s32 dpu_result_check(k_dpu_chn_result_u *result, k_u32 chn_num) @@ -526,18 +528,26 @@ static k_s32 dpu_result_check(k_dpu_chn_result_u *result, k_u32 chn_num) // __func__, __LINE__, lcn->depth_out.depth_phys_addr, lcn->depth_out.length, g_depth_out_space.size); virt_result = (k_u8 *)kd_mpi_sys_mmap(lcn->depth_out.depth_phys_addr, lcn->depth_out.length); ret = result_check(virt_result, g_depth_out_space.virt_addr, lcn->depth_out.length); - if (ret) + kd_mpi_sys_munmap(virt_result, lcn->depth_out.length); + if (ret > ERROR_BYTES_THRESHOLD) + { + printf("depth_out error bytes %d\n", ret); return ret; + } printf("%-15s check pass\n", "depth_out"); - kd_mpi_sys_munmap(virt_result, lcn->depth_out.length); + } if (lcn->disp_out.valid) { // printf("%s,%d, disp_phys_addr:%lx, vb.length:%d, array.length:%d\n", // __func__, __LINE__, lcn->disp_out.disp_phys_addr, lcn->disp_out.length, g_disp_out_space.size); virt_result = (k_u8 *)kd_mpi_sys_mmap(lcn->disp_out.disp_phys_addr, lcn->disp_out.length); ret = result_check(virt_result, g_disp_out_space.virt_addr, lcn->disp_out.length); - if (ret) + kd_mpi_sys_munmap(virt_result, lcn->disp_out.length); + if (ret > ERROR_BYTES_THRESHOLD) + { + printf("disp_out error bytes %d\n", ret); return ret; + } printf("%-15s check pass\n", "disp_out"); } if (lcn->qlt_out.valid) { @@ -545,24 +555,36 @@ static k_s32 dpu_result_check(k_dpu_chn_result_u *result, k_u32 chn_num) // __func__, __LINE__, lcn->qlt_out.qlt_phys_addr, lcn->qlt_out.qlt_length, g_qlt_out_space.size); virt_result = (k_u8 *)kd_mpi_sys_mmap(lcn->qlt_out.qlt_phys_addr, lcn->qlt_out.qlt_length); ret = result_check(virt_result, g_qlt_out_space.virt_addr, lcn->qlt_out.qlt_length); - if (ret) + kd_mpi_sys_munmap(virt_result, lcn->qlt_out.qlt_length); + if (ret > 3) + { + printf("qlt_out error bytes %d\n", ret); return ret; + } printf("%-15s check pass\n", "qlt_out"); // printf("%s,%d, sad_disp_phys_addr:%lx, vb.length:%d, array.length:%d\n", // __func__, __LINE__, lcn->qlt_out.sad_disp_phys_addr, lcn->qlt_out.sad_disp_length, g_disp_out_x_space.size); virt_result = (k_u8 *)kd_mpi_sys_mmap(lcn->qlt_out.sad_disp_phys_addr, lcn->qlt_out.sad_disp_length); ret = result_check(virt_result, g_disp_out_x_space.virt_addr, lcn->qlt_out.sad_disp_length); - if (ret) + kd_mpi_sys_munmap(virt_result, lcn->qlt_out.sad_disp_length); + if (ret > ERROR_BYTES_THRESHOLD) + { + printf("sad_disp error bytes %d\n", ret); return ret; + } printf("%-15s check pass\n", "sad_disp"); // printf("%s,%d, init_sad_disp_phys_addr:%lx, vb.length:%d, array.length:%d\n", // __func__, __LINE__, lcn->qlt_out.init_sad_disp_phys_addr, lcn->qlt_out.init_sad_disp_length, g_disp_out_xy_space.size); virt_result = (k_u8 *)kd_mpi_sys_mmap(lcn->qlt_out.init_sad_disp_phys_addr, lcn->qlt_out.init_sad_disp_length); ret = result_check(virt_result, g_disp_out_xy_space.virt_addr, lcn->qlt_out.init_sad_disp_length); - if (ret) + kd_mpi_sys_munmap(virt_result, lcn->qlt_out.init_sad_disp_length); + if (ret > ERROR_BYTES_THRESHOLD) + { + printf("init_sad_disp error bytes %d\n", ret); return ret; + } printf("%-15s check pass\n", "init_sad_disp"); } } else if (chn_num == 1) { @@ -570,8 +592,12 @@ static k_s32 dpu_result_check(k_dpu_chn_result_u *result, k_u32 chn_num) if (ir->ir_out.valid) { virt_result = (k_u8 *)kd_mpi_sys_mmap(ir->ir_out.ir_phys_addr, ir->ir_out.length); ret = result_check(virt_result, g_ir_out_space.virt_addr, ir->ir_out.length); - if (ret) + kd_mpi_sys_munmap(virt_result, ir->ir_out.length); + if (ret > ERROR_BYTES_THRESHOLD) + { + printf("ir_out error bytes %d\n", ret); return ret; + } printf("%-15s check pass\n", "ir"); } } else { @@ -621,19 +647,19 @@ k_s32 sample_dpu_unbound_mode(k_dpu_dev_attr_t *dev_attr, k_dpu_chn_lcn_attr_t * } } - ret = kd_mpi_dpu_send_frame(0, g_lcn_space.phys_addr, 10); + ret = kd_mpi_dpu_send_frame(0, g_lcn_space.phys_addr, 100); if (ret) { printf("kd_mpi_dpu_send_frame lcn failed\n"); return 0; } - ret = kd_mpi_dpu_send_frame(1, g_ir_space.phys_addr, 10); + ret = kd_mpi_dpu_send_frame(1, g_ir_space.phys_addr, 100); if (ret) { printf("kd_mpi_dpu_send_frame ir failed\n"); return 0; } - ret = kd_mpi_dpu_get_frame(0, &lcn_result, 33); + ret = kd_mpi_dpu_get_frame(0, &lcn_result, 100); if (ret) { printf("kd_mpi_dpu_get_frame failed\n"); return 0; @@ -642,7 +668,7 @@ k_s32 sample_dpu_unbound_mode(k_dpu_dev_attr_t *dev_attr, k_dpu_chn_lcn_attr_t * err_times++; - ret = kd_mpi_dpu_get_frame(1, &ir_result, 33); + ret = kd_mpi_dpu_get_frame(1, &ir_result, 100); if (ret) { printf("kd_mpi_dpu_get_frame failed\n"); return 0; @@ -652,6 +678,8 @@ k_s32 sample_dpu_unbound_mode(k_dpu_dev_attr_t *dev_attr, k_dpu_chn_lcn_attr_t * kd_mpi_dpu_release_frame(); + usleep(30000); + printf("\n****************frame num %d end*******************\n", tmp); } printf("all times:%d, error times:%d\n", test_nums*2, err_times); @@ -962,11 +990,11 @@ int main(int argc, char *argv[]) err_input_rels: dpu_golden_data_release(); - printf("%s,%d\n", __func__, __LINE__); + // printf("%s,%d\n", __func__, __LINE__); err_vb_exit: dpu_vb_exit(); - printf("%s,%d\n", __func__, __LINE__); - + // printf("%s,%d\n", __func__, __LINE__); + printf("sample dpu done!"); return 0; } \ No newline at end of file diff --git a/src/big/mpp/userapps/sample/sample_dpu_vicap/Makefile b/src/big/mpp/userapps/sample/sample_dpu_vicap/Makefile index 84b2bb989..890cf5e67 100755 --- a/src/big/mpp/userapps/sample/sample_dpu_vicap/Makefile +++ b/src/big/mpp/userapps/sample/sample_dpu_vicap/Makefile @@ -5,11 +5,17 @@ CURRECT_DIR_NAME=$(shell basename `pwd`) LOCAL_SRC_DIR = $(shell pwd) BIN = $(MPP_SRC_DIR)/userapps/sample/elf/$(CURRECT_DIR_NAME).elf LIBPATH = $(MPP_LIB_PATH) +LIBPATH += -L$(RTSMART_SRC_DIR)/userapps/sdk/rt-thread/lib/risc-v/rv64 LIBS = $(MPP_LIBS) +LIBS += -lrtthread LOCAL_CFLAGS = -I$(LOCAL_SRC_DIR) \ -I$(LOCAL_SRC_DIR)/../sample_vo +DEVICE_CFLAGS = -I$(RTSMART_SRC_DIR)/userapps \ + -I$(RTSMART_SRC_DIR)/userapps/sdk/rt-thread/include \ + -I$(RTSMART_SRC_DIR)/userapps/sdk/rt-thread/components/drivers + SRCS = $(wildcard $(LOCAL_SRC_DIR)/*.c) \ $(LOCAL_SRC_DIR)/../sample_vo/vo_test_case.c \ $(LOCAL_SRC_DIR)/../sample_vo/vo_bind_test.c @@ -21,7 +27,7 @@ all: $(BIN) @echo "${PWD}/Makefile all" $(OBJS): %.o : %.c - @$(CC) $(CC_CFLAGS) $(LOCAL_CFLAGS) $(BSP_CFLGAS) $(RTSMART_CFLAGS) $(MPP_USER_CFLGAS) -c $< -o $@ + @$(CC) -DHAVE_CCONFIG_H $(CC_CFLAGS) $(LOCAL_CFLAGS) $(DEVICE_CFLAGS) $(BSP_CFLGAS) $(RTSMART_CFLAGS) $(MPP_USER_CFLGAS) -c $< -o $@ $(BIN): $(OBJS) $(MPP_SRC_DIR)/userapps/lib/libvicap.a @echo LD $@ diff --git a/src/big/mpp/userapps/sample/sample_dpu_vicap/sample_dpu_vicap.c b/src/big/mpp/userapps/sample/sample_dpu_vicap/sample_dpu_vicap.c index 9791dcd11..0020a713f 100755 --- a/src/big/mpp/userapps/sample/sample_dpu_vicap/sample_dpu_vicap.c +++ b/src/big/mpp/userapps/sample/sample_dpu_vicap/sample_dpu_vicap.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -56,6 +57,10 @@ #define DISPLAY_WITDH 1088 #define DISPLAY_HEIGHT 1920 +#define IR_BUF_SIZE ((DMA_CHN0_WIDTH * DMA_CHN0_WIDTH *3/2 + 0x3ff) & ~0x3ff)//(5 * 1024 * 1024) + +extern k_dpu_dev_attr_t dpu_dev_attr; + typedef struct { k_vicap_dev dev_num; k_bool dev_enable; @@ -112,14 +117,26 @@ typedef struct { static vicap_device_obj device_obj[VICAP_DEV_ID_MAX]; static k_u32 dump_count = 0; static pthread_t output_tid = 0; +static pthread_t adc_tid = 0; static k_bool exiting = K_FALSE; +static k_bool dump_exited = K_FALSE; +static k_bool adc_exited = K_FALSE; static k_video_frame_info rgb_buf[VICAP_OUTPUT_BUF_NUM]; +// static k_video_frame_info ir_buf[VICAP_OUTPUT_BUF_NUM]; static k_u32 rgb_wp=0; static k_u32 rgb_rp=0; static k_u32 rgb_total_cnt=0; static char OUT_PATH[50] = {"\0"}; static int rgb_dev; static int rgb_chn; +static k_vb_blk_handle ir_handle; +static k_u64 ir_phys_addr; +static k_u8 *ir_virt_addr; +static k_bool gen_calibration = K_FALSE; +static k_bool adc_en = K_FALSE; +#if ENABLE_CDC +static int fd_usb = -1; +#endif static k_u32 sample_vicap_vo_init(void) { @@ -311,6 +328,11 @@ static k_s32 sample_vicap_vb_init(vicap_device_obj *dev_obj) config.comm_pool[k+2].blk_size = 5 * 1024 * 1024; config.comm_pool[k+2].mode = VB_REMAP_MODE_NOCACHE; + //ir + config.comm_pool[k+3].blk_cnt = (3); + config.comm_pool[k+3].blk_size = IR_BUF_SIZE;//5 * 1024 * 1024; + config.comm_pool[k+3].mode = VB_REMAP_MODE_NOCACHE; + ret = kd_mpi_vb_set_config(&config); if (ret) { printf("vb_set_config failed ret:%d\n", ret); @@ -332,6 +354,44 @@ static k_s32 sample_vicap_vb_init(vicap_device_obj *dev_obj) return ret; } + k_vb_blk_handle handle; + k_s32 pool_id = 0; + k_u64 phys_addr = 0; + + + handle = kd_mpi_vb_get_block(VB_INVALID_POOLID, config.comm_pool[k+3].blk_size, NULL); + if (handle == VB_INVALID_HANDLE) + { + printf("%s get vb block error\n", __func__); + return -1; + } + ir_handle = handle; + + pool_id = kd_mpi_vb_handle_to_pool_id(handle); + if (pool_id == VB_INVALID_POOLID) + { + printf("%s get pool id error\n", __func__); + return -1; + } + + phys_addr = kd_mpi_vb_handle_to_phyaddr(handle); + if (phys_addr == 0) + { + printf("%s get phys addr error\n", __func__); + return -1; + } + + ir_phys_addr = phys_addr; + + printf("%s>phys_addr 0x%lx, blk_size %ld\n", __func__, phys_addr, config.comm_pool[k+3].blk_size); + ir_virt_addr = (k_u8 *)kd_mpi_sys_mmap_cached(phys_addr, config.comm_pool[k+3].blk_size); + if (ir_virt_addr == NULL) + { + printf("%s mmap error\n", __func__); + return -1; + } + printf("%s>ir_virt_addr_Y %p\n", __func__, ir_virt_addr); + return 0; } @@ -388,7 +448,14 @@ static void dpu_dump() k_video_frame_info dump_info; k_video_frame_info dma_get_info; k_dpu_chn_result_u lcn_result; + k_dpu_chn_result_u ir_result; k_s32 ret; + void *dpu_virt_addr = NULL; + k_bool get_ir = K_FALSE; +#if ENABLE_CDC + k_u32 remain_size = 0; + void* wp = NULL; +#endif for (int dev_num = 0; dev_num < VICAP_DEV_ID_MAX; dev_num++) { if (!device_obj[dev_num].dev_enable) @@ -398,8 +465,11 @@ static void dpu_dump() if (!device_obj[dev_num].chn_enable[chn_num]) continue; - //printf("sample_vicap, dev(%d) chn(%d) dump frame.\n", dev_num, chn_num); + if(!gen_calibration) + if(dpu_dev_attr.dev_param.spp.flag_align) + get_ir = K_TRUE; + //printf("sample_vicap, dev(%d) chn(%d) dump frame.\n", dev_num, chn_num); if(device_obj[dev_num].out_format[chn_num] == PIXEL_FORMAT_YUV_SEMIPLANAR_420) { memset(&dump_info, 0 , sizeof(k_video_frame_info)); @@ -407,67 +477,237 @@ static void dpu_dump() if (ret) { printf("sample_vicap, dev(%d) chn(%d) dump frame failed.\n", dev_num, chn_num); } - + printf("dump_info pts: %ld\n", dump_info.v_frame.pts); //printf("addr: [%lx, %lx, %lx]\n", dump_info.v_frame.phys_addr[0], dump_info.v_frame.phys_addr[1], dump_info.v_frame.phys_addr[2]); - ret = kd_mpi_dma_send_frame(DMA_CHN0, &dump_info, -1); - if (ret != K_SUCCESS) + if(gen_calibration) { - printf("send frame error\r\n"); +#if 1 + /* save vicap ir file */ + // void *dpu_virt_addr = NULL; + k_char vicap_ir_filename[256]; + + memset(vicap_ir_filename, 0 , sizeof(vicap_ir_filename)); + sprintf(vicap_ir_filename, "%svicap_ir_%04d.yuv", OUT_PATH, dump_count); + + dpu_virt_addr = kd_mpi_sys_mmap(dump_info.v_frame.phys_addr[0], dump_info.v_frame.width* dump_info.v_frame.height*3/2); + if (dpu_virt_addr) { + FILE *file = fopen(vicap_ir_filename, "wb+"); + if (file) { + fwrite(dpu_virt_addr, 1, dump_info.v_frame.width* dump_info.v_frame.height*3/2, file); + fclose(file); + printf("save %s success\n", vicap_ir_filename); + } else { + printf("can't create file\n"); + } + } else { + printf("save ir out failed\n"); + } + + kd_mpi_sys_munmap(dpu_virt_addr, dump_info.v_frame.width* dump_info.v_frame.height*3/2); +#endif + + ret = kd_mpi_dma_send_frame(DMA_CHN0, &dump_info, -1); + if (ret != K_SUCCESS) + { + printf("send frame error\r\n"); + } + + ret = kd_mpi_dma_get_frame(DMA_CHN0, &dma_get_info, -1); + if (ret != K_SUCCESS) + { + printf("get frame error\r\n"); + } + + + ret = kd_mpi_dpu_send_frame(0, ir_phys_addr, 200); + if (ret) { + printf("kd_mpi_dpu_send_frame ir failed: %d\n", ret); + } + + ret = kd_mpi_dpu_send_frame(1, dma_get_info.v_frame.phys_addr[0], 200); + if (ret) { + printf("kd_mpi_dpu_send_frame ir failed: %d\n", ret); + } + + ret = kd_mpi_dpu_get_frame(0, &lcn_result, 200); + if (ret) { + printf("kd_mpi_dpu_get_frame failed: %d\n", ret); + } + + ret = kd_mpi_dpu_get_frame(1, &ir_result, 200); + if (ret) { + printf("kd_mpi_dpu_get_frame failed: %d\n", ret); + } +#if 0 + /* save vicap ir file */ + // void *dpu_virt_addr = NULL; + k_char ir_filename[256]; + + memset(ir_filename, 0 , sizeof(ir_filename)); + sprintf(ir_filename, "%sir_%04d.ir", OUT_PATH, dump_count); + + dpu_virt_addr = kd_mpi_sys_mmap(ir_result.ir_result.ir_out.ir_phys_addr, ir_result.ir_result.ir_out.length); + if (dpu_virt_addr) { + FILE *file = fopen(ir_filename, "wb+"); + if (file) { + fwrite(dpu_virt_addr, 1, ir_result.ir_result.ir_out.length, file); + fclose(file); + printf("save %s success, pts %ld\n", ir_filename, dump_info.v_frame.pts); + } else { + printf("can't create file\n"); + } + } else { + printf("save irout failed\n"); + } + + kd_mpi_sys_munmap(dpu_virt_addr, dump_info.v_frame.width* dump_info.v_frame.height*3/2); +#endif + kd_mpi_dma_release_frame(DMA_CHN0, &dma_get_info); + //printf("depth addr:%lx\n", lcn_result.lcn_result.depth_out.depth_phys_addr); + + kd_mpi_dpu_release_frame(); } - ret = kd_mpi_dma_get_frame(DMA_CHN0, &dma_get_info, -1); - if (ret != K_SUCCESS) + else { - printf("get frame error\r\n"); - } - //printf("dma addr:%lx\n", dma_get_info.v_frame.phys_addr[0]); +#if 0 + /* save vicap depth file */ + // void *dpu_virt_addr = NULL; + k_char vicap_depth_filename[256]; + + memset(vicap_depth_filename, 0 , sizeof(vicap_depth_filename)); + sprintf(vicap_depth_filename, "%svicap_depth_%04d.yuv", OUT_PATH, dump_count); + + dpu_virt_addr = kd_mpi_sys_mmap(dump_info.v_frame.phys_addr[0], dump_info.v_frame.width* dump_info.v_frame.height*3/2); + if (dpu_virt_addr) { + FILE *file = fopen(vicap_depth_filename, "wb+"); + if (file) { + fwrite(dpu_virt_addr, 1, dump_info.v_frame.width* dump_info.v_frame.height*3/2, file); + fclose(file); + printf("save %s success\n", vicap_depth_filename); + } else { + printf("can't create file\n"); + } + } else { + printf("save ir out failed\n"); + } - ret = kd_mpi_dpu_send_frame(0, dma_get_info.v_frame.phys_addr[0], 200); - if (ret) { - printf("kd_mpi_dpu_send_frame lcn failed\n"); - } + kd_mpi_sys_munmap(dpu_virt_addr, dump_info.v_frame.width* dump_info.v_frame.height*3/2); +#endif - ret = kd_mpi_dpu_get_frame(0, &lcn_result, 200); - if (ret) { - printf("kd_mpi_dpu_get_frame failed\n"); - } + printf("lcn dma\n"); + ret = kd_mpi_dma_send_frame(DMA_CHN0, &dump_info, -1); + if (ret != K_SUCCESS) + { + printf("send frame error\r\n"); + } - /* save file */ - void *dpu_virt_addr = NULL; - k_char dpu_filename[256]; + ret = kd_mpi_dma_get_frame(DMA_CHN0, &dma_get_info, -1); + if (ret != K_SUCCESS) + { + printf("get frame error\r\n"); + } + //printf("dma addr:%lx\n", dma_get_info.v_frame.phys_addr[0]); - memset(dpu_filename, 0 , sizeof(dpu_filename)); - snprintf(dpu_filename, sizeof(dpu_filename), "%sdepth_%04d.bin", OUT_PATH, dump_count); + printf("lcn dpu\n"); + ret = kd_mpi_dpu_send_frame(0, dma_get_info.v_frame.phys_addr[0], 200); + if (ret) { + printf("kd_mpi_dpu_send_frame lcn failed: %d\n", ret); + } - dpu_virt_addr = kd_mpi_sys_mmap(lcn_result.lcn_result.depth_out.depth_phys_addr, lcn_result.lcn_result.depth_out.length); - if (dpu_virt_addr) { - FILE *file = fopen(dpu_filename, "wb+"); - if (file) { - fwrite(dpu_virt_addr, 1, lcn_result.lcn_result.depth_out.length, file); - fclose(file); - printf("save %s success, pts %ld\n", dpu_filename, dump_info.v_frame.pts); + if(get_ir) + { + printf("ir dpu\n"); + + ret = kd_mpi_dpu_send_frame(1, ir_phys_addr, 200); + + if (ret) { + printf("kd_mpi_dpu_send_frame ir failed: %d\n", ret); + } + } + + ret = kd_mpi_dpu_get_frame(0, &lcn_result, 200); + if (ret) { + printf("kd_mpi_dpu_get_frame failed: %d\n", ret); + } + +#if 0//ENABLE_CDC + remain_size = lcn_result.lcn_result.depth_out.length; + dpu_virt_addr = kd_mpi_sys_mmap(lcn_result.lcn_result.depth_out.depth_phys_addr, lcn_result.lcn_result.depth_out.length); + wp = dpu_virt_addr; + while(remain_size) + { + if(remain_size >= 1024) + { + write(fd_usb, wp, 1024); + wp += 1024; + remain_size -= 1024; + } + else + { + write(fd_usb, wp, remain_size); + wp = NULL; + remain_size = 0; + } + } + kd_mpi_sys_munmap(dpu_virt_addr, lcn_result.lcn_result.depth_out.length); +#else + /* save file */ + // void *dpu_virt_addr = NULL; + k_char dpu_filename[256]; + + memset(dpu_filename, 0 , sizeof(dpu_filename)); + snprintf(dpu_filename, sizeof(dpu_filename), "%sdepth_%04d.bin", OUT_PATH, dump_count); + + dpu_virt_addr = kd_mpi_sys_mmap(lcn_result.lcn_result.depth_out.depth_phys_addr, lcn_result.lcn_result.depth_out.length); + if (dpu_virt_addr) { + FILE *file = fopen(dpu_filename, "wb+"); + if (file) { + fwrite(dpu_virt_addr, 1, lcn_result.lcn_result.depth_out.length, file); + fclose(file); + printf("save %s success, pts %ld\n", dpu_filename, dump_info.v_frame.pts); + } else { + printf("can't create file\n"); + } } else { - printf("can't create file\n"); + printf("save depthout failed\n"); } - } else { - printf("save depthout failed\n"); - } - kd_mpi_dma_release_frame(DMA_CHN0, &dma_get_info); - //printf("depth addr:%lx\n", lcn_result.lcn_result.depth_out.depth_phys_addr); + kd_mpi_sys_munmap(dpu_virt_addr, lcn_result.lcn_result.depth_out.length); +#endif - kd_mpi_dpu_release_frame(); + kd_mpi_dma_release_frame(DMA_CHN0, &dma_get_info); + //printf("depth addr:%lx\n", lcn_result.lcn_result.depth_out.depth_phys_addr); - kd_mpi_sys_munmap(dpu_virt_addr, lcn_result.lcn_result.depth_out.length); + kd_mpi_dpu_release_frame(); + + if(get_ir) + { + ret = kd_mpi_dpu_get_frame(1, &ir_result, 200); + if (ret) { + printf("kd_mpi_dpu_get_frame ir failed: %d\n", ret); + } + + kd_mpi_dpu_release_frame(); + + + get_ir = K_FALSE; + } + + // kd_mpi_dpu_release_frame(); + } } + if(device_obj[dev_num].out_format[chn_num] == PIXEL_FORMAT_RGB_888 || device_obj[dev_num].out_format[chn_num] == PIXEL_FORMAT_BGR_888_PLANAR) { k_u32 data_size = 0; void *virt_addr = NULL; +#if !ENABLE_CDC k_char filename[256]; +#endif memset(&dump_info, 0 , sizeof(k_video_frame_info)); ret = kd_mpi_vicap_dump_frame(dev_num, chn_num, VICAP_DUMP_RGB, &dump_info, 1000); @@ -477,6 +717,31 @@ static void dpu_dump() //printf("addr: [%lx, %lx, %lx]\n", dump_info.v_frame.phys_addr[0], dump_info.v_frame.phys_addr[1], dump_info.v_frame.phys_addr[2]); +#if 0 + /* save vicap depth file */ + // void *dpu_virt_addr = NULL; + k_char vicap_rgb_filename[256]; + + memset(vicap_rgb_filename, 0 , sizeof(vicap_rgb_filename)); + sprintf(vicap_rgb_filename, "%svicap_rgb_%04d.rgb", OUT_PATH, dump_count); + + dpu_virt_addr = kd_mpi_sys_mmap(dump_info.v_frame.phys_addr[0], dump_info.v_frame.width* dump_info.v_frame.height*3); + if (dpu_virt_addr) { + FILE *file = fopen(vicap_rgb_filename, "wb+"); + if (file) { + fwrite(dpu_virt_addr, 1, dump_info.v_frame.width* dump_info.v_frame.height*3, file); + fclose(file); + printf("save %s success\n", vicap_rgb_filename); + } else { + printf("can't create file\n"); + } + } else { + printf("save ir out failed\n"); + } + kd_mpi_sys_munmap(dpu_virt_addr, dump_info.v_frame.width* dump_info.v_frame.height*3); + +#endif + if (dump_info.v_frame.pixel_format == PIXEL_FORMAT_YUV_SEMIPLANAR_420) { data_size = dump_info.v_frame.width * dump_info.v_frame.height * 3 /2; } else if (dump_info.v_frame.pixel_format == PIXEL_FORMAT_RGB_888) { @@ -500,6 +765,30 @@ static void dpu_dump() printf("get frame error\r\n"); } +#if ENABLE_CDC + remain_size = data_size; + printf("data size %d\n", data_size); + virt_addr = kd_mpi_sys_mmap(dma_get_info.v_frame.phys_addr[0], data_size); + wp = virt_addr; + int block = 1024; + while(remain_size) + { + if(remain_size >= block) + { + write(fd_usb, wp, block); + wp += block; + remain_size -= block; + } + else + { + write(fd_usb, wp, remain_size); + wp = NULL; + remain_size = 0; + } + usleep(5000); + } + kd_mpi_sys_munmap(virt_addr, data_size); +#else virt_addr = kd_mpi_sys_mmap(dma_get_info.v_frame.phys_addr[0], data_size); if (virt_addr) { memset(filename, 0 , sizeof(filename)); @@ -519,7 +808,7 @@ static void dpu_dump() } kd_mpi_sys_munmap(virt_addr, data_size); - +#endif kd_mpi_dma_release_frame(DMA_CHN1, &dma_get_info); } @@ -540,6 +829,8 @@ static void dpu_continue_dump() k_video_frame_info dump_info; k_video_frame_info dma_get_info; k_dpu_chn_result_u lcn_result; + k_dpu_chn_result_u ir_result; + k_bool get_ir = K_FALSE; k_s32 ret; for (int dev_num = 0; dev_num < VICAP_DEV_ID_MAX; dev_num++) { @@ -550,7 +841,8 @@ static void dpu_continue_dump() if (!device_obj[dev_num].chn_enable[chn_num]) continue; - //printf("sample_vicap, dev(%d) chn(%d) dump frame.\n", dev_num, chn_num); + if(dpu_dev_attr.dev_param.spp.flag_align) + get_ir = K_TRUE; if(device_obj[dev_num].out_format[chn_num] == PIXEL_FORMAT_RGB_888 || device_obj[dev_num].out_format[chn_num] == PIXEL_FORMAT_BGR_888_PLANAR) @@ -615,11 +907,27 @@ static void dpu_continue_dump() printf("kd_mpi_dpu_send_frame lcn failed\n"); } + if(get_ir) + { + ret = kd_mpi_dpu_send_frame(1, ir_phys_addr, 200); + if (ret) { + printf("kd_mpi_dpu_send_frame lcn failed\n"); + } + } + ret = kd_mpi_dpu_get_frame(0, &lcn_result, 200); if (ret) { printf("kd_mpi_dpu_get_frame failed\n"); } + if(get_ir) + { + ret = kd_mpi_dpu_get_frame(1, &ir_result, 200); + if (ret) { + printf("kd_mpi_dpu_get_frame failed\n"); + } + } + /* save depth file */ void *dpu_virt_addr = NULL; k_char dpu_filename[256]; @@ -739,7 +1047,55 @@ static void *dump_thread(void *arg) rgb_rp++; rgb_rp %= VICAP_OUTPUT_BUF_NUM; } - exiting = K_FALSE; + dump_exited = K_TRUE; + return arg; +} + +static void *adc_thread(void *arg) +{ + printf("%s\n", __FUNCTION__); + float temp = -300.0;//初始变量建议定义到正常范围之外,如果没有正常赋值,不会影响计算。 + float old_temp = -300.0; + // char input = 'a'; + while (!exiting) + { + if (!sample_adc(&temp)) + { + //printf("%f\n", temp - old_temp); + if (temp - old_temp > 5 || temp - old_temp < -5) + { + sample_dv_dpu_update_temp(temp); + old_temp = temp; + } + } + + fd_set rfds; + struct timeval tv; + int retval; + + FD_ZERO(&rfds); + FD_SET(0, &rfds); // 监视标准输入流 + + tv.tv_sec = 5; // 设置等待时间为5秒 + tv.tv_usec = 0; + + retval = select(1, &rfds, NULL, NULL, &tv); + if (retval == -1) { + perror("select()"); + } + else if (retval > 0) { + FD_ISSET(0, &rfds); + } + else { + printf("Timeout reached\n"); + } + + //k_u32 display_ms = 1000;//get temperature per 1s + //usleep(1000 * display_ms); + } + adc_exited = K_TRUE; + printf("adc exit\n"); + return arg; } @@ -769,9 +1125,18 @@ static void usage(void) exit(1); } +static void _set_mod_log(k_mod_id mod_id,k_s32 level) +{ + k_log_level_conf level_conf; + level_conf.level = level; + level_conf.mod_id = mod_id; + kd_mpi_log_set_level_conf(&level_conf); +} + int main(int argc, char *argv[]) { // _set_mod_log(K_ID_VI, 6); + _set_mod_log(K_ID_DPU, 7); k_s32 ret = 0; k_u32 work_mode = VICAP_WORK_ONLINE_MODE; @@ -798,6 +1163,9 @@ int main(int argc, char *argv[]) usage(); } +#if ENABLE_CDC + fd_usb = open("/dev/ttyUSB1", O_RDWR); +#endif for (int i = 1; i < argc; i += 2) { if (strcmp(argv[i], "-help") == 0) @@ -830,6 +1198,18 @@ int main(int argc, char *argv[]) return -1; } } + else if (strcmp(argv[i], "-adc") == 0) + { + if(argv[i+1]){ + adc_en = K_TRUE; + } + } + else if (strcmp(argv[i], "-cal") == 0) + { + if(argv[i+1]){ + gen_calibration = K_TRUE; + } + } else if (strcmp(argv[i], "-dev") == 0) { dev_parse: @@ -1406,6 +1786,7 @@ int main(int argc, char *argv[]) printf("sample_vicap, vo layer init failed.\n"); goto vb_exit; } + printf("sample_vicap, vo layer init ok.\n"); for (int dev_num = 0; dev_num < VICAP_DEV_ID_MAX; dev_num++) { if (!device_obj[dev_num].dev_enable) @@ -1435,6 +1816,11 @@ int main(int argc, char *argv[]) memset(&ae_roi, 0, sizeof(k_isp_ae_roi)); k_char select = 0; + + if(adc_en){ + pthread_create(&adc_tid, NULL, adc_thread, NULL); + } + while(K_TRUE) { if(select != '\n') @@ -1505,10 +1891,10 @@ int main(int argc, char *argv[]) pthread_create(&output_tid, NULL, dump_thread, NULL); break; case 'q': - if(output_tid) + if(output_tid || adc_tid) { exiting = K_TRUE; - while(exiting) + while((output_tid && !dump_exited) || (adc_tid && !adc_exited)) { usleep(30000); } @@ -1517,6 +1903,7 @@ int main(int argc, char *argv[]) default: break; } + sleep(1); } @@ -1568,11 +1955,19 @@ int main(int argc, char *argv[]) } } + if(adc_tid) + { + pthread_cancel(adc_tid); + pthread_join(adc_tid, NULL); + } + if(output_tid) { pthread_cancel(output_tid); pthread_join(output_tid, NULL); } + exiting = K_FALSE; + printf("%d: exiting %d\n", __LINE__, exiting); ret = sample_dv_dma_delete(); if (ret) { @@ -1593,6 +1988,12 @@ int main(int argc, char *argv[]) k_u32 display_ms = 1000 / 33; usleep(1000 * display_ms); + kd_mpi_sys_munmap(ir_virt_addr, IR_BUF_SIZE); + kd_mpi_vb_release_block(ir_handle); +#if ENABLE_CDC + close(fd_usb); +#endif + vb_exit: return ret; diff --git a/src/big/mpp/userapps/sample/sample_dpu_vicap/sample_dpu_vicap.h b/src/big/mpp/userapps/sample/sample_dpu_vicap/sample_dpu_vicap.h index 9cbaf047a..e8885b77f 100755 --- a/src/big/mpp/userapps/sample/sample_dpu_vicap/sample_dpu_vicap.h +++ b/src/big/mpp/userapps/sample/sample_dpu_vicap/sample_dpu_vicap.h @@ -35,6 +35,11 @@ #include #include +// #include +// #include +// #include +// #include + #include "k_module.h" #include "k_type.h" #include "k_vb_comm.h" @@ -48,6 +53,14 @@ #include "mpi_dpu_api.h" #include "mpi_sys_api.h" +#define ENABLE_ADC (0) +#define ENABLE_CDC (0) + +#include +#include +#include +#include + #define SAMPLE_VDD_CHN_NUM 1 #define SAMPLE_VDD_CHN 0 #define VDD_INPUT_BUF_CNT 6 @@ -78,6 +91,8 @@ static inline void VDD_CHECK_RET(k_s32 ret, const char *func, const int line) } /* vi */ +int sample_adc(float* temp); +int sample_dv_dpu_update_temp(float temperature_obj); int sample_dv_dma_init(); int sample_dv_dma_delete(); int sample_dv_dpu_init(); diff --git a/src/big/mpp/userapps/sample/sample_dpu_vicap/sample_vdd_dpu.c b/src/big/mpp/userapps/sample/sample_dpu_vicap/sample_vdd_dpu.c index f3d9890a6..824f5310f 100755 --- a/src/big/mpp/userapps/sample/sample_dpu_vicap/sample_vdd_dpu.c +++ b/src/big/mpp/userapps/sample/sample_dpu_vicap/sample_vdd_dpu.c @@ -25,6 +25,18 @@ #include "sample_dpu_vicap.h" +#define REF_VOL (1.8) +#define RESOLUTION (4096) + +#define ADC_CHN_ENABLE (0) +#define ADC_CHN_DISABLE (1) + +#define REF_TEMPERATURE (36.289)//临时使用固定参数。 +#define TEMPERATURE_CX (640)//临时使用固定参数,实际应该从温度标定参数文件中获得 +#define TEMPERATURE_CY (360)//临时使用固定参数,实际应该从温度标定参数文件中获得 +#define TEMPERATURE_KX (0.00015)//临时使用固定参数,实际应该从温度标定参数文件中获得 +#define TEMPERATURE_KY (0.00015)//临时使用固定参数,实际应该从温度标定参数文件中获得 + /* dpu file path define */ #define PARAM_PATH "/sharefs/H1280W720_conf.bin" #define REF_PATH "/sharefs/H1280W720_ref.bin" @@ -37,6 +49,122 @@ k_dpu_chn_ir_attr_t ir_attr; /* dpu global variable */ k_dpu_user_space_t g_temp_space; +int sample_adc(float* temp) +{ + //adc + int ret = 0; + unsigned int channel = 2; + unsigned int reg_value = 0; + float R_series = 10.2; + float R_ntc = 1.0; + float R_t0 = 10.0; + float Bn = 3380; + + float temperature = 0.0f; + float vol = 0.0; + + rt_device_t adc_dev; + printf("adc_driver test\n"); + + adc_dev = rt_device_find("adc"); + if (adc_dev == RT_NULL) + { + printf("device find error\n"); + return -1; + } + printf("find device success\n"); + + ret = rt_device_open(adc_dev, RT_DEVICE_OFLAG_RDWR); + if (ret != RT_EOK) + { + printf("adc device open err\n"); + return -1; + } + + /////////// + //get temperature + //1read + uint32_t *p; + p = (uint32_t *)(intptr_t)channel; + ret = rt_device_control(adc_dev, ADC_CHN_ENABLE, (void *)p); + if (ret != RT_EOK) + { + printf("adc device control err\n"); + return -1; + } + printf("adc device control success. "); + ret = rt_device_read(adc_dev, channel, (void *)®_value, sizeof(unsigned int)); + + //2get target + vol = REF_VOL * reg_value / RESOLUTION; + R_ntc = vol * R_series / (REF_VOL - vol); + temperature = Bn / (log(R_ntc / R_t0) + Bn / 298.15) - 273.15; + printf("channel %d reg_value:0x%04x, voltage:%f, R_ntc:%f, temperature:%f *c\n", channel, reg_value, vol, R_ntc, temperature); + + *temp = temperature; + return 0; +} + +int sample_dv_dpu_update_temp(float temperature_obj) +{ + if (temperature_obj < -50 || temperature_obj>100) { + printf("obj temperature is invalid!\n"); + return -1; + } + + printf("start temperature rectify:ref_temp: %f, obj_ref:%f \n", REF_TEMPERATURE, temperature_obj); + float diff_temp = temperature_obj - REF_TEMPERATURE; + //if (diff_temp < 3 && diff_temp > -3) + //{ + // printf("temperature is near refence temperature!there is no need to rectify \n"); + // return 0; + //} + + k_u16 image_width = dpu_dev_attr.dev_param.spp.width_speckle; + k_u16 image_height = dpu_dev_attr.dev_param.spp.height_speckle; + + float* row_offset_ = dpu_dev_attr.dev_param.lpp.row_offset; + float* col_offset_ = dpu_dev_attr.dev_param.lpp.col_offset; + + // 温度补偿量计算 + for (k_u16 r = 0; r < image_height; r++) { + // 行偏差温度补偿 + float dalte_v_ = 0.f; + float temp_vertical = (r - TEMPERATURE_CY) * diff_temp * TEMPERATURE_KY; + float y_temp = temp_vertical + r; + if (y_temp > 0.5 && y_temp < image_height - 0.5) + dalte_v_ = temp_vertical; + row_offset_[r] = dalte_v_; + } + + for (k_u16 c = 0; c < image_width; c++) { + // 列偏差温度补偿 + float dalte_u_ = 0.f; + float temp_horizonal = (c - TEMPERATURE_CX) * diff_temp * TEMPERATURE_KX; + float x_temp = temp_horizonal + c; + if (x_temp > 0.5 && x_temp < image_width-0.5) + dalte_u_ = temp_horizonal; + col_offset_[c] = dalte_u_; + } + + kd_mpi_sys_mmz_flush_cache(dpu_dev_attr.dev_param.lpp.row_offset_phys, dpu_dev_attr.dev_param.lpp.row_offset, image_height * sizeof(float)); + kd_mpi_sys_mmz_flush_cache(dpu_dev_attr.dev_param.lpp.col_offset_phys, dpu_dev_attr.dev_param.lpp.col_offset, image_width * sizeof(float)); + + + k_s32 ret = kd_mpi_dpu_set_dev_attr(&dpu_dev_attr); + if (ret) { + printf("kd_mpi_dpu_set_dev_attr failed\n"); + printf("rectify failed\n"); + return -1; + //goto err_dpu_delet; + } + printf("kd_mpi_dpu_set_dev_attr success\n"); + printf("rectify success\n"); + + return 0; + +} + int sample_dv_dpu_init() { k_s32 ret; @@ -128,6 +256,14 @@ int sample_dv_dpu_init() } printf("kd_mpi_dpu_start_chn lcn success\n"); + /* start channel 1 */ + ret = kd_mpi_dpu_start_chn(1); + if (ret) { + printf("kd_mpi_dpu_start_chn 1 failed\n"); + goto err_dpu_dev; + } + printf("kd_mpi_dpu_start_chn ir success\n"); + return K_SUCCESS; /************************************************************ @@ -138,6 +274,11 @@ int sample_dv_dpu_init() printf("kd_mpi_dpu_stop_chn lcn failed\n"); return 0; } + ret = kd_mpi_dpu_stop_chn(1); + if (ret) { + printf("kd_mpi_dpu_stop_chn ir failed\n"); + return 0; + } printf("kd_mpi_dpu_stop_chn success\n"); err_dpu_dev: @@ -164,6 +305,11 @@ int sample_dv_dpu_delete() printf("kd_mpi_dpu_stop_chn lcn failed\n"); return 0; } + ret = kd_mpi_dpu_stop_chn(1); + if (ret) { + printf("kd_mpi_dpu_stop_chn ir failed\n"); + return 0; + } printf("kd_mpi_dpu_stop_chn success\n"); ret = kd_mpi_dpu_stop_dev(); diff --git a/src/big/mpp/userapps/sample/sample_vdec/sample_vdec.c b/src/big/mpp/userapps/sample/sample_vdec/sample_vdec.c index 4bd524af4..582dc3f2a 100644 --- a/src/big/mpp/userapps/sample/sample_vdec/sample_vdec.c +++ b/src/big/mpp/userapps/sample/sample_vdec/sample_vdec.c @@ -85,6 +85,7 @@ typedef struct k_u32 act_height; k_u32 input_pool_id; k_u32 output_pool_id; + k_u32 dec_stream_frames; } sample_vdec_conf_t; static sample_vdec_conf_t g_vdec_conf[VDEC_MAX_CHN_NUMS]; @@ -324,6 +325,7 @@ static void *output_thread(void *arg) if (status.end_of_stream) { vdec_debug("%s>ch %d, receive eos\n", __func__, vdec_conf->ch_id); + vdec_conf->dec_stream_frames = status.dec_stream_frames; break; } else if (status.width != vdec_conf->act_width && first == 0) @@ -509,6 +511,11 @@ int main(int argc, char *argv[]) while (1) { + if(g_vdec_conf[ch].dec_stream_frames == 1 && type == K_PT_JPEG) + { + sleep(3); + vdec_debug("one jpeg picture\n"); + } if (g_vdec_conf[ch].done == K_TRUE) { sample_vdec_unbind_vo(BIND_VO_LAYER); diff --git a/src/big/mpp/userapps/src/Makefile b/src/big/mpp/userapps/src/Makefile index e4c263e86..12beb885f 100644 --- a/src/big/mpp/userapps/src/Makefile +++ b/src/big/mpp/userapps/src/Makefile @@ -3,8 +3,10 @@ all: @cd connector; make || exit 1 @cd fft; make || exit 1 @cd cipher; make || exit 1 + @cd pm; make || exit 1 clean: @cd sensor; make clean @cd fft; make clean @cd cipher; make clean @cd connector; make clean + @cd pm; make clean \ No newline at end of file diff --git a/src/big/mpp/userapps/src/connector/mpi_connector.c b/src/big/mpp/userapps/src/connector/mpi_connector.c index 70e86e50d..5d4686393 100755 --- a/src/big/mpp/userapps/src/connector/mpi_connector.c +++ b/src/big/mpp/userapps/src/connector/mpi_connector.c @@ -8,6 +8,7 @@ #include "k_connector_comm.h" #include "k_connector_ioctl.h" #include "k_vo_comm.h" +#include "mpi_connector_api.h" #define pr_debug(...) //printf(__VA_ARGS__) #define pr_info(...) //printf(__VA_ARGS__) @@ -29,6 +30,19 @@ const k_connector_info connector_info_list[] = { {74250, 445500, 1160, 1080, 20, 20, 40, 2134, 1920, 5, 8, 206}, HX8377_V2_MIPI_4LAN_1080X1920_30FPS, }, + { + "lt9611", + 0, + 0, + BACKGROUND_BLACK_COLOR, + 10, + K_DSI_4LAN, + K_BURST_MODE, + K_VO_LP_MODE, + {0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + LT9611_MIPI_ADAPT_RESOLUTION, + }, { "lt9611", 0, @@ -81,6 +95,53 @@ k_s32 kd_mpi_get_connector_info(k_connector_type connector_type, k_connector_inf } +k_s32 kd_mpi_connector_adapt_resolution(k_connector_type type, k_connector_negotiated_data *negotiated_data) +{ + k_u32 ret = 0; + k_s32 connector_fd; + k_connector_type connector_type; + k_connector_info connector_info; + + // step 1 + // read HDMI monitor EDID and negotiate the resolution + memset(&connector_info, 0, sizeof(k_connector_info)); + connector_type = type; + ret = kd_mpi_get_connector_info(connector_type, &connector_info); + if (ret) { + printf("%s get connector info failed for connector_type %d\n", __func__, connector_type); + return ret; + } + + connector_fd = kd_mpi_connector_open(connector_info.connector_name); + if (connector_fd < 0) { + printf("%s connector open %s failed \n", __func__, connector_info.connector_name); + return K_ERR_VO_NOTREADY; + } + kd_mpi_connector_get_negotiated_data(connector_fd, negotiated_data); + kd_mpi_connector_close(connector_fd); + + // step 2 + // according to the negotiated resolution and then set the prefered resolution + memset(&connector_info, 0, sizeof(k_connector_info)); + connector_type = negotiated_data->negotiated_types[0]; + ret = kd_mpi_get_connector_info(connector_type, &connector_info); + if (ret) { + printf("%s get connector info failed for connector_type %d\n", __func__, connector_type); + return ret; + } + + connector_fd = kd_mpi_connector_open(connector_info.connector_name); + if (connector_fd < 0) { + printf("%s connector open %s failed \n", __func__, connector_info.connector_name); + return K_ERR_VO_NOTREADY; + } + kd_mpi_connector_power_set(connector_fd, 1); + kd_mpi_connector_init(connector_fd, connector_info); + + return 0; +} + + k_s32 kd_mpi_connector_open(const char *connector_name) { k_s32 fd = 0; @@ -151,3 +212,17 @@ k_s32 kd_mpi_connector_init(k_s32 fd, k_connector_info info) return ret; } + +k_s32 kd_mpi_connector_get_negotiated_data(k_s32 fd, k_connector_negotiated_data *negotiated_data) +{ + k_s32 ret; + + ret = ioctl(fd, KD_IOC_CONNECTOR_G_NEG_DATA, negotiated_data); + if (ret == -1) { + pr_err("%s, error(%d)\n", __func__, ret); + return K_ERR_VO_NOT_SUPPORT; + } + + return ret; +} + diff --git a/src/big/mpp/userapps/src/pm/Makefile b/src/big/mpp/userapps/src/pm/Makefile new file mode 100644 index 000000000..b7c42c454 --- /dev/null +++ b/src/big/mpp/userapps/src/pm/Makefile @@ -0,0 +1,28 @@ +include $(MPP_SRC_DIR)/userapps/src/mpp.mk +include $(MPP_SRC_DIR)/userapps/src/rt-smart.mk + +CURRECT_DIR_NAME=$(shell basename `pwd`) +LOCAL_SRC_DIR = $(shell pwd) +LIB = $(MPP_SRC_DIR)/userapps/lib/lib$(CURRECT_DIR_NAME).a + +LOCAL_CFLAGS = -I$(LOCAL_SRC_DIR)/ + +SRCS = $(wildcard $(LOCAL_SRC_DIR)/*.c) + +OBJS = $(patsubst %.c,%.o,$(SRCS)) + +all: $(LIB) + @-rm -f $(OBJS) + echo "${PWD}/Makefile all" + +$(OBJS): %.o : %.c + @$(CC) $(CC_CFLAGS) $(LOCAL_CFLAGS) $(BSP_CFLGAS) $(RTSMART_CFLAGS) $(MPP_USER_CFLGAS) -c $< -o $@ + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +clean: + echo "${PWD}/Makefile clean" + -rm -rf $(LIB) + +.PHONY: all clean \ No newline at end of file diff --git a/src/big/mpp/userapps/src/pm/mpi_pm.c b/src/big/mpp/userapps/src/pm/mpi_pm.c new file mode 100644 index 000000000..11da183ec --- /dev/null +++ b/src/big/mpp/userapps/src/pm/mpi_pm.c @@ -0,0 +1,336 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include "k_pm_ioctl.h" +#include "mpi_pm_api.h" + +static int g_pm_fd = -1; +static pthread_mutex_t g_pm_mutex = PTHREAD_MUTEX_INITIALIZER; + +static int pm_check_open(void) +{ + if (g_pm_fd >= 0) + return 0; + + pthread_mutex_lock(&g_pm_mutex); + if (g_pm_fd < 0) { + g_pm_fd = open("/dev/pm", O_RDWR); + if (g_pm_fd < 0) { + perror("open err\n"); + pthread_mutex_unlock(&g_pm_mutex); + return -errno; + } + } + pthread_mutex_unlock(&g_pm_mutex); + + return 0; +} + +int kd_mpi_pm_set_reg(uint32_t reg, uint32_t val) +{ + return 0; +} + +int kd_mpi_pm_get_reg(uint32_t reg, uint32_t *pval) +{ + return 0; +} + +int kd_mpi_pm_get_profiles(k_pm_domain domain, uint32_t *pcount, + k_pm_profile *pprofile) +{ + int ret; + _k_pm_domain_profiles *profiles; + + ret = pm_check_open(); + if (ret) + return ret; + + if ((!pcount) || (*pcount && !pprofile)) + return K_ERR_PM_NULL_PTR; + if (*pcount > 128) + *pcount = 128; + profiles = malloc(sizeof(_k_pm_domain_profiles) + *pcount * + sizeof(k_pm_profile)); + if (!profiles) + return K_ERR_PM_NOMEM; + + profiles->domain = domain; + profiles->number = *pcount; + + ret = ioctl(g_pm_fd, K_IOC_PM_GET_PROFILES, profiles); + if (ret) { + free(profiles); + return ret; + } + + if (*pcount) + memcpy(pprofile, profiles->profiles, profiles->number * + sizeof(k_pm_profile)); + *pcount = profiles->number; + free(profiles); + + return 0; +} + +int kd_mpi_pm_get_stat(k_pm_domain domain) +{ + return 0; +} + +int kd_mpi_pm_set_governor(k_pm_domain domain, k_pm_governor governor) +{ + int ret; + _k_pm_domain_governor gov; + + ret = pm_check_open(); + if (ret) + return ret; + + gov.domain = domain; + gov.governor = governor; + + ret = ioctl(g_pm_fd, K_IOC_PM_SET_GOVERNOR, &gov); + + return ret; +} + +int kd_mpi_pm_get_governor(k_pm_domain domain, k_pm_governor *pgovernor) +{ + int ret; + _k_pm_domain_governor gov; + + ret = pm_check_open(); + if (ret) + return ret; + + gov.domain = domain; + + ret = ioctl(g_pm_fd, K_IOC_PM_GET_GOVERNOR, &gov); + *pgovernor = gov.governor; + + return ret; +} + +int kd_mpi_pm_set_profile(k_pm_domain domain, int32_t index) +{ + int ret; + _k_pm_domain_profile profile; + + ret = pm_check_open(); + if (ret) + return ret; + + profile.domain = domain; + profile.index = index; + + ret = ioctl(g_pm_fd, K_IOC_PM_SET_PROFILE, &profile); + + return ret; +} + +int kd_mpi_pm_get_profile(k_pm_domain domain, int32_t *pindex) +{ + int ret; + _k_pm_domain_profile profile; + + ret = pm_check_open(); + if (ret) + return ret; + + profile.domain = domain; + + ret = ioctl(g_pm_fd, K_IOC_PM_GET_PROFILE, &profile); + *pindex = profile.index; + + return ret; +} + +int kd_mpi_pm_set_profile_lock(k_pm_domain domain, int32_t index) +{ + int ret; + _k_pm_domain_profile profile; + + ret = pm_check_open(); + if (ret) + return ret; + + profile.domain = domain; + profile.index = index; + + ret = ioctl(g_pm_fd, K_IOC_PM_SET_PROFILE_LOCK, &profile); + + return ret; +} + +int kd_mpi_pm_set_profile_unlock(k_pm_domain domain, int32_t index) +{ + int ret; + _k_pm_domain_profile profile; + + ret = pm_check_open(); + if (ret) + return ret; + + profile.domain = domain; + profile.index = index; + + ret = ioctl(g_pm_fd, K_IOC_PM_SET_PROFILE_UNLOCK, &profile); + + return ret; +} + +int kd_mpi_pm_set_thermal_protect(k_pm_domain domain, int32_t temp, + int32_t index) +{ + int ret; + _k_pm_domain_thermal_protect thermal; + + ret = pm_check_open(); + if (ret) + return ret; + + thermal.domain = domain; + thermal.temp = temp; + thermal.index = index; + + ret = ioctl(g_pm_fd, K_IOC_PM_SET_THERMAL_PROTECT, &thermal); + + return ret; +} + +int kd_mpi_pm_get_thermal_protect(k_pm_domain domain, int32_t *ptemp, + int32_t *pindex) +{ + int ret; + _k_pm_domain_thermal_protect thermal; + + ret = pm_check_open(); + if (ret) + return ret; + + thermal.domain = domain; + + ret = ioctl(g_pm_fd, K_IOC_PM_GET_THERMAL_PROTECT, &thermal); + *ptemp = thermal.temp; + *pindex = thermal.index; + + return ret; +} + +int kd_mpi_pm_set_thermal_shutdown(int32_t temp) +{ + int ret; + + ret = pm_check_open(); + if (ret) + return ret; + + ret = ioctl(g_pm_fd, K_IOC_PM_SET_THERMAL_SHUTDOWN, &temp); + + return ret; +} + +int kd_mpi_pm_get_thermal_shutdown(int32_t *ptemp) +{ + int ret; + int32_t temp; + + ret = pm_check_open(); + if (ret) + return ret; + + ret = ioctl(g_pm_fd, K_IOC_PM_GET_THERMAL_SHUTDOWN, &temp); + *ptemp = temp; + + return ret; +} + +int kd_mpi_pm_set_clock(k_pm_domain domain, bool enable) +{ + int ret; + _k_pm_domain_bool domain_bool; + + ret = pm_check_open(); + if (ret) + return ret; + + domain_bool.domain = domain; + domain_bool.enable = enable; + + ret = ioctl(g_pm_fd, K_IOC_PM_SET_CLOCK, &domain_bool); + + return ret; +} + +int kd_mpi_pm_set_power(k_pm_domain domain, bool enable) +{ + int ret; + _k_pm_domain_bool domain_bool; + + ret = pm_check_open(); + if (ret) + return ret; + + domain_bool.domain = domain; + domain_bool.enable = enable; + + ret = ioctl(g_pm_fd, K_IOC_PM_SET_POWER, &domain_bool); + + return ret; +} + +__attribute__((weak)) int kd_mpi_pm_runtime_runstage(k_runtimestage_id stage) +{ + int ret = 0; + + if (stage == RUNTIMESTAGE_ID_AI2D_START) { + ret = kd_mpi_pm_set_clock(PM_DOMAIN_KPU, true); + if (!ret) + ret = kd_mpi_pm_set_power(PM_DOMAIN_KPU, true); + } else if (stage == RUNTIMESTAGE_ID_AI2D_STOP) { + ret = kd_mpi_pm_set_power(PM_DOMAIN_KPU, false); + if (!ret) + ret = kd_mpi_pm_set_clock(PM_DOMAIN_KPU, false); + } else if (stage == RUNTIMESTAGE_ID_KPU_START) { + ret = kd_mpi_pm_set_clock(PM_DOMAIN_KPU, true); + if (!ret) + ret = kd_mpi_pm_set_power(PM_DOMAIN_KPU, true); + } else if (stage == RUNTIMESTAGE_ID_KPU_STOP) { + ret = kd_mpi_pm_set_power(PM_DOMAIN_KPU, false); + if (!ret) + ret = kd_mpi_pm_set_clock(PM_DOMAIN_KPU, false); + } else { + ret = 0; + } + + return ret; +} diff --git a/src/big/rt-smart/kernel/bsp/maix3/board/extcomponents/CherryUSB/usb_port.c b/src/big/rt-smart/kernel/bsp/maix3/board/extcomponents/CherryUSB/usb_port.c index ffffc69e6..6153408d7 100755 --- a/src/big/rt-smart/kernel/bsp/maix3/board/extcomponents/CherryUSB/usb_port.c +++ b/src/big/rt-smart/kernel/bsp/maix3/board/extcomponents/CherryUSB/usb_port.c @@ -63,21 +63,9 @@ static int cdc_write(struct dfs_fd *fd, const void *buf, size_t count) { if (count == 0) { return 0; } - #if 0 - rt_kprintf("write:"); - for (size_t i = 0; i < count; i++) { - rt_kprintf("\\x%02X", ((unsigned char*)buf)[i]); - } - rt_kprintf("\n"); - #endif - if ((count == 1) && (*(char*)buf == '\n')) { - usbd_ep_start_write(CDC_IN_EP, "\r\n", 2); - } else { - usbd_ep_start_write(CDC_IN_EP, buf, count); - } - // FIXME: async - usleep(10000); - // rt_sem_take(&cdc_write_sem, RT_WAITING_FOREVER); + // TODO: async + rt_sem_take(&cdc_write_sem, RT_WAITING_FOREVER); + usbd_ep_start_write(CDC_IN_EP, buf, count); return count; } @@ -113,7 +101,7 @@ void usb_dc_low_level_init(void) } device->fops = &cdc_ops; rt_sem_init(&cdc_read_sem, "cdc/read", 0, RT_IPC_FLAG_FIFO); - rt_sem_init(&cdc_write_sem, "cdc/write", 0, RT_IPC_FLAG_FIFO); + rt_sem_init(&cdc_write_sem, "cdc/write", 1, RT_IPC_FLAG_FIFO); #define MEMORY_MSC 1 #if !MEMORY_MSC diff --git a/src/big/rt-smart/kernel/bsp/maix3/board/interdrv/cipher/cipher_aes/drv_aes.c b/src/big/rt-smart/kernel/bsp/maix3/board/interdrv/cipher/cipher_aes/drv_aes.c index a15570430..1af2807cd 100644 --- a/src/big/rt-smart/kernel/bsp/maix3/board/interdrv/cipher/cipher_aes/drv_aes.c +++ b/src/big/rt-smart/kernel/bsp/maix3/board/interdrv/cipher/cipher_aes/drv_aes.c @@ -43,8 +43,6 @@ static void *sec_base_addr = RT_NULL; static int aes_hardlock; rt_uint8_t pufs_buffer[BUFFER_SIZE]; pufs_ka_slot_t g_keyslot; -static void *in_kvirt; -static void *out_kvirt; struct aes_context aes_ctx = { .op = GCM_AVAILABLE_OP }; //----------------------BASE FUNCTION ----------------------------------------// @@ -314,7 +312,7 @@ static void dma_write_data_block_config(rt_bool_t head, rt_bool_t tail, rt_bool_ writel(value, sec_base_addr + DMA_DSC_CFG_4_OFFSET); } -static void dma_write_rwcfg(const rt_uint8_t *out, const rt_uint8_t *in, rt_uint32_t len) +static void dma_write_rwcfg(const rt_uint8_t *out, const rt_uint8_t *in, rt_uint32_t len, void *in_kvirt, void *out_kvirt) { rt_uint64_t in_pa, out_pa; @@ -690,7 +688,17 @@ static pufs_status_t _ctx_update(struct aes_context* aes_ctx, dma_write_config_0(RT_FALSE, RT_FALSE, RT_FALSE); dma_write_data_block_config(aes_ctx->start ? RT_FALSE : RT_TRUE, last, RT_TRUE, RT_TRUE, 0); - dma_write_rwcfg(out, in, inlen); + + void *in_kvirt, *out_kvirt; + in_kvirt = rt_malloc(inlen); + out_kvirt = rt_malloc(inlen); + if(!in_kvirt || !out_kvirt) + { + rt_kprintf("%s malloc fail!\n", __func__); + check = -E_ERROR; + return check; + } + dma_write_rwcfg(out, in, inlen, in_kvirt, out_kvirt); if ((check = gcm_prepare(aes_ctx, out, inlen)) != SUCCESS) return check; @@ -719,6 +727,8 @@ static pufs_status_t _ctx_update(struct aes_context* aes_ctx, *outlen = inlen; rt_memcpy(out, out_kvirt, inlen); } + rt_free(in_kvirt); + rt_free(out_kvirt); return SUCCESS; } @@ -772,7 +782,7 @@ static pufs_status_t gcm_tag(struct aes_context *aes_ctx, rt_uint8_t *tag, rt_ui writel(0, sec_base_addr + GCM_CFG_2_OFFSET); dma_write_data_block_config(RT_TRUE, RT_TRUE, RT_TRUE, RT_TRUE, 0); - dma_write_rwcfg(RT_NULL, RT_NULL, 0); + dma_write_rwcfg(RT_NULL, RT_NULL, 0, RT_NULL, RT_NULL); dma_write_config_0(RT_FALSE, RT_FALSE, RT_FALSE); dma_write_key_config_0(aes_ctx->keytype, ALGO_TYPE_GCM, aes_ctx->keylen << 3, get_key_slot_idx(aes_ctx->keytype, aes_ctx->keyslot)); @@ -1037,6 +1047,8 @@ static pufs_status_t build_j0(rt_uint8_t* j0, *(j0 + 15) = 1; return SUCCESS; } + else + return E_UNSUPPORT; #if 0 struct aes_context aes_ctx = { .op = GCM_AVAILABLE_OP }; @@ -1224,16 +1236,6 @@ static rt_err_t aes_control(rt_device_t dev, int cmd, void *args) lwp_get_from_user(_aad, config_args->in, _aadlen); lwp_get_from_user(_in, (config_args->in + _aadlen), _inlen); - // alloc global buffer for store val from PUF-DMA - in_kvirt = rt_malloc(_ivlen + _aadlen + _inlen + 16); - out_kvirt = rt_malloc(_ivlen + _aadlen + _inlen + 16); - if(!in_kvirt || !out_kvirt) - { - rt_kprintf("%s malloc fail!\n", __func__); - ret = -RT_ERROR; - return ret; - } - // rt_kprintf("keybits = %d, ivlen = %d, inlen = %d, outlen = %d, aadlen = %d, taglen = %d\n", _keybits, _ivlen, _inlen, _outlen, _aadlen, _taglen); switch(cmd) @@ -1255,7 +1257,7 @@ static rt_err_t aes_control(rt_device_t dev, int cmd, void *args) while(0 != kd_hardlock_lock(aes_hardlock)); if((check = pufs_import_plaintext_key(SSKEY, g_keyslot, (const rt_uint8_t *)_key, _keybits)) != SUCCESS) { ret = -RT_ERROR; - return ret; + goto release_lock; } // do encrypt @@ -1268,14 +1270,14 @@ static rt_err_t aes_control(rt_device_t dev, int cmd, void *args) (rt_uint8_t *)_tag, _taglen)) != SUCCESS) { ret = -RT_ERROR; - return ret; + goto release_lock; } // clear key from hardware if((check = pufs_clear_key(SSKEY, g_keyslot, _keybits) != SUCCESS)) { ret = -RT_ERROR; - return ret; + goto release_lock; } kd_hardlock_unlock(aes_hardlock); @@ -1310,7 +1312,7 @@ static rt_err_t aes_control(rt_device_t dev, int cmd, void *args) while(0 != kd_hardlock_lock(aes_hardlock)); if((check = pufs_import_plaintext_key(SSKEY, g_keyslot, (const rt_uint8_t *)_key, _keybits)) != SUCCESS) { ret = -RT_ERROR; - return ret; + goto release_lock; } // do decrypt @@ -1323,14 +1325,14 @@ static rt_err_t aes_control(rt_device_t dev, int cmd, void *args) (const rt_uint8_t *)_tag, _taglen)) != SUCCESS) { ret = -RT_ERROR; - return ret; + goto release_lock; } // clear key from hardware if((check = pufs_clear_key(SSKEY, g_keyslot, _keybits) != SUCCESS)) { ret = -RT_ERROR; - return ret; + goto release_lock; } kd_hardlock_unlock(aes_hardlock); @@ -1351,11 +1353,16 @@ static rt_err_t aes_control(rt_device_t dev, int cmd, void *args) return -RT_EINVAL; } - // release global buffer - rt_free(in_kvirt); - rt_free(out_kvirt); + if(ret != RT_EOK) + goto release_lock; + +ret_aes: return ret; + +release_lock: + kd_hardlock_unlock(aes_hardlock); + goto ret_aes; } static rt_err_t aes_open(rt_device_t dev, rt_uint16_t oflag) diff --git a/src/big/rt-smart/kernel/bsp/maix3/board/interdrv/cipher/cipher_hash/drv_hash256.c b/src/big/rt-smart/kernel/bsp/maix3/board/interdrv/cipher/cipher_hash/drv_hash256.c index 2b4021fa6..38a19e769 100644 --- a/src/big/rt-smart/kernel/bsp/maix3/board/interdrv/cipher/cipher_hash/drv_hash256.c +++ b/src/big/rt-smart/kernel/bsp/maix3/board/interdrv/cipher/cipher_hash/drv_hash256.c @@ -492,7 +492,7 @@ static rt_err_t hash_control(rt_device_t dev, int cmd, void *args) while(0 != kd_hardlock_lock(hash_hardlock)); if((ret = sha256_init(&hash_ctx)) != RT_EOK) - return ret; + goto release_lock; break; } @@ -500,7 +500,7 @@ static rt_err_t hash_control(rt_device_t dev, int cmd, void *args) case RT_HWHASH_CTRL_UPDATE: { if((ret = sha256_update(&hash_ctx, msg, msglen)) != RT_EOK) - return ret; + goto release_lock; break; } @@ -508,7 +508,7 @@ static rt_err_t hash_control(rt_device_t dev, int cmd, void *args) case RT_HWHASH_CTRL_FINISH: { if((ret = sha256_finish(&hash_ctx, &md)) != RT_EOK) - return ret; + goto release_lock; lwp_put_to_user(config_args->dgst, md.dgst, md.dlen); config_args->dlen = md.dlen; @@ -521,7 +521,13 @@ static rt_err_t hash_control(rt_device_t dev, int cmd, void *args) return RT_EINVAL; } +ret_hash: return ret; + +release_lock: + if(ret != RT_EOK) + kd_hardlock_unlock(hash_hardlock); + goto ret_hash; } static rt_err_t hash_open(rt_device_t dev, rt_uint16_t oflag) diff --git a/src/big/rt-smart/kernel/bsp/maix3/board/interdrv/cipher/cipher_sm4/drv_sm4.c b/src/big/rt-smart/kernel/bsp/maix3/board/interdrv/cipher/cipher_sm4/drv_sm4.c index b5002bc9a..fb2762b69 100644 --- a/src/big/rt-smart/kernel/bsp/maix3/board/interdrv/cipher/cipher_sm4/drv_sm4.c +++ b/src/big/rt-smart/kernel/bsp/maix3/board/interdrv/cipher/cipher_sm4/drv_sm4.c @@ -254,7 +254,8 @@ static void dma_write_data_block_config(rt_bool_t head, rt_bool_t tail, rt_bool_ writel(value, sec_base_addr + DMA_DSC_CFG_4_OFFSET); } -static void dma_write_rwcfg(const rt_uint8_t *out, const rt_uint8_t *in, rt_uint32_t len) +static void dma_write_rwcfg(const rt_uint8_t *out, const rt_uint8_t *in, rt_uint32_t len, void *in_buff, void *out_buff) +// static void dma_write_rwcfg(const rt_uint8_t *out, const rt_uint8_t *in, rt_uint32_t len) { rt_uint64_t in_pa, out_pa; @@ -264,8 +265,8 @@ static void dma_write_rwcfg(const rt_uint8_t *out, const rt_uint8_t *in, rt_uint writel((uintptr_t)out, sec_base_addr + DMA_DSC_CFG_1_OFFSET); else { - rt_hw_cpu_dcache_clean_flush(out_kvirt, len); - out_pa = virt_to_phys((void*)out_kvirt); + rt_hw_cpu_dcache_clean_flush(out_buff, len); + out_pa = virt_to_phys((void*)out_buff); rt_hw_cpu_dcache_clean_flush((void *)out_pa, len); writel(out_pa, sec_base_addr + DMA_DSC_CFG_1_OFFSET); } @@ -274,10 +275,10 @@ static void dma_write_rwcfg(const rt_uint8_t *out, const rt_uint8_t *in, rt_uint writel((uintptr_t)in, sec_base_addr + DMA_DSC_CFG_0_OFFSET); else // virtual to physical { - rt_memcpy(in_kvirt, (void *)in, len); + rt_memcpy(in_buff, (void *)in, len); - rt_hw_cpu_dcache_clean_flush(in_kvirt, len); - in_pa = virt_to_phys(in_kvirt); + rt_hw_cpu_dcache_clean_flush(in_buff, len); + in_pa = virt_to_phys(in_buff); rt_hw_cpu_dcache_clean_flush((void *)in_pa, len); writel(in_pa, sec_base_addr + DMA_DSC_CFG_0_OFFSET); } @@ -733,33 +734,77 @@ static pufs_status_t _ctx_update(struct sm4_context* sm4_ctx, dma_write_config_0(RT_FALSE, RT_FALSE, RT_FALSE); dma_write_data_block_config(sm4_ctx->start ? RT_FALSE : RT_TRUE, last, RT_TRUE, RT_TRUE, 0); - dma_write_rwcfg(out, in, inlen); - - if ((check = sp38a_prepare(sm4_ctx)) != SUCCESS) - return check; - dma_write_start(); - while (dma_check_busy_status(&val32)); - - if (val32 != 0) + if(inlen > 448) { - rt_kprintf("[ERROR] DMA status 0: 0x%08x\n", val32); - return E_ERROR; - } + rt_uint8_t *in_buff = RT_NULL; + rt_uint8_t *out_buff = RT_NULL; + rt_uint8_t array[2*inlen + 16]; + rt_memset(array, 0, 2*inlen + 16); + in_buff = array; + out_buff = (array + inlen); + dma_write_rwcfg(out, in, inlen, in_buff, out_buff); + + if ((check = sp38a_prepare(sm4_ctx)) != SUCCESS) + return check; + + dma_write_start(); + while (dma_check_busy_status(&val32)); + + if (val32 != 0) + { + rt_kprintf("[ERROR] DMA status 0: 0x%08x\n", val32); + return E_ERROR; + } - val32 = readl(sec_base_addr + SP38A_STAT_OFFSET); - if ((val32 & SP38A_STATUS_ERROR_MASK) != 0) - { - rt_kprintf("[ERROR] SM4 status 0: 0x%08x\n", val32); - return E_ERROR; + val32 = readl(sec_base_addr + SP38A_STAT_OFFSET); + if ((val32 & SP38A_STATUS_ERROR_MASK) != 0) + { + rt_kprintf("[ERROR] SM4 status 0: 0x%08x\n", val32); + return E_ERROR; + } + + // post-processing + if (last == RT_FALSE) + sp38a_postproc(sm4_ctx); + + // rt_memcpy(out, out_kvirt, inlen); + rt_memcpy(out, out_buff, inlen); + *outlen = inlen; } + else + { + rt_uint8_t *in_buff = (rt_uint8_t*)in_kvirt; + rt_uint8_t *out_buff = (rt_uint8_t*)out_kvirt; + dma_write_rwcfg(out, in, inlen, in_buff, out_buff); - // post-processing - if (last == RT_FALSE) - sp38a_postproc(sm4_ctx); + if ((check = sp38a_prepare(sm4_ctx)) != SUCCESS) + return check; - rt_memcpy(out, out_kvirt, inlen); - *outlen = inlen; + dma_write_start(); + while (dma_check_busy_status(&val32)); + + if (val32 != 0) + { + rt_kprintf("[ERROR] DMA status 0: 0x%08x\n", val32); + return E_ERROR; + } + + val32 = readl(sec_base_addr + SP38A_STAT_OFFSET); + if ((val32 & SP38A_STATUS_ERROR_MASK) != 0) + { + rt_kprintf("[ERROR] SM4 status 0: 0x%08x\n", val32); + return E_ERROR; + } + + // post-processing + if (last == RT_FALSE) + sp38a_postproc(sm4_ctx); + + // rt_memcpy(out, out_kvirt, inlen); + rt_memcpy(out, out_buff, inlen); + *outlen = inlen; + } debug_func("out", (void*)out, inlen); @@ -1165,6 +1210,7 @@ static rt_err_t sm4_control(rt_device_t dev, int cmd, void *args) { case RT_SM4_ENC: { + rt_uint32_t _toutlen; // debug debug_func("key", _key, _keylen); debug_func("iv", _iv, _ivlen); @@ -1183,7 +1229,7 @@ static rt_err_t sm4_control(rt_device_t dev, int cmd, void *args) } // do encrypt - if((check = pufs_enc_sm4((rt_uint8_t *)_out, &_outlen, + if((check = pufs_enc_sm4((rt_uint8_t *)_out, &_toutlen, (const rt_uint8_t *)_in, _inlen, SM4, SSKEY, g_keyslot, _keybits, @@ -1194,7 +1240,7 @@ static rt_err_t sm4_control(rt_device_t dev, int cmd, void *args) } // clear key from hardware - if((check = pufs_clear_key(SSKEY, g_keyslot, _keybits) != SUCCESS) || (_outlen != _inlen)) + if((check = pufs_clear_key(SSKEY, g_keyslot, _keybits) != SUCCESS) || (_outlen != _toutlen)) { ret = -RT_ERROR; return ret; @@ -1207,7 +1253,7 @@ static rt_err_t sm4_control(rt_device_t dev, int cmd, void *args) // output result config_args->outlen = _outlen; lwp_put_to_user(config_args->out, _out, _outlen); - rt_free(total); + break; } case RT_SM4_DEC: @@ -1254,14 +1300,14 @@ static rt_err_t sm4_control(rt_device_t dev, int cmd, void *args) // output result config_args->outlen = _outlen; lwp_put_to_user(config_args->out, _out, _outlen); - rt_free(total); + break; } default: return -RT_EINVAL; } - + rt_free(total); // release global buffer rt_free(in_kvirt); rt_free(out_kvirt); diff --git a/src/common/cdk/user/component/datafifo/host/lib/libdatafifo.a b/src/common/cdk/user/component/datafifo/host/lib/libdatafifo.a index 72d511a08..82619fc0c 100644 Binary files a/src/common/cdk/user/component/datafifo/host/lib/libdatafifo.a and b/src/common/cdk/user/component/datafifo/host/lib/libdatafifo.a differ diff --git a/src/common/cdk/user/component/datafifo/slave/lib/libdatafifo.a b/src/common/cdk/user/component/datafifo/slave/lib/libdatafifo.a index a2d4c9d6d..3b9f7cb6d 100644 Binary files a/src/common/cdk/user/component/datafifo/slave/lib/libdatafifo.a and b/src/common/cdk/user/component/datafifo/slave/lib/libdatafifo.a differ diff --git a/src/common/cdk/user/component/ipcmsg/host/lib/libipcmsg.a b/src/common/cdk/user/component/ipcmsg/host/lib/libipcmsg.a index ce39a1154..6fbf9d395 100644 Binary files a/src/common/cdk/user/component/ipcmsg/host/lib/libipcmsg.a and b/src/common/cdk/user/component/ipcmsg/host/lib/libipcmsg.a differ diff --git a/src/common/cdk/user/component/ipcmsg/slave/lib/libipcmsg.a b/src/common/cdk/user/component/ipcmsg/slave/lib/libipcmsg.a index d00d2448e..779f29515 100644 Binary files a/src/common/cdk/user/component/ipcmsg/slave/lib/libipcmsg.a and b/src/common/cdk/user/component/ipcmsg/slave/lib/libipcmsg.a differ diff --git a/src/common/cdk/user/samples/rtsp_demo/src/h265LiveFrameSource.cpp b/src/common/cdk/user/samples/rtsp_demo/src/h265LiveFrameSource.cpp index 081feaedf..3cbb6ba13 100644 --- a/src/common/cdk/user/samples/rtsp_demo/src/h265LiveFrameSource.cpp +++ b/src/common/cdk/user/samples/rtsp_demo/src/h265LiveFrameSource.cpp @@ -45,12 +45,12 @@ H265LiveFrameSource::parseFrame(std::shared_ptr data, size_t data_size, case 32: // VPS fAuxLine.clear(); fVps.reset(), fSps.reset(), fPps.reset(); - fVps = make_shared_array(size);; + fVps = make_shared_array(size); memcpy(fVps.get(), buffer, size); vps_size = size; break; case 33: // SPS - fSps = make_shared_array(size);; + fSps = make_shared_array(size); memcpy(fSps.get(), buffer, size); sps_size = size; break; diff --git a/src/common/cdk/user/samples/rtsp_demo/src/streaming_player.cpp b/src/common/cdk/user/samples/rtsp_demo/src/streaming_player.cpp index 71a3927a1..cfdac3f26 100644 --- a/src/common/cdk/user/samples/rtsp_demo/src/streaming_player.cpp +++ b/src/common/cdk/user/samples/rtsp_demo/src/streaming_player.cpp @@ -225,6 +225,14 @@ int StreamingPlayer::CreateVideoEncode(const SessionAttr &session_attr) { chn_attr.rc_attr.rc_mode = K_VENC_RC_MODE_CBR; chn_attr.rc_attr.cbr.src_frame_rate = 30; chn_attr.rc_attr.cbr.dst_frame_rate = 30; + if (sensor_type_ == OV_OV9286_MIPI_1280X720_30FPS_10BIT_LINEAR_IR || + sensor_type_ == OV_OV9286_MIPI_1280X720_30FPS_10BIT_LINEAR_SPECKLE) { + chn_attr.rc_attr.cbr.src_frame_rate = 15; + chn_attr.rc_attr.cbr.dst_frame_rate = 15; + } else if (sensor_type_ == OV_OV9286_MIPI_1280X720_60FPS_10BIT_LINEAR_IR_SPECKLE) { + chn_attr.rc_attr.cbr.src_frame_rate = 60; + chn_attr.rc_attr.cbr.dst_frame_rate = 60; + } chn_attr.rc_attr.cbr.bit_rate = 4000; if (session_attr.video_type == kVideoTypeH264) { chn_attr.venc_attr.type = K_PT_H264; diff --git a/src/common/cdk/user/samples/rtsp_server/media.cpp b/src/common/cdk/user/samples/rtsp_server/media.cpp index 9cede5185..0e9be1ab0 100644 --- a/src/common/cdk/user/samples/rtsp_server/media.cpp +++ b/src/common/cdk/user/samples/rtsp_server/media.cpp @@ -364,6 +364,14 @@ int KdMedia::CreateVcapVEnc(IOnVEncData *on_venc_data) { chn_attr.rc_attr.rc_mode = K_VENC_RC_MODE_CBR; chn_attr.rc_attr.cbr.src_frame_rate = 30; chn_attr.rc_attr.cbr.dst_frame_rate = 30; + if (config_.sensor_type == OV_OV9286_MIPI_1280X720_30FPS_10BIT_LINEAR_IR || + config_.sensor_type == OV_OV9286_MIPI_1280X720_30FPS_10BIT_LINEAR_SPECKLE) { + chn_attr.rc_attr.cbr.src_frame_rate = 15; + chn_attr.rc_attr.cbr.dst_frame_rate = 15; + } else if (config_.sensor_type == OV_OV9286_MIPI_1280X720_60FPS_10BIT_LINEAR_IR_SPECKLE) { + chn_attr.rc_attr.cbr.src_frame_rate = 60; + chn_attr.rc_attr.cbr.dst_frame_rate = 60; + } chn_attr.rc_attr.cbr.bit_rate = config_.bitrate_kbps; if (config_.video_type == KdMediaVideoType::kVideoTypeH264) { chn_attr.venc_attr.type = K_PT_H264; diff --git a/src/common/opensbi/lib/sbi/sbi_hart.c b/src/common/opensbi/lib/sbi/sbi_hart.c index 1837455c6..c3f6d0c2e 100644 --- a/src/common/opensbi/lib/sbi/sbi_hart.c +++ b/src/common/opensbi/lib/sbi/sbi_hart.c @@ -191,6 +191,7 @@ int sbi_hart_pmp_configure(struct sbi_scratch *scratch) pmp_gran_log2 = log2roundup(sbi_hart_pmp_granularity(scratch)); pmp_bits = sbi_hart_pmp_addrbits(scratch) - 1; pmp_addr_max = (1UL << pmp_bits) | ((1UL << pmp_bits) - 1); + pmp_addr_max = 0x3fffffffff; sbi_domain_for_each_memregion(dom, reg) { if (pmp_count <= pmp_idx) diff --git a/src/little/buildroot-ext/configs/k230_evb_doorlock_defconfig b/src/little/buildroot-ext/configs/k230_evb_doorlock_defconfig index 51b4dfa2b..9ceada773 100644 --- a/src/little/buildroot-ext/configs/k230_evb_doorlock_defconfig +++ b/src/little/buildroot-ext/configs/k230_evb_doorlock_defconfig @@ -21,6 +21,7 @@ BR2_ROOTFS_DEVICE_TABLE="$(TOPDIR)/../board/canaan/k230/device_table.txt" BR2_ROOTFS_POST_IMAGE_SCRIPT="$(TOPDIR)/../board/canaan/k230/post-image.sh" BR2_PACKAGE_BUSYBOX_CONFIG_FRAGMENT_FILES="$(TOPDIR)/../board/canaan/k230/defconfigs/busybox-riscv.fragment" BR2_PACKAGE_BUSYBOX_SHOW_OTHERS=y +BR2_PACKAGE_UNZIP=y BR2_PACKAGE_FIO=y BR2_PACKAGE_LMBENCH=y BR2_PACKAGE_RAMSMP=y diff --git a/src/little/buildroot-ext/configs/k230_evb_peephole_device_flash_defconfig b/src/little/buildroot-ext/configs/k230_evb_peephole_device_flash_defconfig new file mode 100644 index 000000000..e70386d51 --- /dev/null +++ b/src/little/buildroot-ext/configs/k230_evb_peephole_device_flash_defconfig @@ -0,0 +1,61 @@ +BR2_riscv=y +BR2_riscv_custom=y +BR2_RISCV_ISA_CUSTOM_RVM=y +BR2_RISCV_ISA_CUSTOM_RVF=y +BR2_RISCV_ISA_CUSTOM_RVD=y +BR2_RISCV_ISA_CUSTOM_RVC=y +BR2_RISCV_ISA_CUSTOM_THEAD=y +BR2_DL_DIR="$(TOPDIR)/../dl" +BR2_SHARED_STATIC_LIBS=y +BR2_GLOBAL_PATCH_DIR="$(TOPDIR)/../package/patches" +BR2_TOOLCHAIN_EXTERNAL=y +BR2_TOOLCHAIN_EXTERNAL_PATH="/data/toolchain/T-head/Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.0" +BR2_TOOLCHAIN_EXTERNAL_CUSTOM_PREFIX="riscv64-unknown-linux-gnu" +BR2_TOOLCHAIN_EXTERNAL_HEADERS_5_10=y +BR2_TOOLCHAIN_EXTERNAL_CUSTOM_GLIBC=y +# BR2_TOOLCHAIN_EXTERNAL_INET_RPC is not set +BR2_TOOLCHAIN_EXTERNAL_CXX=y +# BR2_PACKAGE_HOST_GDB is not set +# BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_MDEV is not set +BR2_ROOTFS_DEVICE_TABLE="$(TOPDIR)/../board/canaan/k230/device_table.txt" +BR2_ROOTFS_POST_IMAGE_SCRIPT="$(TOPDIR)/../board/canaan/k230/post-image.sh" +BR2_PACKAGE_BUSYBOX_CONFIG_FRAGMENT_FILES="$(TOPDIR)/../board/canaan/k230/defconfigs/busybox-riscv.fragment" +BR2_PACKAGE_BUSYBOX_SHOW_OTHERS=y +BR2_PACKAGE_FIO=y +BR2_PACKAGE_LMBENCH=y +BR2_PACKAGE_RAMSMP=y +BR2_PACKAGE_RAMSPEED=y +# BR2_PACKAGE_STRESS_NG is not set +BR2_PACKAGE_TRACE_CMD=y +BR2_PACKAGE_DOSFSTOOLS=y +BR2_PACKAGE_DOSFSTOOLS_FATLABEL=y +BR2_PACKAGE_DOSFSTOOLS_FSCK_FAT=y +BR2_PACKAGE_DOSFSTOOLS_MKFS_FAT=y +BR2_PACKAGE_MTD=y +BR2_PACKAGE_MTD_JFFS2DUMP=y +BR2_PACKAGE_MTD_MKFSJFFS2=y +BR2_PACKAGE_MTD_MKFSUBIFS=y +BR2_PACKAGE_I2C_TOOLS=y +BR2_PACKAGE_MEMTESTER=y +BR2_PACKAGE_LIBDRM=y +BR2_PACKAGE_LIBDRM_INSTALL_TESTS=y +BR2_PACKAGE_LIBFFI=y +BR2_PACKAGE_LRZSZ=y +BR2_PACKAGE_OPENSSH=y +BR2_PACKAGE_BASH=y +BR2_TARGET_ROOTFS_CPIO=y +BR2_TARGET_ROOTFS_CPIO_GZIP=y +BR2_TARGET_ROOTFS_EXT2=y +BR2_TARGET_OPENSBI=y +BR2_PACKAGE_HOST_ANDROID_TOOLS=y +BR2_PACKAGE_HOST_ANDROID_TOOLS_EXT4_UTILS=y +BR2_PACKAGE_HOST_DTC=y +BR2_PACKAGE_HOST_GENIMAGE=y +BR2_PACKAGE_HOST_UBOOT_TOOLS=y +# BR2_PACKAGE_I2C_TOOL is not set +# BR2_PACKAGE_USB_TEST is not set +# BR2_PACKAGE_AIW4211LV10 is not set +BR2_PACKAGE_LVGL=y +BR2_PACKAGE_LIBDISP=y +BR2_PACKAGE_PEEPHOLE_DEVICE=y +BR2_PACKAGE_TOUCH_EMU=y diff --git a/src/little/buildroot-ext/configs/k230_evb_peephole_device_defconfig b/src/little/buildroot-ext/configs/k230_evb_peephole_device_sd_defconfig similarity index 100% rename from src/little/buildroot-ext/configs/k230_evb_peephole_device_defconfig rename to src/little/buildroot-ext/configs/k230_evb_peephole_device_sd_defconfig diff --git a/src/little/buildroot-ext/package/door_lock/src/ui/data/img/ota.png b/src/little/buildroot-ext/package/door_lock/src/ui/data/img/ota.png new file mode 100644 index 000000000..5607edd7f Binary files /dev/null and b/src/little/buildroot-ext/package/door_lock/src/ui/data/img/ota.png differ diff --git a/src/little/buildroot-ext/package/door_lock/src/ui/src/scr_main.c b/src/little/buildroot-ext/package/door_lock/src/ui/src/scr_main.c index 0f6fadede..44bc97b0a 100644 --- a/src/little/buildroot-ext/package/door_lock/src/ui/src/scr_main.c +++ b/src/little/buildroot-ext/package/door_lock/src/ui/src/scr_main.c @@ -48,6 +48,11 @@ static void scr_main_btn_signup_event_handler(lv_event_t *e) jump_to_scr_signup(); } +static void scr_main_btn_ota_event_handler(lv_event_t *e) +{ + jump_to_scr_ota(); +} + static void scr_main_btn_import_event_handler(lv_event_t *e) { static const char* pic_path = "/sharefs/pic"; @@ -64,12 +69,12 @@ static int obj_property_init(void) { lv_ui.img_root_path = DATA_FILE_PATH"img/"; - lv_ui.scr_main_btn_signup.pos.x = 20; + lv_ui.scr_main_btn_signup.pos.x = lv_pct(10); lv_ui.scr_main_btn_signup.pos.y = -90; lv_ui.scr_main_btn_signup.align = LV_ALIGN_BOTTOM_MID; lv_ui.scr_main_btn_signup.img_path = "signup.png"; - lv_ui.scr_main_btn_import.pos.x = lv_pct(-30); + lv_ui.scr_main_btn_import.pos.x = lv_pct(-10); lv_ui.scr_main_btn_import.pos.y = -96; lv_ui.scr_main_btn_import.align = LV_ALIGN_BOTTOM_MID; lv_ui.scr_main_btn_import.img_path = "import.png"; @@ -79,6 +84,11 @@ static int obj_property_init(void) lv_ui.scr_main_btn_delete.align = LV_ALIGN_BOTTOM_MID; lv_ui.scr_main_btn_delete.img_path = "delete.png"; + lv_ui.scr_main_btn_ota.pos.x = lv_pct(-30); + lv_ui.scr_main_btn_ota.pos.y = -96; + lv_ui.scr_main_btn_ota.align = LV_ALIGN_BOTTOM_MID; + lv_ui.scr_main_btn_ota.img_path = "ota.png"; + return 0; } @@ -134,6 +144,19 @@ void setup_scr_scr_main(void) lv_obj_add_flag(obj, LV_OBJ_FLAG_CLICKABLE); lv_obj_add_event_cb(obj, scr_main_btn_delete_event_handler, LV_EVENT_CLICKED, NULL); + + obj = lv_img_create(lv_ui.scr_main); + lv_ui.scr_main_btn_ota.obj = obj; + lv_obj_set_pos(obj, lv_ui.scr_main_btn_ota.pos.x, + lv_ui.scr_main_btn_ota.pos.y); + lv_obj_set_align(obj, lv_ui.scr_main_btn_ota.align); + lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT); + snprintf(file_path, sizeof(file_path), "%s%s", lv_ui.img_root_path, + lv_ui.scr_main_btn_ota.img_path); + lv_img_set_src(obj, file_path); + lv_obj_add_flag(obj, LV_OBJ_FLAG_CLICKABLE); + lv_obj_add_event_cb(obj, scr_main_btn_ota_event_handler, LV_EVENT_CLICKED, + NULL); } void jump_to_scr_main(void) diff --git a/src/little/buildroot-ext/package/door_lock/src/ui/src/scr_ota.c b/src/little/buildroot-ext/package/door_lock/src/ui/src/scr_ota.c new file mode 100644 index 000000000..c8262fb3e --- /dev/null +++ b/src/little/buildroot-ext/package/door_lock/src/ui/src/scr_ota.c @@ -0,0 +1,80 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "ui_common.h" + +#define OTA_PACKAGE_PATH "/tmp/doorlock_ota_package.kpk" + +static void scr_ota_close(lv_event_t *e) +{ + lv_scr_load_anim(lv_ui.scr_main, LV_SCR_LOAD_ANIM_NONE, 0, 0, true); +} + +static void scr_ota_continue(lv_event_t *e) +{ + lv_obj_t *ta = lv_event_get_user_data(e); + char *name = lv_textarea_get_text(ta); + char cmd[256]; + if (strlen(name)) { + sprintf(cmd,"sed -ri 's/([0-9]{1,3}\.){3}[0-9]{1,3}/%s/g' /etc/ota.conf",name); + system(cmd); + } + lv_scr_load_anim(lv_ui.scr_main, LV_SCR_LOAD_ANIM_NONE, 0, 0, true); +} + +static void setup_scr_scr_ota(void) +{ + lv_obj_t *obj; + + obj = lv_obj_create(NULL); + lv_ui.scr_ota = obj; + lv_obj_remove_style_all(obj); + lv_obj_set_style_bg_opa(obj, LV_OPA_TRANSP, LV_PART_MAIN); + lv_obj_clear_flag(obj, LV_OBJ_FLAG_CLICKABLE); + lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE); + + lv_obj_t *ta = lv_textarea_create(lv_ui.scr_ota); + lv_obj_set_size(ta, lv_pct(100), LV_SIZE_CONTENT); + lv_textarea_set_text(ta, ""); + lv_textarea_set_one_line(ta, true); + lv_textarea_set_max_length(ta, 32); + lv_textarea_set_align(ta, LV_TEXT_ALIGN_CENTER); + lv_obj_set_style_text_font(ta, &lv_font_montserrat_48, LV_PART_MAIN); + + lv_obj_t *kb = lv_keyboard_create(lv_ui.scr_ota); + lv_obj_set_style_text_font(kb, &lv_font_montserrat_40, LV_PART_MAIN); + lv_obj_set_size(kb, lv_pct(100), 580); + lv_keyboard_set_mode(kb, LV_KEYBOARD_MODE_NUMBER); + lv_keyboard_set_textarea(kb, ta); + lv_obj_add_event_cb(kb, scr_ota_continue, LV_EVENT_READY, ta); + lv_obj_add_event_cb(kb, scr_ota_close, LV_EVENT_CANCEL, NULL); + lv_obj_align_to(ta, kb, LV_ALIGN_OUT_TOP_MID, 0, -10); +} + +void jump_to_scr_ota(void) +{ + setup_scr_scr_ota(); + lv_scr_load_anim(lv_ui.scr_ota, LV_SCR_LOAD_ANIM_NONE, 0, 0, false); +} diff --git a/src/little/buildroot-ext/package/door_lock/src/ui/src/ui_common.h b/src/little/buildroot-ext/package/door_lock/src/ui/src/ui_common.h index df94ec576..d27d1d5a9 100644 --- a/src/little/buildroot-ext/package/door_lock/src/ui/src/ui_common.h +++ b/src/little/buildroot-ext/package/door_lock/src/ui/src/ui_common.h @@ -57,7 +57,9 @@ typedef struct { user_img_obj_t scr_main_btn_signup; user_img_obj_t scr_main_btn_import; user_img_obj_t scr_main_btn_delete; + user_img_obj_t scr_main_btn_ota; lv_obj_t *scr_signup; + lv_obj_t *scr_ota; } lv_ui_t; extern lv_ui_t lv_ui; @@ -68,6 +70,7 @@ lv_obj_t *create_msgbox(const char *title, const char *txt); void setup_scr_scr_main(void); void jump_to_scr_main(void); void jump_to_scr_signup(void); +void jump_to_scr_ota(void); void scr_main_display_result(int8_t result); #ifdef __cplusplus diff --git a/src/little/buildroot-ext/package/ota/src/ota.c b/src/little/buildroot-ext/package/ota/src/ota.c index cc7a0c614..70e235eef 100755 --- a/src/little/buildroot-ext/package/ota/src/ota.c +++ b/src/little/buildroot-ext/package/ota/src/ota.c @@ -252,33 +252,34 @@ int main(int argc, char **argv) memset(command, 0x00, sizeof(command)); snprintf(command, sizeof(command), "%s 1", SCRIPT_PATH); - fp = popen(command, "r"); - if (fp == NULL) { - printf("popen %s error \n", command); - return -1; - } - while (fgets(pbuff, sizeof(pbuff), fp)) { - // no need to compare the last character '\n' - if (!strncmp(pbuff, "decompress ota_package.zip success", strlen(pbuff)-1)) { - printf("OTA update progress 50% \n"); - } else if (!strncmp(pbuff, "OTA update success", strlen(pbuff)-1)) { - printf("OTA update success \n"); - ota_reboot_flag = 1; - } else { - continue; - } - memset(pbuff, 0x00, sizeof(pbuff)); - } - ret = pclose(fp); - if ((WIFEXITED(ret)) && (WEXITSTATUS(ret) != 0)) { - printf("OTA update error \n"); - printf("run %s error \n", OTA_FIRMWARE_PATH); + ret = run_command(command); + if (ret < 0) { + printf("run_command %s error \n", command); return -1; - } else if ((WIFEXITED(ret)) && (WEXITSTATUS(ret) == 0)) { - printf("We captured the SIGCHLD signal \n"); - } else if ((WIFEXITED(ret) == 0) && (WEXITSTATUS(ret) == 255)) { - printf("We lost the SIGCHLD signal \n"); } + ota_reboot_flag = 1; + // while (fgets(pbuff, sizeof(pbuff), fp)) { + // // no need to compare the last character '\n' + // if (!strncmp(pbuff, "decompress ota_package.zip success", strlen(pbuff)-1)) { + // printf("OTA update progress 50% \n"); + // } else if (!strncmp(pbuff, "OTA update success", strlen(pbuff)-1)) { + // printf("OTA update success \n"); + // ota_reboot_flag = 1; + // } else { + // continue; + // } + // memset(pbuff, 0x00, sizeof(pbuff)); + // } + // ret = pclose(fp); + // if ((WIFEXITED(ret)) && (WEXITSTATUS(ret) != 0)) { + // printf("OTA update error \n"); + // printf("run %s error \n", OTA_FIRMWARE_PATH); + // return -1; + // } else if ((WIFEXITED(ret)) && (WEXITSTATUS(ret) == 0)) { + // printf("We captured the SIGCHLD signal \n"); + // } else if ((WIFEXITED(ret) == 0) && (WEXITSTATUS(ret) == 255)) { + // printf("We lost the SIGCHLD signal \n"); + // } // 重启系统 if (ota_reboot_flag == 1) { diff --git a/src/little/buildroot-ext/package/peephole_device/src/src/audio_talk.c b/src/little/buildroot-ext/package/peephole_device/src/src/audio_talk.c index 065e1f5ec..901a92ab3 100644 --- a/src/little/buildroot-ext/package/peephole_device/src/src/audio_talk.c +++ b/src/little/buildroot-ext/package/peephole_device/src/src/audio_talk.c @@ -16,10 +16,8 @@ #define AUDIO_PERSEC_DIV_NUM 25 static k_bool g_vb_init = K_FALSE; -static k_mapi_media_attr_t media_attr = {0}; static k_bool g_enable_audio_codec = K_TRUE; -extern void kd_mapi_media_init_workaround(k_bool media_init_flag); static k_s32 _mapi_sample_vb_init(k_bool enable_cache,k_u32 sample_rate) { if (g_vb_init) @@ -37,6 +35,7 @@ static k_s32 _mapi_sample_vb_init(k_bool enable_cache,k_u32 sample_rate) } #endif + k_mapi_media_attr_t media_attr; memset(&media_attr, 0, sizeof(k_mapi_media_attr_t)); k_vb_config* config = &media_attr.media_config.vb_config; @@ -59,7 +58,6 @@ static k_s32 _mapi_sample_vb_init(k_bool enable_cache,k_u32 sample_rate) } printf("mmz blk total size:%.2f MB\n", blk_total_size / 1024 / 1024.0); - kd_mapi_media_init_workaround(K_FALSE); ret = kd_mapi_media_init(&media_attr); if(ret != K_SUCCESS) { printf("kd_mapi_media_init error: %x\n", ret); diff --git a/src/little/buildroot-ext/package/peephole_device/src/src/comm/include/comm_msg.h b/src/little/buildroot-ext/package/peephole_device/src/src/comm/include/comm_msg.h index 828c35061..f7e2cef48 100644 --- a/src/little/buildroot-ext/package/peephole_device/src/src/comm/include/comm_msg.h +++ b/src/little/buildroot-ext/package/peephole_device/src/src/comm/include/comm_msg.h @@ -51,6 +51,7 @@ enum class UserMsgType : int { // server->client SERVER_MSG_BASE = 100, PLAYBACK_ACK, + CURRENT_MODE_TYPE, // UserMsgMax = 1000 }; diff --git a/src/little/buildroot-ext/package/peephole_device/src/src/lv_picture_files.c b/src/little/buildroot-ext/package/peephole_device/src/src/lv_picture_files.c index 587ae9a47..5fa8526a9 100644 --- a/src/little/buildroot-ext/package/peephole_device/src/src/lv_picture_files.c +++ b/src/little/buildroot-ext/package/peephole_device/src/src/lv_picture_files.c @@ -15,7 +15,7 @@ typedef struct tag_picture_file_info }picture_file_info; #define MAX_FILES_COUNT 100 -static picture_file_info g_ary_files[MAX_FILES_COUNT]; +static picture_file_info *g_ary_files = NULL; static int g_files_count = 0; static int _file_size(char* filename) @@ -87,6 +87,7 @@ static int readFileList(char *basePath) int _lv_picture_files_init(char *basePath) { g_files_count = 0; + g_ary_files = (picture_file_info*)calloc(sizeof(picture_file_info), MAX_FILES_COUNT); return readFileList(basePath); } diff --git a/src/little/buildroot-ext/package/peephole_device/src/src/lv_record_files.c b/src/little/buildroot-ext/package/peephole_device/src/src/lv_record_files.c index 528dc69ab..45dcccc24 100644 --- a/src/little/buildroot-ext/package/peephole_device/src/src/lv_record_files.c +++ b/src/little/buildroot-ext/package/peephole_device/src/src/lv_record_files.c @@ -15,7 +15,8 @@ typedef struct tag_record_file_info }record_file_info; #define MAX_FILES_COUNT 100 -static record_file_info g_ary_files[MAX_FILES_COUNT]; +// static record_file_info g_ary_files[MAX_FILES_COUNT]; +static record_file_info *g_ary_files = NULL; static int g_files_count = 0; static int _file_size(char* filename) @@ -87,6 +88,7 @@ static int readFileList(char *basePath) int _lv_record_files_init(char *basePath) { g_files_count = 0; + g_ary_files = (record_file_info*)calloc(sizeof(record_file_info), MAX_FILES_COUNT); return readFileList(basePath); } diff --git a/src/little/buildroot-ext/package/peephole_device/src/src/main.cpp b/src/little/buildroot-ext/package/peephole_device/src/src/main.cpp index b2a930949..a78a0835a 100755 --- a/src/little/buildroot-ext/package/peephole_device/src/src/main.cpp +++ b/src/little/buildroot-ext/package/peephole_device/src/src/main.cpp @@ -67,11 +67,13 @@ static bool enable_record = false; static std::string mp4_dir = "/sharefs/app"; static std::string jpeg_dir = "/sharefs/app"; static bool enable_debug_record = false; +static bool enable_pir_vo = false; +static bool show_perf_cycles = false; int parse_config(int argc, char *argv[]) { int result; opterr = 0; - while ((result = getopt(argc, argv, "hrsm:j:d")) != -1) { + while ((result = getopt(argc, argv, "hrsvm:j:dt")) != -1) { switch(result) { case 'r' : { remote_features_only = true; @@ -81,6 +83,10 @@ int parse_config(int argc, char *argv[]) { enable_record = true; break; } + case 'v' : { + enable_pir_vo = true; + break; + } case 'm' : { mp4_dir = optarg; break; @@ -93,6 +99,10 @@ int parse_config(int argc, char *argv[]) { enable_debug_record = true; break; } + case 't': { + printf("perf_get_smodecycles %llu\n", perf_get_smodecycles()); + exit(0); + } case 'h': default: Usage(); break; } @@ -160,7 +170,7 @@ int main(int argc, char *argv[]) return 0; #endif k_s32 ret; - printf("./peehole_device -h to show usage\n"); + // printf("./peephole_device -h to show usage\n"); parse_config(argc, argv); signal(SIGINT, sigHandler); @@ -175,7 +185,7 @@ int main(int argc, char *argv[]) return -1; } printf("MyApp::GetInstance()->Init() done\n"); - + bool gui_init = false; if (remote_features_only) { // for test, there are no local features (no GUI) while(!g_exit_flag) { @@ -197,33 +207,78 @@ int main(int argc, char *argv[]) usleep(40 * 1000); } } else { - lv_init(); - lv_port_disp_init(); - lv_port_indev_init(); + if (!enable_pir_vo) { + lv_init(); + lv_port_disp_init(); + lv_port_indev_init(); - setup_scr_scr_main(argv[1]); - if(0) set_priority(); + setup_scr_scr_main(argv[1]); + set_priority(); - jump_to_scr_main(); - while (!g_exit_flag) { - lv_timer_handler(); - usleep(40 * 1000); + jump_to_scr_main(); + printf("perf_ after jump_to_scr_main: %llu\n", perf_get_smodecycles()); - if (MyApp::GetInstance()->RpcPowerOff()) { - break; - } + std::thread([](){ + show_ipaddr(); + }).detach(); + while (!g_exit_flag) { + lv_timer_handler(); + usleep(40 * 1000); - if (enable_debug_record) { - int c = my_getchar(); - if(c == 's') { - MyApp::GetInstance()->EnableRecord(true); - printf("start record ...\n"); - } else if(c == 'p') { - MyApp::GetInstance()->EnableRecord(false); - printf("record stopping, wait until \"mp4 file generated\" shown\n"); - } else if (c == 'q') { + if (MyApp::GetInstance()->RpcPowerOff()) { break; } + if (enable_debug_record) { + int c = my_getchar(); + if(c == 's') { + MyApp::GetInstance()->EnableRecord(true); + printf("start record ...\n"); + } else if(c == 'p') { + MyApp::GetInstance()->EnableRecord(false); + printf("record stopping, wait until \"mp4 file generated\" shown\n"); + } else if (c == 'q') { + break; + } + } + } + } else { + while (!g_exit_flag) { + if (MyApp::GetInstance()->RpcPowerOff()) { + break; + } + int cur_mode = MyApp::GetInstance()->GetCurrentMode(); + + if (cur_mode == DOORBELL_MODE) { + if (!gui_init) { + lv_init(); + lv_port_disp_init(); + lv_port_indev_init(); + + setup_scr_scr_main(argv[1]); + set_priority(); + jump_to_scr_main(); + std::thread([](){ + show_ipaddr(); + }).detach(); + + gui_init = true; + } + lv_timer_handler(); + } + + if (enable_debug_record) { + int c = my_getchar(); + if(c == 's') { + MyApp::GetInstance()->EnableRecord(true); + printf("start record ...\n"); + } else if(c == 'p') { + MyApp::GetInstance()->EnableRecord(false); + printf("record stopping, wait until \"mp4 file generated\" shown\n"); + } else if (c == 'q') { + break; + } + } + usleep(40 * 1000); } } } diff --git a/src/little/buildroot-ext/package/peephole_device/src/src/my_app.cpp b/src/little/buildroot-ext/package/peephole_device/src/src/my_app.cpp index e1cd25468..dd616b1d4 100755 --- a/src/little/buildroot-ext/package/peephole_device/src/src/my_app.cpp +++ b/src/little/buildroot-ext/package/peephole_device/src/src/my_app.cpp @@ -44,26 +44,76 @@ static uint64_t get_avail_space_megabytes(const std::string &dir) { return (availableDisk >> 20); } +// FIXME +static bool flash_boot(void) { + char buf[1024]; + bool ret = false; + FILE* fp = popen("cat /proc/cmdline", "r"); + if (fp) { + while (fgets(buf, 1024, fp) != NULL) { + std::string str = buf; + if (str.find("ubifs") != std::string::npos) { + ret = true; + break; + } + } + pclose(fp); + } else { + std::cout << "popen fail!" << std::endl; + return false; + } + return ret; +} + int MyApp::Init(unsigned short port) { + printf("peephole_before comminit : %llu\n", perf_get_smodecycles()); if (client_.Init("peephole", this) < 0) { std::cout << "MyApp::Init() client_.init failed" << std::endl; return -1; } + printf("peephole_after comminit : %llu\n", perf_get_smodecycles()); key_detect_thread_exit_flag_.store(false); key_detect_thread_ = std::thread([this](){ key_event_handler(); }); + if (flash_boot()) { + storage_ready_ = 0; + sd_thd_ = std::thread([]() { + usleep(3000 * 1000); // FIXME, netdrv has higher priority + std::cout << "install mmc drv... " << std::endl; + system("insmod /lib/modules/5.10.4/kernel/drivers/mmc/core/mmc_core.ko"); + // system("insmod /lib/modules/5.10.4/kernel/drivers/mmc/core/pwrseq_simple.ko"); + // system("insmod /lib/modules/5.10.4/kernel/drivers/mmc/core/pwrseq_emmc.ko"); + system("insmod /lib/modules/5.10.4/kernel/drivers/mmc/core/mmc_block.ko"); + system("insmod /lib/modules/5.10.4/kernel/drivers/mmc/host/sdhci.ko"); + system("insmod /lib/modules/5.10.4/kernel/drivers/mmc/host/sdhci-pltfm.ko"); + system("insmod /lib/modules/5.10.4/kernel/drivers/mmc/host/sdhci-of-kendryte.ko"); + usleep(1000 * 1000); + std::cout << "mount sdcard... " << std::endl; + system("mkdir -p /sharefs"); + system("mount -t vfat /dev/mmcblk1p4 /sharefs"); + system("mkdir -p /sharefs/DCIM/video"); + system("mkdir -p /sharefs/DCIM/snapshot"); + std::cout << "mount sdcard... done" << std::endl; + storage_ready_ = 1; + }); + } else { + storage_ready_ = 1; + } + mp4_muxer_.Init(this); - if (enable_record_) cmd_start_record(); + if (enable_mp4_record_) cmd_start_record(); jpeg_muxer_.Init(this); + printf("peephole_after CreateRtspServer : %llu\n", perf_get_smodecycles()); if (CreateRtspServer() < 0) { std::cout << "MyApp::Init() CreateRtspServer failed" << std::endl; return - 1; } + printf("peephole_after CreateRtspServer : %llu\n", perf_get_smodecycles()); request_power_off_.store(false); playback_ack_.store(false); @@ -72,16 +122,17 @@ int MyApp::Init(unsigned short port) { return -1; } - std::cout << " mp4 available space (MB) : " << get_avail_space_megabytes(mp4_dir_) << std::endl; - std::cout << "jpeg available space (MB) : " << get_avail_space_megabytes(jpeg_dir_) << std::endl; + // std::cout << " mp4 available space (MB) : " << get_avail_space_megabytes(mp4_dir_) << std::endl; + // std::cout << "jpeg available space (MB) : " << get_avail_space_megabytes(jpeg_dir_) << std::endl; // init done, notify the comm-server that we are ready client_.Start(); + printf("peephole_after comm-client start : %llu\n", perf_get_smodecycles()); return 0; } void MyApp::DeInit() { - if (enable_record_) { + if (enable_mp4_record_) { this->EnableRecord(false); } if (key_detect_thread_.joinable()) { @@ -100,6 +151,21 @@ void MyApp::DeInit() { client_.DeInit(); mp4_muxer_.DeInit(); jpeg_muxer_.DeInit(); + // + if (flash_boot()) { + if (sd_thd_.joinable()) { + sd_thd_.join(); + } + /* + system("umount /sharefs"); + system("rmmod sdhci-of-kendryte"); + system("rmmod sdhci-pltfm"); + system("rmmod sdhci"); + system("rmmod mmc_block"); + system("rmmod mmc_core"); + */ + } + storage_ready_ = 0; } static uint64_t get_steady_time_ms(); @@ -109,7 +175,7 @@ int MyApp::EnterPlaybackMode(bool sync) if (!bEnterPlaybackMode) { std::cout << "EnterPlaybackMode --- 1 -- " << get_steady_time_ms() << std::endl; - if (enable_record_) { + if (enable_mp4_record_) { this->EnableRecord(false); } // exit all the services except comm @@ -135,7 +201,7 @@ int MyApp::EnterPlaybackMode(bool sync) while (!playback_ack_.load()) { usleep(1000); ++count; - if(count > 500) { + if(count > 5000) { std::cout << "PLAYBACK_ACK timeout" << std::endl; break; } @@ -174,6 +240,7 @@ int MyApp::RpcSendEvent(const RpcEventData &event) { // IRpcClientCallback void MyApp::OnNewClient(int64_t conn_id, const std::string &remote_ip) { std::cout << "MyApp::OnNewClient -- id " << (long) conn_id << ", remote_ip : " << remote_ip << std::endl; + printf("OnNewClient : %llu\n", perf_get_smodecycles()); StopRtspServer(); StartRtspServer(); } @@ -214,6 +281,17 @@ void MyApp::OnMessage(const UserMessage *message) { playback_ack_.store(true); break; } + case UserMsgType::CURRENT_MODE_TYPE: { + std::cout << "MyApp::OnMessage() -- CURRENT_MODE_TYPE" << std::endl; + if (!strcmp(message->data, "doorbell_mode")) { + current_mode_ = DOORBELL_MODE; + } else if (!strcmp(message->data, "pir_mode")) { + current_mode_ = PIR_MODE; + } else { + current_mode_ = MODE_BUTT; + } + break; + } default: { std::cout << "MyApp::OnMessage() -- unknown message : " << message->type << std::endl; break; @@ -292,7 +370,7 @@ void MyApp::OnEvent(const UserEventData &event) { } } - if(enable_record_) { + if(enable_jpeg_recod_) { jpeg_muxer_.Write(event); } } @@ -343,7 +421,7 @@ void MyApp::OnVEncFrameData(const AVEncFrameData &data) { } rtsp_lck.unlock(); - if (enable_record_) { + if (enable_mp4_record_) { mp4_muxer_.Write(data); } } @@ -368,7 +446,7 @@ void MyApp::OnAEncFrameData(const AVEncFrameData &data) { } rtsp_lck.unlock(); - if (enable_record_) { + if (enable_mp4_record_) { // mix the audio data, FIXME std::unique_lock lck(aq_mutex_); if (!audio_queue_.empty()) { @@ -414,7 +492,7 @@ void MyApp::OnBackChannelData(std::string &session_name, const uint8_t *data, si data.flags = 0; // not used this->SendAudioData(data, &cb); - if (enable_record_) { + if (enable_mp4_record_) { BackchannelData audio_data; audio_data.size = 320; std::shared_ptr p(new uint8_t[audio_data.size], std::default_delete()); diff --git a/src/little/buildroot-ext/package/peephole_device/src/src/my_app.h b/src/little/buildroot-ext/package/peephole_device/src/src/my_app.h index e67659797..b7102080c 100755 --- a/src/little/buildroot-ext/package/peephole_device/src/src/my_app.h +++ b/src/little/buildroot-ext/package/peephole_device/src/src/my_app.h @@ -34,6 +34,21 @@ #include "rtsp_server.h" #include "my_muxer.h" +static uint64_t perf_get_smodecycles(void) +{ + uint64_t cnt; + __asm__ __volatile__( + "rdcycle %0" : "=r"(cnt) + ); + return cnt; +} + +typedef enum { + PIR_MODE = 1, + DOORBELL_MODE, + MODE_BUTT, +} CurrentMode; + /* remote bidirection-speech with video: 1. audio-input(innner_codec) --> OnAEncFrameData() --> rtsp_server.SendAudioData @@ -59,7 +74,7 @@ class MyApp : public IRpcServerCallback, public IClientCallback, public IOnBackC jpeg_dir = jpeg_dir_; } void EnableRecord(bool enable) { - enable_record_.store(enable); + enable_mp4_record_.store(enable); if (!enable) { cmd_stop_record(); } else { @@ -67,6 +82,10 @@ class MyApp : public IRpcServerCallback, public IClientCallback, public IOnBackC } } + int GetCurrentMode() { + return current_mode_; + } + void SetPowerOff() { request_power_off_.store(true); } bool RpcPowerOff() const { return request_power_off_.load(); } @@ -137,6 +156,7 @@ class MyApp : public IRpcServerCallback, public IClientCallback, public IOnBackC // UserCommClient client_; std::atomic playback_ack_{false}; + std::atomic current_mode_ {0}; // KdRtspServer rtsp_server_; std::string stream_url_ = "peephole_stream"; @@ -160,13 +180,15 @@ class MyApp : public IRpcServerCallback, public IClientCallback, public IOnBackC std::string jpeg_dir_{"/sharefs/app/peephole_device"}; MyMp4Muxer mp4_muxer_; MyJpegMuxer jpeg_muxer_; - std::atomic enable_record_{false}; + std::atomic enable_mp4_record_{false}; + std::atomic enable_jpeg_recod_ {true}; struct BackchannelData{ std::shared_ptr data{nullptr}; size_t size{0}; }; std::mutex aq_mutex_; std::queue audio_queue_; + std::thread sd_thd_; }; #endif // MY_APP_H_ diff --git a/src/little/buildroot-ext/package/peephole_device/src/src/my_muxer.cpp b/src/little/buildroot-ext/package/peephole_device/src/src/my_muxer.cpp index 492c6cecf..ad760330b 100755 --- a/src/little/buildroot-ext/package/peephole_device/src/src/my_muxer.cpp +++ b/src/little/buildroot-ext/package/peephole_device/src/src/my_muxer.cpp @@ -4,6 +4,8 @@ #include #include "mp4_format.h" +volatile int storage_ready_ = 0; + class Mp4Muxer { public: Mp4Muxer() {} @@ -181,9 +183,6 @@ int MyMp4Muxer::Write(const AVEncFrameData &frame_data) { return 0; } - if (callback_ && !callback_->IsMp4SpaceAvailable()) { - return -1; - } // TODO, adjust timestamp for avsync ... // AVEncData data; @@ -229,10 +228,23 @@ void MyMp4Muxer::Process() { usleep(1000 * 10); continue; } + // FIXME, to control memory used by stream data + if (!storage_ready_) { + lck.unlock(); + usleep(1000 * 100); + continue; + } + data = queue_.top(); queue_.pop(); } + if (!callback_->IsMp4SpaceAvailable()) { + // std::cout << "MyMp4Muxer::Process, no space, discard data" << std::endl; + usleep(1000 * 10); + continue; + } + // check cmd first if(data.flags == 0x1000) { std::cout << "MyMp4Muxer::Process, receive command to stop record" << std::endl; @@ -352,10 +364,6 @@ int MyJpegMuxer::Write(const UserEventData &event) { std::unique_lock lck(mutex_); if (!initialized_) return -1; - if (callback_ && !callback_->IsJpegSpaceAvailable()) { - return -1; - } - EventData data; data.type = event.type; data.timestamp_ms = event.timestamp_ms; @@ -399,10 +407,24 @@ void MyJpegMuxer::Process() { usleep(1000 * 10); continue; } + + // FIXME, to control memory used by jpeg data + if (!storage_ready_) { + lck.unlock(); + // std::cout << "jpeg muxer --- waiting for storage ready ... " << std::endl; + usleep(1000 * 100); + continue; + } + data = queue_.front(); queue_.pop(); } + if (!callback_->IsJpegSpaceAvailable()) { + usleep(1000 * 10); + continue; + } + if (save_jpeg(data) < 0) { break; } diff --git a/src/little/buildroot-ext/package/peephole_device/src/src/my_muxer.h b/src/little/buildroot-ext/package/peephole_device/src/src/my_muxer.h index 576c4ae8d..41367b315 100755 --- a/src/little/buildroot-ext/package/peephole_device/src/src/my_muxer.h +++ b/src/little/buildroot-ext/package/peephole_device/src/src/my_muxer.h @@ -103,4 +103,6 @@ class MyJpegMuxer { std::queue queue_; }; +extern volatile int storage_ready_; + #endif // _MY_MUXER_H diff --git a/src/little/buildroot-ext/package/peephole_device/src/src/scr_main.cpp b/src/little/buildroot-ext/package/peephole_device/src/src/scr_main.cpp index 0d1dea089..d34a468eb 100755 --- a/src/little/buildroot-ext/package/peephole_device/src/src/scr_main.cpp +++ b/src/little/buildroot-ext/package/peephole_device/src/src/scr_main.cpp @@ -41,7 +41,7 @@ lv_ui_t lv_ui; static int get_ipaddr(const char *interface, char *ipaddr){ int sock_fd; if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1){ - printf("get_ipaddr() -- socket create failed...!\n"); + // printf("get_ipaddr() -- socket create failed...!\n"); return -1; } @@ -52,7 +52,7 @@ static int get_ipaddr(const char *interface, char *ipaddr){ strncpy(ifr_ip.ifr_name, interface, sizeof(ifr_ip.ifr_name) - 1); if(ioctl( sock_fd, SIOCGIFADDR, &ifr_ip) < 0 ){ - printf("get_ipaddr() -- SIOCGIFADDR ioctl error\n"); + // printf("get_ipaddr() -- SIOCGIFADDR ioctl error\n"); close(sock_fd); return -1; } @@ -252,14 +252,28 @@ void setup_scr_scr_main(char *url) lv_obj_add_flag(obj, LV_OBJ_FLAG_CLICKABLE); lv_obj_add_event_cb(obj, scr_main_btn_shutdown_event_handler, LV_EVENT_CLICKED, NULL); +} +void show_ipaddr(void) { std::string net_interface{"eth0"}; char local_ipaddr[20] = {0}; - get_ipaddr(net_interface.c_str(), (char*)local_ipaddr); + // FIXME + system("/sbin/ifup -a"); + while(get_ipaddr(net_interface.c_str(), (char*)local_ipaddr)) { + system("/sbin/ifup eth0"); + usleep(200000); + } + printf("perf_get_smodecycles after get ipaddr: %llu\n", perf_get_smodecycles()); + std::string ipaddr_str = local_ipaddr; + std::cout << "get_ipaddr : " << ipaddr_str << std::endl; + create_msgbox("", local_ipaddr); + /* + lv_obj_t *obj; obj = lv_msgbox_create(lv_ui.scr_main, NULL, local_ipaddr, NULL, false); lv_ui.scr_main_msg_url = obj; lv_obj_align_to(obj, lv_ui.scr_main_btn_intercom.obj, LV_ALIGN_OUT_TOP_LEFT, 0, -20); lv_obj_set_style_text_font(obj, &lv_font_montserrat_32, LV_PART_MAIN); + */ } void jump_to_scr_main(void) @@ -330,7 +344,7 @@ lv_obj_t *create_msgbox(const char *title, const char *txt) lv_timer_t *timer = lv_timer_create(msgbox_timeout_timer_handler, - 1 * 1000, (void *)&msgbox); + 3 * 1000, (void *)&msgbox); lv_timer_set_repeat_count(timer, 1); lv_obj_set_user_data(msgbox, timer); diff --git a/src/little/buildroot-ext/package/peephole_device/src/src/ui_common.h b/src/little/buildroot-ext/package/peephole_device/src/src/ui_common.h index 34b73b763..7ab5c3dcb 100755 --- a/src/little/buildroot-ext/package/peephole_device/src/src/ui_common.h +++ b/src/little/buildroot-ext/package/peephole_device/src/src/ui_common.h @@ -85,6 +85,7 @@ lv_timer_t *create_oneshot_timer(lv_timer_cb_t timer_xcb, uint32_t period, lv_obj_t *create_msgbox(const char *title, const char *txt); void setup_scr_scr_main(char *url); void jump_to_scr_main(void); +void show_ipaddr(void); void jump_to_scr_playback(void); void scr_main_display_result(int8_t result); void jump_to_scr_playback_ctrl(uint32_t track_id); diff --git a/src/little/linux/arch/riscv/boot/dts/kendryte/k230_canmv.dts b/src/little/linux/arch/riscv/boot/dts/kendryte/k230_canmv.dts index 749a5d2ed..4a42003f8 100755 --- a/src/little/linux/arch/riscv/boot/dts/kendryte/k230_canmv.dts +++ b/src/little/linux/arch/riscv/boot/dts/kendryte/k230_canmv.dts @@ -97,6 +97,10 @@ }; }; +&gpio1 { + status = "okay"; +}; + &mmc_sd0{ status = "okay"; io_fixed_1v8; @@ -104,6 +108,7 @@ tx_delay_line = <0x00>; bcmdhd_wlan { compatible = "android,bcmdhd_wlan"; + gpio_wl_reg_on = <&port1 0 GPIO_ACTIVE_HIGH>; }; }; diff --git a/src/little/linux/arch/riscv/configs/k230_evb_doorlock_defconfig b/src/little/linux/arch/riscv/configs/k230_evb_doorlock_defconfig index 318e2fddd..81e63f760 100644 --- a/src/little/linux/arch/riscv/configs/k230_evb_doorlock_defconfig +++ b/src/little/linux/arch/riscv/configs/k230_evb_doorlock_defconfig @@ -59,9 +59,18 @@ CONFIG_PHYLIB=y CONFIG_MARVELL_PHY=y CONFIG_MICROCHIP_PHY=y CONFIG_PCS_XPCS=y + +CONFIG_MARVELL_PHY=y +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_RTL8152=m +CONFIG_USB_LAN78XX=m +CONFIG_USB_USBNET=m # CONFIG_USB_NET_ZAURUS is not set # CONFIG_WLAN_VENDOR_ADMTEK is not set -CONFIG_AIW4211LV10=m +# CONFIG_AIW4211LV10=m # CONFIG_WLAN_VENDOR_ATH is not set # CONFIG_WLAN_VENDOR_ATMEL is not set # CONFIG_WLAN_VENDOR_BROADCOM is not set @@ -111,8 +120,8 @@ CONFIG_GPIO_SYSFS=y CONFIG_POWER_RESET=y CONFIG_POWER_SUPPLY=y # CONFIG_HWMON is not set -CONFIG_THERMAL=y -CONFIG_CANAAN_THERMAL=m +# CONFIG_THERMAL=y +# CONFIG_CANAAN_THERMAL=m CONFIG_WATCHDOG=y CONFIG_DW_WATCHDOG=y CONFIG_MFD_SYSCON=y @@ -286,11 +295,11 @@ CONFIG_BACKLIGHT_CLASS_DEVICE=y CONFIG_USB=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y CONFIG_USB_STORAGE=y -CONFIG_USB_DWC2=m +CONFIG_USB_DWC2=y CONFIG_USB_TEST=m -CONFIG_USB_GADGET=m -CONFIG_USB_SNP_UDC_PLAT=m -CONFIG_USB_CONFIGFS=m +CONFIG_USB_GADGET=y +CONFIG_USB_SNP_UDC_PLAT=y +CONFIG_USB_CONFIGFS=y CONFIG_USB_CONFIGFS_MASS_STORAGE=y CONFIG_USB_CONFIGFS_F_LB_SS=y CONFIG_USB_CONFIGFS_F_UVC=y diff --git a/src/little/linux/arch/riscv/configs/k230_evb_peephole_device_flash_defconfig b/src/little/linux/arch/riscv/configs/k230_evb_peephole_device_flash_defconfig new file mode 100644 index 000000000..86550ee5a --- /dev/null +++ b/src/little/linux/arch/riscv/configs/k230_evb_peephole_device_flash_defconfig @@ -0,0 +1,372 @@ +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_PREEMPT=y +# CONFIG_IKCONFIG is not set +# CONFIG_IKCONFIG_PROC is not set +CONFIG_CGROUPS=y +CONFIG_CGROUP_SCHED=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_EXPERT=y +CONFIG_PERF_EVENTS=y +CONFIG_SOC_THEAD=y +CONFIG_SECTION_ALIGN_4KB=y +CONFIG_SMP=y +CONFIG_NR_CPUS=2 +CONFIG_PM=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_BSD_DISKLABEL=y +CONFIG_LDM_PARTITION=y +# CONFIG_LDM_DEBUG is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +# CONFIG_CMDLINE_PARTITION is not set +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IPV6 is not set +CONFIG_DNS_RESOLVER=y +CONFIG_NETLINK_DIAG=y +# CONFIG_CFG80211 is not set +# CONFIG_CFG80211_DEFAULT_PS is not set +# CONFIG_CFG80211_CRDA_SUPPORT is not set +# CONFIG_CFG80211_WEXT is not set +# CONFIG_ETHTOOL_NETLINK is not set +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_MTD=y +# CONFIG_MTD_TESTS is not set +CONFIG_MTD_BLOCK=y +CONFIG_MTD_RAW_NAND=y +CONFIG_MTD_SPI_NAND=y +CONFIG_MTD_SPI_NOR=y +# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set +CONFIG_MTD_UBI=y +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_LOOP_MIN_COUNT=4 +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_NETDEVICES=y +# CONFIG_VIRTIO_NET is not set +CONFIG_MACB=y +CONFIG_STMMAC_ETH=y +# CONFIG_NET_VENDOR_SYNOPSYS is not set +# CONFIG_NET_VENDOR_VIA is not set +# CONFIG_NET_VENDOR_WIZNET is not set +CONFIG_MARVELL_PHY=y +# CONFIG_USB_RTL8150 is not set +CONFIG_USB_RTL8152=m +# CONFIG_USB_LAN78XX is not set +CONFIG_USB_USBNET=m +# CONFIG_WLAN_VENDOR_ADMTEK is not set +# CONFIG_AIW4211LV10 is not set +# CONFIG_WLAN_VENDOR_ATH is not set +# CONFIG_WLAN_VENDOR_ATMEL is not set +# CONFIG_WLAN_VENDOR_BROADCOM is not set +# CONFIG_WLAN_VENDOR_CISCO is not set +# CONFIG_WLAN_VENDOR_INTEL is not set +# CONFIG_HOSTAP is not set +# CONFIG_WLAN_VENDOR_MARVELL is not set +# CONFIG_WLAN_VENDOR_MEDIATEK is not set +# CONFIG_WLAN_VENDOR_MICROCHIP is not set +# CONFIG_WLAN_VENDOR_RALINK is not set +# CONFIG_WLAN_VENDOR_REALTEK is not set +# CONFIG_WLAN_VENDOR_RSI is not set +# CONFIG_WLAN_VENDOR_ST is not set +# CONFIG_WLAN_VENDOR_TI is not set +# CONFIG_WLAN_VENDOR_ZYDAS is not set +# CONFIG_WLAN_VENDOR_QUANTENNA is not set +CONFIG_INPUT_EVDEV=y +CONFIG_KEYBOARD_GPIO=y +# CONFIG_MOUSE_PS2 is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_GOODIX=y +# CONFIG_SERIO_SERPORT is not set +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=5 +CONFIG_SERIAL_8250_RUNTIME_UARTS=5 +CONFIG_SERIAL_8250_DW=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIAL_EARLYCON_RISCV_SBI=y +CONFIG_HVC_RISCV_SBI=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_VIRTIO=y +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX=y +CONFIG_I2C_DESIGNWARE_PLATFORM=y +CONFIG_I2C_DESIGNWARE_ICE=y +CONFIG_SPI=y +CONFIG_SPI_DEBUG=y +CONFIG_SPI_DESIGNWARE=y +CONFIG_SPI_DW_DMA=y +CONFIG_SPI_DW_MMIO=y +# CONFIG_PTP_1588_CLOCK is not set +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_DWAPB=y +CONFIG_POWER_RESET=y +CONFIG_POWER_SUPPLY=y +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_CANAAN_THERMAL is not set +CONFIG_WATCHDOG=y +CONFIG_DW_WATCHDOG=y +# CONFIG_MEDIA_CEC_SUPPORT is not set +CONFIG_MEDIA_SUPPORT=y +# CONFIG_DVB_NET is not set +# CONFIG_DVB_DYNAMIC_MINORS is not set +# CONFIG_RADIO_ADAPTERS is not set +# CONFIG_CXD2880_SPI_DRV is not set +# CONFIG_MEDIA_TUNER_SIMPLE is not set +# CONFIG_MEDIA_TUNER_TDA18250 is not set +# CONFIG_MEDIA_TUNER_TDA8290 is not set +# CONFIG_MEDIA_TUNER_TDA827X is not set +# CONFIG_MEDIA_TUNER_TDA18271 is not set +# CONFIG_MEDIA_TUNER_TDA9887 is not set +# CONFIG_MEDIA_TUNER_TEA5761 is not set +# CONFIG_MEDIA_TUNER_TEA5767 is not set +# CONFIG_MEDIA_TUNER_MSI001 is not set +# CONFIG_MEDIA_TUNER_MT20XX is not set +# CONFIG_MEDIA_TUNER_MT2060 is not set +# CONFIG_MEDIA_TUNER_MT2063 is not set +# CONFIG_MEDIA_TUNER_MT2266 is not set +# CONFIG_MEDIA_TUNER_MT2131 is not set +# CONFIG_MEDIA_TUNER_QT1010 is not set +# CONFIG_MEDIA_TUNER_XC2028 is not set +# CONFIG_MEDIA_TUNER_XC5000 is not set +# CONFIG_MEDIA_TUNER_XC4000 is not set +# CONFIG_MEDIA_TUNER_MXL5005S is not set +# CONFIG_MEDIA_TUNER_MXL5007T is not set +# CONFIG_MEDIA_TUNER_MC44S803 is not set +# CONFIG_MEDIA_TUNER_MAX2165 is not set +# CONFIG_MEDIA_TUNER_TDA18218 is not set +# CONFIG_MEDIA_TUNER_FC0011 is not set +# CONFIG_MEDIA_TUNER_FC0012 is not set +# CONFIG_MEDIA_TUNER_FC0013 is not set +# CONFIG_MEDIA_TUNER_TDA18212 is not set +# CONFIG_MEDIA_TUNER_E4000 is not set +# CONFIG_MEDIA_TUNER_FC2580 is not set +# CONFIG_MEDIA_TUNER_M88RS6000T is not set +# CONFIG_MEDIA_TUNER_TUA9001 is not set +# CONFIG_MEDIA_TUNER_SI2157 is not set +# CONFIG_MEDIA_TUNER_IT913X is not set +# CONFIG_MEDIA_TUNER_R820T is not set +# CONFIG_MEDIA_TUNER_MXL301RF is not set +# CONFIG_MEDIA_TUNER_QM1D1C0042 is not set +# CONFIG_MEDIA_TUNER_QM1D1B0004 is not set +# CONFIG_DVB_STB0899 is not set +# CONFIG_DVB_STB6100 is not set +# CONFIG_DVB_STV090x is not set +# CONFIG_DVB_STV0910 is not set +# CONFIG_DVB_STV6110x is not set +# CONFIG_DVB_STV6111 is not set +# CONFIG_DVB_MXL5XX is not set +# CONFIG_DVB_M88DS3103 is not set +# CONFIG_DVB_DRXK is not set +# CONFIG_DVB_TDA18271C2DD is not set +# CONFIG_DVB_SI2165 is not set +# CONFIG_DVB_MN88472 is not set +# CONFIG_DVB_MN88473 is not set +# CONFIG_DVB_CX24110 is not set +# CONFIG_DVB_CX24123 is not set +# CONFIG_DVB_MT312 is not set +# CONFIG_DVB_ZL10036 is not set +# CONFIG_DVB_ZL10039 is not set +# CONFIG_DVB_S5H1420 is not set +# CONFIG_DVB_STV0288 is not set +# CONFIG_DVB_STB6000 is not set +# CONFIG_DVB_STV0299 is not set +# CONFIG_DVB_STV6110 is not set +# CONFIG_DVB_STV0900 is not set +# CONFIG_DVB_TDA8083 is not set +# CONFIG_DVB_TDA10086 is not set +# CONFIG_DVB_TDA8261 is not set +# CONFIG_DVB_VES1X93 is not set +# CONFIG_DVB_TUNER_ITD1000 is not set +# CONFIG_DVB_TUNER_CX24113 is not set +# CONFIG_DVB_TDA826X is not set +# CONFIG_DVB_TUA6100 is not set +# CONFIG_DVB_CX24116 is not set +# CONFIG_DVB_CX24117 is not set +# CONFIG_DVB_CX24120 is not set +# CONFIG_DVB_SI21XX is not set +# CONFIG_DVB_TS2020 is not set +# CONFIG_DVB_DS3000 is not set +# CONFIG_DVB_MB86A16 is not set +# CONFIG_DVB_TDA10071 is not set +# CONFIG_DVB_SP8870 is not set +# CONFIG_DVB_SP887X is not set +# CONFIG_DVB_CX22700 is not set +# CONFIG_DVB_CX22702 is not set +# CONFIG_DVB_S5H1432 is not set +# CONFIG_DVB_DRXD is not set +# CONFIG_DVB_L64781 is not set +# CONFIG_DVB_TDA1004X is not set +# CONFIG_DVB_NXT6000 is not set +# CONFIG_DVB_MT352 is not set +# CONFIG_DVB_ZL10353 is not set +# CONFIG_DVB_DIB3000MB is not set +# CONFIG_DVB_DIB3000MC is not set +# CONFIG_DVB_DIB7000M is not set +# CONFIG_DVB_DIB7000P is not set +# CONFIG_DVB_DIB9000 is not set +# CONFIG_DVB_TDA10048 is not set +# CONFIG_DVB_AF9013 is not set +# CONFIG_DVB_EC100 is not set +# CONFIG_DVB_STV0367 is not set +# CONFIG_DVB_CXD2820R is not set +# CONFIG_DVB_CXD2841ER is not set +# CONFIG_DVB_RTL2830 is not set +# CONFIG_DVB_RTL2832 is not set +# CONFIG_DVB_RTL2832_SDR is not set +# CONFIG_DVB_SI2168 is not set +# CONFIG_DVB_ZD1301_DEMOD is not set +# CONFIG_DVB_CXD2880 is not set +# CONFIG_DVB_VES1820 is not set +# CONFIG_DVB_TDA10021 is not set +# CONFIG_DVB_TDA10023 is not set +# CONFIG_DVB_STV0297 is not set +# CONFIG_DVB_NXT200X is not set +# CONFIG_DVB_OR51211 is not set +# CONFIG_DVB_OR51132 is not set +# CONFIG_DVB_BCM3510 is not set +# CONFIG_DVB_LGDT330X is not set +# CONFIG_DVB_LGDT3305 is not set +# CONFIG_DVB_LGDT3306A is not set +# CONFIG_DVB_LG2160 is not set +# CONFIG_DVB_S5H1409 is not set +# CONFIG_DVB_AU8522_DTV is not set +# CONFIG_DVB_AU8522_V4L is not set +# CONFIG_DVB_S5H1411 is not set +# CONFIG_DVB_S921 is not set +# CONFIG_DVB_DIB8000 is not set +# CONFIG_DVB_MB86A20S is not set +# CONFIG_DVB_TC90522 is not set +# CONFIG_DVB_MN88443X is not set +# CONFIG_DVB_PLL is not set +# CONFIG_DVB_TUNER_DIB0070 is not set +# CONFIG_DVB_TUNER_DIB0090 is not set +# CONFIG_DVB_DRX39XYJ is not set +# CONFIG_DVB_LNBH25 is not set +# CONFIG_DVB_LNBH29 is not set +# CONFIG_DVB_LNBP21 is not set +# CONFIG_DVB_LNBP22 is not set +# CONFIG_DVB_ISL6405 is not set +# CONFIG_DVB_ISL6421 is not set +# CONFIG_DVB_ISL6423 is not set +# CONFIG_DVB_A8293 is not set +# CONFIG_DVB_LGS8GL5 is not set +# CONFIG_DVB_LGS8GXX is not set +# CONFIG_DVB_ATBM8830 is not set +# CONFIG_DVB_TDA665x is not set +# CONFIG_DVB_IX2505V is not set +# CONFIG_DVB_M88RS2000 is not set +# CONFIG_DVB_AF9033 is not set +# CONFIG_DVB_HORUS3A is not set +# CONFIG_DVB_ASCOT2E is not set +# CONFIG_DVB_HELENE is not set +# CONFIG_DVB_CXD2099 is not set +# CONFIG_DVB_SP2 is not set +CONFIG_DRM=y +CONFIG_DRM_PANEL_CANAAN_UNIVERSAL=y +CONFIG_DRM_CANAAN=y +CONFIG_DRM_CANAAN_DSI=y +CONFIG_VG_LITE=m +CONFIG_FB=y +CONFIG_FB_VIRTUAL=m +CONFIG_FB_SIMPLE=y +CONFIG_LCD_CLASS_DEVICE=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +# CONFIG_VGA_CONSOLE is not set +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +# CONFIG_USB_STORAGE is not set +CONFIG_USB_DWC2=y +# CONFIG_USB_TEST is not set +# CONFIG_USB_GADGET is not set +# CONFIG_USB_SNP_UDC_PLAT is not set +# CONFIG_USB_CONFIGFS is not set +# CONFIG_USB_CONFIGFS_MASS_STORAGE is not set +# CONFIG_USB_CONFIGFS_F_LB_SS is not set +# CONFIG_USB_CONFIGFS_F_HID is not set +# CONFIG_USB_CONFIGFS_F_UVC is not set +CONFIG_MMC=m +# CONFIG_MMC_TEST is not set +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_SDHCI=m +CONFIG_MMC_SDHCI_PLTFM=m +CONFIG_MMC_SDHCI_OF_KENDRYTE=m +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_DMADEVICES=y +CONFIG_DW_AXI_DMAC=y +CONFIG_DMATEST=m +CONFIG_SYNC_FILE=y +# CONFIG_VIRTIO_MENU is not set +# CONFIG_VHOST_MENU is not set +# CONFIG_VIRTIO_BALLOON is not set +# CONFIG_VIRTIO_MMIO is not set +# CONFIG_MAILBOX is not set +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_SIFIVE_PLIC=y +CONFIG_GENERIC_PHY=y +CONFIG_RAS=y +CONFIG_NVMEM_KENDRYTE_K230_OTP=y +# CONFIG_EXT4_FS is not set +# CONFIG_EXT4_FS_POSIX_ACL is not set +CONFIG_FUSE_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_UTF8=y +# CONFIG_EXFAT_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_UBIFS_FS=y +CONFIG_UBIFS_FS_ADVANCED_COMPR=y +# CONFIG_UBIFS_FS_LZO is not set +# CONFIG_UBIFS_FS_ZSTD is not set +# CONFIG_NETWORK_FILESYSTEMS is not set +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_1250=y +CONFIG_NLS_CODEPAGE_1251=y +CONFIG_NLS_ISO8859_1=y +CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity" +CONFIG_CRYPTO_USER=y +CONFIG_CRYPTO_USER_API_HASH=y +CONFIG_CRYPTO_USER_API_AEAD=y +CONFIG_CRYPTO_DEV_CANAAN=y +CONFIG_CRYPTO_DEV_KENDRYTE_CRYP=y +CONFIG_CRYPTO_DEV_VIRTIO=y +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO=y +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_FS=y +CONFIG_DETECT_HUNG_TASK=y +CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=60 +CONFIG_DEBUG_ATOMIC_SLEEP=y +# CONFIG_RCU_TRACE is not set +CONFIG_IIO=y +CONFIG_PWM=y +CONFIG_PWM_SYSFS=y +CONFIG_PWM_K230=y diff --git a/src/little/linux/arch/riscv/configs/k230_evb_peephole_device_defconfig b/src/little/linux/arch/riscv/configs/k230_evb_peephole_device_sd_defconfig similarity index 100% rename from src/little/linux/arch/riscv/configs/k230_evb_peephole_device_defconfig rename to src/little/linux/arch/riscv/configs/k230_evb_peephole_device_sd_defconfig diff --git a/src/little/linux/arch/riscv/configs/k230_evb_peephole_phone_defconfig b/src/little/linux/arch/riscv/configs/k230_evb_peephole_phone_defconfig new file mode 100644 index 000000000..2a15a4660 --- /dev/null +++ b/src/little/linux/arch/riscv/configs/k230_evb_peephole_phone_defconfig @@ -0,0 +1,408 @@ +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_CGROUPS=y +CONFIG_CGROUP_SCHED=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_CGROUP_BPF=y +CONFIG_NAMESPACES=y +CONFIG_USER_NS=y +CONFIG_CHECKPOINT_RESTORE=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_EXPERT=y +CONFIG_BPF_SYSCALL=y +CONFIG_PERF_EVENTS=y +CONFIG_SOC_THEAD=y +CONFIG_SMP=y +CONFIG_PM=y +CONFIG_KPROBES=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_ACORN_PARTITION=y +CONFIG_ACORN_PARTITION_CUMANA=y +CONFIG_ACORN_PARTITION_EESOX=y +CONFIG_ACORN_PARTITION_ICS=y +CONFIG_ACORN_PARTITION_ADFS=y +CONFIG_ACORN_PARTITION_POWERTEC=y +CONFIG_ACORN_PARTITION_RISCIX=y +CONFIG_AIX_PARTITION=y +CONFIG_OSF_PARTITION=y +CONFIG_AMIGA_PARTITION=y +CONFIG_ATARI_PARTITION=y +CONFIG_MAC_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_LDM_PARTITION=y +CONFIG_LDM_DEBUG=y +CONFIG_SGI_PARTITION=y +CONFIG_ULTRIX_PARTITION=y +CONFIG_SUN_PARTITION=y +CONFIG_KARMA_PARTITION=y +CONFIG_SYSV68_PARTITION=y +CONFIG_CMDLINE_PARTITION=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NETLINK_DIAG=y +CONFIG_CFG80211=y +# CONFIG_CFG80211_DEFAULT_PS is not set +# CONFIG_CFG80211_CRDA_SUPPORT is not set +CONFIG_CFG80211_WEXT=y +CONFIG_NET_9P=y +CONFIG_NET_9P_VIRTIO=y +CONFIG_NET_9P_DEBUG=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_MTD=y +CONFIG_MTD_TESTS=m +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_RAW_NAND=y +CONFIG_MTD_SPI_NAND=y +CONFIG_MTD_SPI_NOR=y +# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set +CONFIG_MTD_UBI=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_VIRTIO_BLK=y +CONFIG_EEPROM_AT24=y +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_NETDEVICES=y +CONFIG_VIRTIO_NET=y +CONFIG_MACB=y +CONFIG_STMMAC_ETH=y +# CONFIG_NET_VENDOR_SYNOPSYS is not set +# CONFIG_NET_VENDOR_VIA is not set +# CONFIG_NET_VENDOR_WIZNET is not set +CONFIG_MARVELL_PHY=y +CONFIG_USB_CATC=y +CONFIG_USB_KAWETH=y +CONFIG_USB_PEGASUS=y +CONFIG_USB_RTL8150=y +CONFIG_USB_RTL8152=y +CONFIG_USB_LAN78XX=y +CONFIG_USB_USBNET=y +# CONFIG_WLAN_VENDOR_ADMTEK is not set +CONFIG_AIW4211LV10=m +# CONFIG_WLAN_VENDOR_ATH is not set +# CONFIG_WLAN_VENDOR_ATMEL is not set +# CONFIG_WLAN_VENDOR_BROADCOM is not set +# CONFIG_WLAN_VENDOR_CISCO is not set +# CONFIG_WLAN_VENDOR_INTEL is not set +CONFIG_HOSTAP=y +# CONFIG_WLAN_VENDOR_MARVELL is not set +# CONFIG_WLAN_VENDOR_MEDIATEK is not set +# CONFIG_WLAN_VENDOR_MICROCHIP is not set +# CONFIG_WLAN_VENDOR_RALINK is not set +# CONFIG_WLAN_VENDOR_REALTEK is not set +# CONFIG_WLAN_VENDOR_RSI is not set +# CONFIG_WLAN_VENDOR_ST is not set +# CONFIG_WLAN_VENDOR_TI is not set +# CONFIG_WLAN_VENDOR_ZYDAS is not set +# CONFIG_WLAN_VENDOR_QUANTENNA is not set +CONFIG_INPUT_EVDEV=y +CONFIG_KEYBOARD_GPIO=y +# CONFIG_MOUSE_PS2 is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_GOODIX=y +# CONFIG_SERIO_SERPORT is not set +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=5 +CONFIG_SERIAL_8250_RUNTIME_UARTS=5 +CONFIG_SERIAL_8250_DW=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIAL_EARLYCON_RISCV_SBI=y +CONFIG_HVC_RISCV_SBI=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_VIRTIO=y +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX=y +CONFIG_I2C_DESIGNWARE_PLATFORM=y +CONFIG_I2C_DESIGNWARE_ICE=y +CONFIG_SPI=y +CONFIG_SPI_DEBUG=y +CONFIG_SPI_DESIGNWARE=y +CONFIG_SPI_DW_DMA=y +CONFIG_SPI_DW_MMIO=y +# CONFIG_PTP_1588_CLOCK is not set +CONFIG_GPIOLIB=y +CONFIG_DEBUG_GPIO=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_DWAPB=y +CONFIG_POWER_RESET=y +CONFIG_POWER_SUPPLY=y +# CONFIG_HWMON is not set +CONFIG_THERMAL=y +CONFIG_CANAAN_THERMAL=y +CONFIG_WATCHDOG=y +CONFIG_DW_WATCHDOG=y +# CONFIG_MEDIA_CEC_SUPPORT is not set +CONFIG_MEDIA_SUPPORT=y +# CONFIG_DVB_NET is not set +# CONFIG_DVB_DYNAMIC_MINORS is not set +# CONFIG_RADIO_ADAPTERS is not set +# CONFIG_CXD2880_SPI_DRV is not set +# CONFIG_MEDIA_TUNER_SIMPLE is not set +# CONFIG_MEDIA_TUNER_TDA18250 is not set +# CONFIG_MEDIA_TUNER_TDA8290 is not set +# CONFIG_MEDIA_TUNER_TDA827X is not set +# CONFIG_MEDIA_TUNER_TDA18271 is not set +# CONFIG_MEDIA_TUNER_TDA9887 is not set +# CONFIG_MEDIA_TUNER_TEA5761 is not set +# CONFIG_MEDIA_TUNER_TEA5767 is not set +# CONFIG_MEDIA_TUNER_MSI001 is not set +# CONFIG_MEDIA_TUNER_MT20XX is not set +# CONFIG_MEDIA_TUNER_MT2060 is not set +# CONFIG_MEDIA_TUNER_MT2063 is not set +# CONFIG_MEDIA_TUNER_MT2266 is not set +# CONFIG_MEDIA_TUNER_MT2131 is not set +# CONFIG_MEDIA_TUNER_QT1010 is not set +# CONFIG_MEDIA_TUNER_XC2028 is not set +# CONFIG_MEDIA_TUNER_XC5000 is not set +# CONFIG_MEDIA_TUNER_XC4000 is not set +# CONFIG_MEDIA_TUNER_MXL5005S is not set +# CONFIG_MEDIA_TUNER_MXL5007T is not set +# CONFIG_MEDIA_TUNER_MC44S803 is not set +# CONFIG_MEDIA_TUNER_MAX2165 is not set +# CONFIG_MEDIA_TUNER_TDA18218 is not set +# CONFIG_MEDIA_TUNER_FC0011 is not set +# CONFIG_MEDIA_TUNER_FC0012 is not set +# CONFIG_MEDIA_TUNER_FC0013 is not set +# CONFIG_MEDIA_TUNER_TDA18212 is not set +# CONFIG_MEDIA_TUNER_E4000 is not set +# CONFIG_MEDIA_TUNER_FC2580 is not set +# CONFIG_MEDIA_TUNER_M88RS6000T is not set +# CONFIG_MEDIA_TUNER_TUA9001 is not set +# CONFIG_MEDIA_TUNER_SI2157 is not set +# CONFIG_MEDIA_TUNER_IT913X is not set +# CONFIG_MEDIA_TUNER_R820T is not set +# CONFIG_MEDIA_TUNER_MXL301RF is not set +# CONFIG_MEDIA_TUNER_QM1D1C0042 is not set +# CONFIG_MEDIA_TUNER_QM1D1B0004 is not set +# CONFIG_DVB_STB0899 is not set +# CONFIG_DVB_STB6100 is not set +# CONFIG_DVB_STV090x is not set +# CONFIG_DVB_STV0910 is not set +# CONFIG_DVB_STV6110x is not set +# CONFIG_DVB_STV6111 is not set +# CONFIG_DVB_MXL5XX is not set +# CONFIG_DVB_M88DS3103 is not set +# CONFIG_DVB_DRXK is not set +# CONFIG_DVB_TDA18271C2DD is not set +# CONFIG_DVB_SI2165 is not set +# CONFIG_DVB_MN88472 is not set +# CONFIG_DVB_MN88473 is not set +# CONFIG_DVB_CX24110 is not set +# CONFIG_DVB_CX24123 is not set +# CONFIG_DVB_MT312 is not set +# CONFIG_DVB_ZL10036 is not set +# CONFIG_DVB_ZL10039 is not set +# CONFIG_DVB_S5H1420 is not set +# CONFIG_DVB_STV0288 is not set +# CONFIG_DVB_STB6000 is not set +# CONFIG_DVB_STV0299 is not set +# CONFIG_DVB_STV6110 is not set +# CONFIG_DVB_STV0900 is not set +# CONFIG_DVB_TDA8083 is not set +# CONFIG_DVB_TDA10086 is not set +# CONFIG_DVB_TDA8261 is not set +# CONFIG_DVB_VES1X93 is not set +# CONFIG_DVB_TUNER_ITD1000 is not set +# CONFIG_DVB_TUNER_CX24113 is not set +# CONFIG_DVB_TDA826X is not set +# CONFIG_DVB_TUA6100 is not set +# CONFIG_DVB_CX24116 is not set +# CONFIG_DVB_CX24117 is not set +# CONFIG_DVB_CX24120 is not set +# CONFIG_DVB_SI21XX is not set +# CONFIG_DVB_TS2020 is not set +# CONFIG_DVB_DS3000 is not set +# CONFIG_DVB_MB86A16 is not set +# CONFIG_DVB_TDA10071 is not set +# CONFIG_DVB_SP8870 is not set +# CONFIG_DVB_SP887X is not set +# CONFIG_DVB_CX22700 is not set +# CONFIG_DVB_CX22702 is not set +# CONFIG_DVB_S5H1432 is not set +# CONFIG_DVB_DRXD is not set +# CONFIG_DVB_L64781 is not set +# CONFIG_DVB_TDA1004X is not set +# CONFIG_DVB_NXT6000 is not set +# CONFIG_DVB_MT352 is not set +# CONFIG_DVB_ZL10353 is not set +# CONFIG_DVB_DIB3000MB is not set +# CONFIG_DVB_DIB3000MC is not set +# CONFIG_DVB_DIB7000M is not set +# CONFIG_DVB_DIB7000P is not set +# CONFIG_DVB_DIB9000 is not set +# CONFIG_DVB_TDA10048 is not set +# CONFIG_DVB_AF9013 is not set +# CONFIG_DVB_EC100 is not set +# CONFIG_DVB_STV0367 is not set +# CONFIG_DVB_CXD2820R is not set +# CONFIG_DVB_CXD2841ER is not set +# CONFIG_DVB_RTL2830 is not set +# CONFIG_DVB_RTL2832 is not set +# CONFIG_DVB_RTL2832_SDR is not set +# CONFIG_DVB_SI2168 is not set +# CONFIG_DVB_ZD1301_DEMOD is not set +# CONFIG_DVB_CXD2880 is not set +# CONFIG_DVB_VES1820 is not set +# CONFIG_DVB_TDA10021 is not set +# CONFIG_DVB_TDA10023 is not set +# CONFIG_DVB_STV0297 is not set +# CONFIG_DVB_NXT200X is not set +# CONFIG_DVB_OR51211 is not set +# CONFIG_DVB_OR51132 is not set +# CONFIG_DVB_BCM3510 is not set +# CONFIG_DVB_LGDT330X is not set +# CONFIG_DVB_LGDT3305 is not set +# CONFIG_DVB_LGDT3306A is not set +# CONFIG_DVB_LG2160 is not set +# CONFIG_DVB_S5H1409 is not set +# CONFIG_DVB_AU8522_DTV is not set +# CONFIG_DVB_AU8522_V4L is not set +# CONFIG_DVB_S5H1411 is not set +# CONFIG_DVB_S921 is not set +# CONFIG_DVB_DIB8000 is not set +# CONFIG_DVB_MB86A20S is not set +# CONFIG_DVB_TC90522 is not set +# CONFIG_DVB_MN88443X is not set +# CONFIG_DVB_PLL is not set +# CONFIG_DVB_TUNER_DIB0070 is not set +# CONFIG_DVB_TUNER_DIB0090 is not set +# CONFIG_DVB_DRX39XYJ is not set +# CONFIG_DVB_LNBH25 is not set +# CONFIG_DVB_LNBH29 is not set +# CONFIG_DVB_LNBP21 is not set +# CONFIG_DVB_LNBP22 is not set +# CONFIG_DVB_ISL6405 is not set +# CONFIG_DVB_ISL6421 is not set +# CONFIG_DVB_ISL6423 is not set +# CONFIG_DVB_A8293 is not set +# CONFIG_DVB_LGS8GL5 is not set +# CONFIG_DVB_LGS8GXX is not set +# CONFIG_DVB_ATBM8830 is not set +# CONFIG_DVB_TDA665x is not set +# CONFIG_DVB_IX2505V is not set +# CONFIG_DVB_M88RS2000 is not set +# CONFIG_DVB_AF9033 is not set +# CONFIG_DVB_HORUS3A is not set +# CONFIG_DVB_ASCOT2E is not set +# CONFIG_DVB_HELENE is not set +# CONFIG_DVB_CXD2099 is not set +# CONFIG_DVB_SP2 is not set +CONFIG_DRM=y +CONFIG_DRM_PANEL_CANAAN_UNIVERSAL=y +CONFIG_DRM_CANAAN=y +CONFIG_DRM_CANAAN_DSI=y +CONFIG_VG_LITE=m +CONFIG_FB=y +CONFIG_FB_VIRTUAL=m +CONFIG_FB_SIMPLE=y +CONFIG_LCD_CLASS_DEVICE=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +# CONFIG_VGA_CONSOLE is not set +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_STORAGE=y +CONFIG_USB_DWC2=y +CONFIG_USB_TEST=m +CONFIG_USB_GADGET=y +CONFIG_USB_SNP_UDC_PLAT=y +CONFIG_USB_CONFIGFS=y +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +CONFIG_USB_CONFIGFS_F_LB_SS=y +CONFIG_USB_CONFIGFS_F_HID=y +CONFIG_USB_CONFIGFS_F_UVC=y +CONFIG_MMC=y +CONFIG_MMC_TEST=y +CONFIG_MMC_DEBUG=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_OF_KENDRYTE=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_DMADEVICES=y +CONFIG_DW_AXI_DMAC=y +CONFIG_DMATEST=y +CONFIG_SYNC_FILE=y +CONFIG_VIRTIO_BALLOON=y +CONFIG_VIRTIO_MMIO=y +CONFIG_SIFIVE_PLIC=y +CONFIG_GENERIC_PHY=y +CONFIG_RAS=y +CONFIG_NVMEM_KENDRYTE_K230_OTP=y +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_AUTOFS4_FS=y +CONFIG_FUSE_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_UTF8=y +CONFIG_EXFAT_FS=y +CONFIG_NTFS_FS=y +CONFIG_NTFS_RW=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_HFS_FS=y +CONFIG_HFSPLUS_FS=y +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_UBIFS_FS=y +CONFIG_UBIFS_FS_ADVANCED_COMPR=y +CONFIG_NFS_FS=y +CONFIG_NFS_V4=y +CONFIG_NFS_V4_1=y +CONFIG_NFS_V4_2=y +CONFIG_ROOT_NFS=y +CONFIG_9P_FS=y +CONFIG_9P_FS_POSIX_ACL=y +CONFIG_9P_FS_SECURITY=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_936=y +CONFIG_NLS_CODEPAGE_1250=y +CONFIG_NLS_CODEPAGE_1251=y +CONFIG_NLS_ISO8859_1=y +CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity" +CONFIG_CRYPTO_USER=y +CONFIG_CRYPTO_USER_API_HASH=y +CONFIG_CRYPTO_USER_API_AEAD=y +CONFIG_CRYPTO_DEV_CANAAN=y +CONFIG_CRYPTO_DEV_KENDRYTE_CRYP=y +CONFIG_CRYPTO_DEV_VIRTIO=y +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO=y +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_FS=y +CONFIG_DETECT_HUNG_TASK=y +CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=60 +CONFIG_DEBUG_ATOMIC_SLEEP=y +# CONFIG_RCU_TRACE is not set +CONFIG_IIO=y +CONFIG_PWM=y +CONFIG_PWM_SYSFS=y +CONFIG_PWM_K230=y diff --git a/src/little/linux/drivers/crypto/canaan/kendryte-aes.c b/src/little/linux/drivers/crypto/canaan/kendryte-aes.c index c2adc03cf..11fd36000 100755 --- a/src/little/linux/drivers/crypto/canaan/kendryte-aes.c +++ b/src/little/linux/drivers/crypto/canaan/kendryte-aes.c @@ -1228,7 +1228,7 @@ static int kendryte_gcm_aes_crypt(struct aead_request *req, bool encrypt) // clear key from internal slot if((check = clear_key(ctx, keytype, keyslot, keybits)) != SUCCESS ) - return check; + goto done; if(aadlen > 0) { diff --git a/src/little/linux/drivers/crypto/canaan/kendryte-hash.c b/src/little/linux/drivers/crypto/canaan/kendryte-hash.c index 3b3428531..48e597ce8 100755 --- a/src/little/linux/drivers/crypto/canaan/kendryte-hash.c +++ b/src/little/linux/drivers/crypto/canaan/kendryte-hash.c @@ -425,6 +425,7 @@ static int kendryte_sha256_final(struct ahash_request *req) { pr_err("Hash-%s Error!\n", __func__); ret = -1; + hardlock_unlock(hardlock); } sha256_free(ctx, req->nbytes); @@ -458,6 +459,7 @@ static int kendryte_sha256_update(struct ahash_request *req) { pr_err("Hash-%s Error!\n", __func__); ret = -1; + hardlock_unlock(hardlock); } kfree(msg); @@ -488,6 +490,7 @@ static int kendryte_sha256_init(struct ahash_request *req) { pr_err("Hash-%s Error!\n", __func__); ret = -1; + hardlock_unlock(hardlock); } return ret; diff --git a/src/little/linux/drivers/mmc/core/sdio.c b/src/little/linux/drivers/mmc/core/sdio.c index 311b1a0ed..5183406a9 100644 --- a/src/little/linux/drivers/mmc/core/sdio.c +++ b/src/little/linux/drivers/mmc/core/sdio.c @@ -665,8 +665,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, * Inform the card of the voltage */ err = mmc_send_io_op_cond(host, ocr, &rocr); - printk("%s: err:%d rocr=0x%x \n", mmc_hostname(host), err, rocr); - if (err) + if (err) return err; /* @@ -1175,8 +1174,7 @@ int mmc_attach_sdio(struct mmc_host *host) WARN_ON(!host->claimed); err = mmc_send_io_op_cond(host, 0, &ocr); - printk("%s: err:%d ocr=0x%x \n", mmc_hostname(host), err, ocr); - if (err) + if (err) return err; mmc_attach_bus(host, &mmc_sdio_ops); diff --git a/src/little/linux/drivers/net/wireless/bcmdhd/Makefile b/src/little/linux/drivers/net/wireless/bcmdhd/Makefile index a8fb30d68..9a1bc870e 100755 --- a/src/little/linux/drivers/net/wireless/bcmdhd/Makefile +++ b/src/little/linux/drivers/net/wireless/bcmdhd/Makefile @@ -27,7 +27,7 @@ CONFIG_BCMDHD_DEBUG := y #CONFIG_BCMDHD_ADAPTER_INDEX := 0 CONFIG_MACH_PLATFORM := y -#CONFIG_BCMDHD_DTS := y +CONFIG_BCMDHD_DTS := y DHDCFLAGS = -Wall -Wstrict-prototypes -Wno-date-time \ -Dlinux -DLINUX -DBCMDRIVER \ diff --git a/src/little/uboot/arch/riscv/dts/k230_canmv.dts b/src/little/uboot/arch/riscv/dts/k230_canmv.dts index 31f6ddefe..c4b098902 100755 --- a/src/little/uboot/arch/riscv/dts/k230_canmv.dts +++ b/src/little/uboot/arch/riscv/dts/k230_canmv.dts @@ -90,17 +90,17 @@ }; sdclk: virt_50mhz { - #clock-cells = <1>; - compatible = "fixed-clock"; - clock-frequency = <100000000>; + #clock-cells = <1>; + compatible = "fixed-clock"; + clock-frequency = <100000000>; u-boot,dm-pre-reloc; - }; + }; emmc: virt_200mhz { - #clock-cells = <1>; - compatible = "fixed-clock"; - clock-frequency = <200000000>; + #clock-cells = <1>; + compatible = "fixed-clock"; + clock-frequency = <200000000>; u-boot,dm-pre-reloc; - }; + }; serial0: serial@91400000 { compatible = "snps,dw-apb-uart"; @@ -221,48 +221,61 @@ u-boot,dm-pre-reloc; pinctrl-single,pins = < - // BOOT + // CAM0_RST (IO0 ) ( 0< OV5647 (IO13) ( 1< camera (IO40) ( 2< camera (IO41) ( 2< camera (IO44) ( 2< camera (IO45) ( 2< display (IO46) ( 3< display (IO47) ( 3< camera (IO48) ( 0< camera (IO49) ( 0< TFCARD (IO54) ( 2<; }; diff --git a/src/little/uboot/board/canaan/common/k230_spl.c b/src/little/uboot/board/canaan/common/k230_spl.c index d423a6d16..c2684b14f 100644 --- a/src/little/uboot/board/canaan/common/k230_spl.c +++ b/src/little/uboot/board/canaan/common/k230_spl.c @@ -116,6 +116,11 @@ static void device_disable(void) writel(value, 0x9110006c); } +__weak void quick_boot_board_init(void) +{ + /* Nothing to do! */ +} + //weak; int spl_board_init_f(void) { @@ -137,13 +142,7 @@ int spl_board_init_f(void) // /* load/boot image from boot device */ //if(quick_boot() == 1){//默认非快起; if(quick_boot()){//默认快起 - u32 usb0_otg_en_gpio52_dir = readl((void*)(GPIO_BASE_ADDR1 + 0x4)); - usb0_otg_en_gpio52_dir |= 1 << (52 - 32); - writel(usb0_otg_en_gpio52_dir, (void*)(GPIO_BASE_ADDR1 + 0x4)); - - u32 usb0_otg_en_gpio52_data = readl((void*)(GPIO_BASE_ADDR1 + 0x0)); - usb0_otg_en_gpio52_data |= 1 << (52 - 32); - writel(usb0_otg_en_gpio52_data, (void*)(GPIO_BASE_ADDR1 + 0x0)); + quick_boot_board_init(); //record_boot_time_info("ls"); ret += k230_img_load_boot_sys(BOOT_SYS_AUTO); diff --git a/src/little/uboot/board/canaan/k230_canmv/board.c b/src/little/uboot/board/canaan/k230_canmv/board.c index 9f99d1e86..59b75cf95 100644 --- a/src/little/uboot/board/canaan/k230_canmv/board.c +++ b/src/little/uboot/board/canaan/k230_canmv/board.c @@ -21,8 +21,28 @@ // #include "sdk_autoconf.h" // #include "k230_board_common.h" #include +#include sysctl_boot_mode_e sysctl_boot_get_boot_mode(void) { return SYSCTL_BOOT_SDIO1; -} \ No newline at end of file +} + +#ifdef CONFIG_BOARD_LATE_INIT +int board_late_init(void) +{ + u32 wifi_regon_gpio1_dir = readl((void*)(GPIO_BASE_ADDR0 + 0x4)); + wifi_regon_gpio1_dir |= 1 << 1; + writel(wifi_regon_gpio1_dir, (void*)(GPIO_BASE_ADDR0 + 0x4)); + + // reset gpio1 -> WIFI REGON + u32 wifi_regon_gpio1_data = readl((void*)(GPIO_BASE_ADDR0 + 0x0)); + wifi_regon_gpio1_data &= ~(1 << 1); + writel(wifi_regon_gpio1_data, (void*)(GPIO_BASE_ADDR0 + 0x0)); + mdelay(10); + // reset gpio1 -> WIFI REGON + wifi_regon_gpio1_data |= 1 << 1; + writel(wifi_regon_gpio1_data, (void*)(GPIO_BASE_ADDR0 + 0x0)); + return 0; +} +#endif diff --git a/src/little/uboot/board/canaan/k230_evb/board.c b/src/little/uboot/board/canaan/k230_evb/board.c index 47aab2dcc..1d6a8578c 100644 --- a/src/little/uboot/board/canaan/k230_evb/board.c +++ b/src/little/uboot/board/canaan/k230_evb/board.c @@ -52,4 +52,16 @@ int board_init(void) sd0_ctrl |= SD_HOST_REG_VOL_STABLE | SD_CARD_WRITE_PROT; writel(sd0_ctrl, (void*)SD0_CTRL); return 0; +} + +void quick_boot_board_init(void) +{ + u32 usb0_otg_en_gpio52_dir = readl((void*)(GPIO_BASE_ADDR1 + 0x4)); + usb0_otg_en_gpio52_dir |= 1 << (52 - 32); + writel(usb0_otg_en_gpio52_dir, (void*)(GPIO_BASE_ADDR1 + 0x4)); + + u32 usb0_otg_en_gpio52_data = readl((void*)(GPIO_BASE_ADDR1 + 0x0)); + usb0_otg_en_gpio52_data |= 1 << (52 - 32); + writel(usb0_otg_en_gpio52_data, (void*)(GPIO_BASE_ADDR1 + 0x0)); + return 0; } \ No newline at end of file diff --git a/src/little/uboot/configs/k230_canmv_defconfig b/src/little/uboot/configs/k230_canmv_defconfig index 14803a210..6e6c23f1b 100755 --- a/src/little/uboot/configs/k230_canmv_defconfig +++ b/src/little/uboot/configs/k230_canmv_defconfig @@ -17,7 +17,6 @@ CONFIG_SPL_SPI=y CONFIG_SYS_LOAD_ADDR=0xc000000 CONFIG_BUILD_TARGET="u-boot.bin" CONFIG_TARGET_K230_CANMV=y -CONFIG_CANMV_LPDDR3_2133=y CONFIG_ARCH_RV64I=y # CONFIG_SPL_SMP is not set CONFIG_SHOW_REGS=y @@ -37,6 +36,7 @@ CONFIG_SYS_STDIO_DEREGISTER=y CONFIG_DISPLAY_CPUINFO=y CONFIG_DISPLAY_BOARDINFO=y CONFIG_BOARD_EARLY_INIT_F=y +CONFIG_BOARD_LATE_INIT=y CONFIG_SPL_MAX_SIZE=0x80000 CONFIG_SPL_BSS_START_ADDR=0x80380000 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y @@ -72,6 +72,7 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_ENV_SECT_SIZE_AUTO=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_PROT_UDP=y +CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPL_DM_DEVICE_REMOVE=y CONFIG_SPL_CLK=y CONFIG_DM_KEYBOARD=y @@ -109,4 +110,3 @@ CONFIG_USB_ETHER_SMSC95XX=y CONFIG_FAT_WRITE=y CONFIG_SPL_GZIP=y # CONFIG_EFI_LOADER is not set -CONFIG_NET_RANDOM_ETHADDR=y \ No newline at end of file diff --git a/src/reference/ai_poc/CMakeLists.txt b/src/reference/ai_poc/CMakeLists.txt index 4fcb28317..54fe8d801 100644 --- a/src/reference/ai_poc/CMakeLists.txt +++ b/src/reference/ai_poc/CMakeLists.txt @@ -56,4 +56,11 @@ add_subdirectory(puzzle_game) add_subdirectory(dynamic_gesture) add_subdirectory(ocr) add_subdirectory(yolop_lane_seg) -add_subdirectory(anomaly_det) \ No newline at end of file +add_subdirectory(anomaly_det) +add_subdirectory(face_alignment) +add_subdirectory(face_mesh) +add_subdirectory(translate_en_ch) +add_subdirectory(self_learning) +add_subdirectory(crosswalk_detect) +add_subdirectory(virtual_keyboard) +add_subdirectory(sq_handkp_flower) diff --git a/src/reference/ai_poc/build_app.sh b/src/reference/ai_poc/build_app.sh index e8ca756d6..6e9995356 100755 --- a/src/reference/ai_poc/build_app.sh +++ b/src/reference/ai_poc/build_app.sh @@ -27,6 +27,7 @@ cp -a ../../big/kmodel/ai_poc/utils/* ${k230_bin} cp -a shell/* ${k230_bin} /opt/toolchain/Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.0/bin/riscv64-unknown-linux-gnu-g++ -O3 llamac/llama_run.cc -o out/llama_run -lm +/opt/toolchain/Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.0/bin/riscv64-unknown-linux-gnu-g++ -O3 self_learning_small/main.cc -o out/create_category -lm if [ -f out/bin/face_detection.elf ]; then cp out/bin/face_detection.elf ${k230_bin} @@ -184,4 +185,36 @@ if [ -f out/bin/anomaly_det.elf ]; then cp out/bin/anomaly_det.elf ${k230_bin} fi +if [ -f out/bin/face_mesh.elf ]; then + cp out/bin/face_mesh.elf ${k230_bin} +fi + +if [ -f out/bin/face_alignment.elf ]; then + cp out/bin/face_alignment.elf ${k230_bin} +fi + +if [ -f out/bin/translate_en_ch.elf ]; then + cp out/bin/translate_en_ch.elf ${k230_bin} +fi + +if [ -f out/create_category ]; then + cp out/create_category ${k230_bin} +fi + +if [ -f out/bin/self_learning.elf ]; then + cp out/bin/self_learning.elf ${k230_bin} +fi + +if [ -f out/bin/crosswalk_detect.elf ]; then + cp out/bin/crosswalk_detect.elf ${k230_bin} +fi + +if [ -f out/bin/virtual_keyboard.elf ]; then + cp out/bin/virtual_keyboard.elf ${k230_bin} +fi + +if [ -f out/bin/sq_handkp_flower.elf ]; then + cp out/bin/sq_handkp_flower.elf ${k230_bin} +fi + rm -rf out diff --git a/src/reference/ai_poc/crosswalk_detect/CMakeLists.txt b/src/reference/ai_poc/crosswalk_detect/CMakeLists.txt new file mode 100644 index 000000000..9323d3b30 --- /dev/null +++ b/src/reference/ai_poc/crosswalk_detect/CMakeLists.txt @@ -0,0 +1,18 @@ +set(src main.cc utils.cc ai_base.cc crosswalk_detect.cc ) +set(bin crosswalk_detect.elf) + +include_directories(${PROJECT_SOURCE_DIR}) +include_directories(${nncase_sdk_root}/riscv64/rvvlib/include) +include_directories(${k230_sdk}/src/big/mpp/userapps/api/) +include_directories(${k230_sdk}/src/big/mpp/include) +include_directories(${k230_sdk}/src/big/mpp/include/comm) +include_directories(${k230_sdk}/src/big/mpp/userapps/sample/sample_vo) +link_directories(${nncase_sdk_root}/riscv64/rvvlib/) + +add_executable(${bin} ${src}) +target_link_libraries(${bin} -Wl,--start-group rvv Nncase.Runtime.Native nncase.rt_modules.k230 functional_k230 sys vicap vb cam_device cam_engine + hal oslayer ebase fpga isp_drv binder auto_ctrol common cam_caldb isi 3a buffer_management cameric_drv video_in virtual_hal start_engine cmd_buffer + switch cameric_reg_drv t_database_c t_mxml_c t_json_c t_common_c vo connector sensor atomic dma -Wl,--end-group) + +target_link_libraries(${bin} opencv_imgcodecs opencv_imgproc opencv_core zlib libjpeg-turbo libopenjp2 libpng libtiff libwebp csi_cv) +install(TARGETS ${bin} DESTINATION bin) \ No newline at end of file diff --git a/src/reference/ai_poc/crosswalk_detect/README.md b/src/reference/ai_poc/crosswalk_detect/README.md new file mode 100644 index 000000000..923cd6cd3 --- /dev/null +++ b/src/reference/ai_poc/crosswalk_detect/README.md @@ -0,0 +1,24 @@ +# 1.简介 + +人行横道检测是一种环境感知应用,其目的是通过车载相机或激光雷达来检测人行横道。近年来,随着计算机视觉的应用发展和落地,人行横道检测也获得了广泛关注,出现一系列的人行横道检测方法。人行横道检测在自动驾驶系统中扮演着重要的角色,特别是在高级辅助驾驶系统(ADAS)中,可以为驾驶系统提供决策依据。 + +本应用采用了yolov5网络结构。使用该应用,可检测到图像或视频中是否有人行横道。 + +# 2.应用使用说明 + +## 2.1 使用帮助 + +``` + Usage: ./crosswalk_detect.elf +For example: + [for img] ./crosswalk_detect.elf crosswalk.kmodel 0.5 0.45 cw.jpg 0 + [for isp] ./crosswalk_detect.elf crosswalk.kmodel 0.5 0.45 None 0 +Options: + 1> kmodel 人行横道检测kmodel文件路径 + 2> cw_thresh 人行横道检测阈值 + 3> nms_thresh NMS阈值 + 4> input_mode 本地图片(图片路径)/ 摄像头(None) + 5> debug_mode 是否需要调试,0、1、2分别表示不调试、简单调试、详细调试 +``` + +人行横道检测效果图 \ No newline at end of file diff --git a/src/reference/ai_poc/crosswalk_detect/ai_base.cc b/src/reference/ai_poc/crosswalk_detect/ai_base.cc new file mode 100644 index 000000000..6ecbdd59d --- /dev/null +++ b/src/reference/ai_poc/crosswalk_detect/ai_base.cc @@ -0,0 +1,191 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "ai_base.h" + +#include +#include + +#include "utils.h" + +using std::cout; +using std::endl; +using namespace nncase; +using namespace nncase::runtime::detail; + +AIBase::AIBase(const char *kmodel_file,const string model_name, const int debug_mode) : debug_mode_(debug_mode),model_name_(model_name) +{ + if (debug_mode > 1) + cout << "kmodel_file:" << kmodel_file << endl; + // kmodel_vec_ = Utils::read_binary_file(kmodel_file); + // kmodel_interp_.load_model({(const gsl::byte *)kmodel_vec_.data(), kmodel_vec_.size()}).expect("cannot load kmodel."); + + std::ifstream ifs(kmodel_file, std::ios::binary); + kmodel_interp_.load_model(ifs).expect("Invalid kmodel"); + + set_input_init(); + set_output_init(); +} + +AIBase::~AIBase() +{ +} + +void AIBase::set_input_init() +{ + ScopedTiming st(model_name_ + " set_input init", debug_mode_); + int input_total_size = 0; + each_input_size_by_byte_.push_back(0); // 先补0,为之后做准备 + for (int i = 0; i < kmodel_interp_.inputs_size(); ++i) + { + auto desc = kmodel_interp_.input_desc(i); + auto shape = kmodel_interp_.input_shape(i); + auto tensor = host_runtime_tensor::create(desc.datatype, shape, hrt::pool_shared).expect("cannot create input tensor"); + kmodel_interp_.input_tensor(i, tensor).expect("cannot set input tensor"); + vector in_shape = {shape[0], shape[1], shape[2], shape[3]}; + input_shapes_.push_back(in_shape); + int dsize = shape[0] * shape[1] * shape[2] * shape[3]; + if (debug_mode_ > 1) + cout << "input shape:" << shape[0] << " " << shape[1] << " " << shape[2] << " " << shape[3] << endl; + // DEFINE_TYPECODE(uint8, u8, 0x06) + // DEFINE_TYPECODE(float32, f32, 0x0B) + if (desc.datatype == 0x06) + { + input_total_size += dsize; + each_input_size_by_byte_.push_back(input_total_size); + } + else if (desc.datatype == 0x0B) + { + input_total_size += (dsize * 4); + each_input_size_by_byte_.push_back(input_total_size); + } + else + assert(("kmodel input data type supports only uint8, float32", 0)); + } + each_input_size_by_byte_.push_back(input_total_size); // 最后一个保存总大小 +} + +void AIBase::set_input(const unsigned char *buf, size_t size) +{ + if (*each_input_size_by_byte_.rbegin() != size) + cout << "set_input:the actual input size{" + std::to_string(size) + "} is different from the model's required input size{" + std::to_string(*each_input_size_by_byte_.rbegin()) + "}" << endl; + assert((*each_input_size_by_byte_.rbegin() == size)); + + ScopedTiming st(model_name_ + " set_input", debug_mode_); + for (size_t i = 0; i < kmodel_interp_.inputs_size(); ++i) + { + auto desc = kmodel_interp_.input_desc(i); + auto shape = kmodel_interp_.input_shape(i); + auto tensor = host_runtime_tensor::create(desc.datatype, shape, hrt::pool_shared).expect("cannot create input tensor"); + auto mapped_buf = std::move(hrt::map(tensor, map_access_::map_write).unwrap()); // mapped_buf实际是有缓存数据的 + memcpy(reinterpret_cast(mapped_buf.buffer().data()), buf, each_input_size_by_byte_[i + 1] - each_input_size_by_byte_[i]); + auto ret = mapped_buf.unmap(); + ret = hrt::sync(tensor, sync_op_t::sync_write_back, true); + if (!ret.is_ok()) + { + std::cerr << "hrt::sync failed" << std::endl; + std::abort(); + } + kmodel_interp_.input_tensor(i, tensor).expect("cannot set input tensor"); + } +} + +runtime_tensor AIBase::get_input_tensor(size_t idx) +{ + return kmodel_interp_.input_tensor(idx).expect("cannot get input tensor"); +} + +void AIBase::set_input_tensor(size_t idx, runtime_tensor &tensor) +{ + ScopedTiming st(model_name_ + " set_input_tensor", debug_mode_); + kmodel_interp_.input_tensor(idx, tensor).expect("cannot set input tensor"); +} + +void AIBase::set_output_init() +{ + ScopedTiming st(model_name_ + " set_output_init", debug_mode_); + each_output_size_by_byte_.clear(); + int output_total_size = 0; + each_output_size_by_byte_.push_back(0); + for (size_t i = 0; i < kmodel_interp_.outputs_size(); i++) + { + auto desc = kmodel_interp_.output_desc(i); + auto shape = kmodel_interp_.output_shape(i); + vector out_shape; + int dsize = 1; + for (int j = 0; j < shape.size(); ++j) + { + out_shape.push_back(shape[j]); + dsize *= shape[j]; + if (debug_mode_ > 1) + cout << shape[j] << ","; + } + if (debug_mode_ > 1) + cout << endl; + output_shapes_.push_back(out_shape); + // DEFINE_TYPECODE(float32, f32, 0x0B) + if (desc.datatype == 0x0B) + { + output_total_size += (dsize * 4); + each_output_size_by_byte_.push_back(output_total_size); + } + else + assert(("kmodel output data type supports only float32", 0)); + auto tensor = host_runtime_tensor::create(desc.datatype, shape, hrt::pool_shared).expect("cannot create output tensor"); + kmodel_interp_.output_tensor(i, tensor).expect("cannot set output tensor"); + } +} + +void AIBase::set_output() +{ + ScopedTiming st(model_name_ + " set_output", debug_mode_); + for (size_t i = 0; i < kmodel_interp_.outputs_size(); i++) + { + auto desc = kmodel_interp_.output_desc(i); + auto shape = kmodel_interp_.output_shape(i); + auto tensor = host_runtime_tensor::create(desc.datatype, shape, hrt::pool_shared).expect("cannot create output tensor"); + kmodel_interp_.output_tensor(i, tensor).expect("cannot set output tensor"); + } +} + +void AIBase::run() +{ + ScopedTiming st(model_name_ + " run", debug_mode_); + kmodel_interp_.run().expect("error occurred in running model"); +} + +void AIBase::get_output() +{ + ScopedTiming st(model_name_ + " get_output", debug_mode_); + p_outputs_.clear(); + for (int i = 0; i < kmodel_interp_.outputs_size(); i++) + { + auto out = kmodel_interp_.output_tensor(i).expect("cannot get output tensor"); + // auto mapped_buf = std::move(hrt::map(out, map_access_::map_read).unwrap()); + // float *p_out = reinterpret_cast(mapped_buf.buffer().data()); + auto buf = out.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_read).unwrap().buffer(); + float *p_out = reinterpret_cast(buf.data()); + p_outputs_.push_back(p_out); + } +} diff --git a/src/reference/ai_poc/crosswalk_detect/ai_base.h b/src/reference/ai_poc/crosswalk_detect/ai_base.h new file mode 100644 index 000000000..9fd4470cc --- /dev/null +++ b/src/reference/ai_poc/crosswalk_detect/ai_base.h @@ -0,0 +1,120 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +// ai_base.h +#ifndef AI_BASE_H +#define AI_BASE_H + +#include +#include +#include + +#include +#include "scoped_timing.hpp" + +using std::string; +using std::vector; +using namespace nncase::runtime; + +/** + * @brief AI基类,封装nncase相关操作 + * 主要封装了nncase的加载、设置输入、运行、获取输出操作,后续开发demo只需要关注模型的前处理、后处理即可 + */ +class AIBase +{ +public: + /** + * @brief AI基类构造函数,加载kmodel,并初始化kmodel输入、输出 + * @param kmodel_file kmodel文件路径 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + AIBase(const char *kmodel_file,const string model_name, const int debug_mode = 1); + + /** + * @brief AI基类析构函数 + * @return None + */ + ~AIBase(); + + /** + * @brief 设置kmodel输入 + * @param buf 输入数据指针 + * @param size 输入数据大小 + * @return None + */ + void set_input(const unsigned char *buf, size_t size); + + /** + * @brief 根据索引获取kmodel输入tensor + * @param idx 输入数据指针 + * @return None + */ + runtime_tensor get_input_tensor(size_t idx); + + void set_input_tensor(size_t idx, runtime_tensor &tensor); + + /** + * @brief 初始化kmodel输出 + * @return None + */ + void set_output(); + + /** + * @brief 推理kmodel + * @return None + */ + void run(); + + /** + * @brief 获取kmodel输出,结果保存在对应的类属性中 + * @return None + */ + void get_output(); + +protected: + string model_name_; // 模型名字 + int debug_mode_; // 调试模型,0(不打印),1(打印时间),2(打印所有) + vector p_outputs_; // kmodel输出对应的指针列表 + vector> input_shapes_; //{{N,C,H,W},{N,C,H,W}...} + vector> output_shapes_; //{{N,C,H,W},{N,C,H,W}...}} 或 {{N,C},{N,C}...}}等 + vector each_input_size_by_byte_; //{0,layer1_length,layer1_length+layer2_length,...} + vector each_output_size_by_byte_; //{0,layer1_length,layer1_length+layer2_length,...} +private: + /** + * @brief 首次初始化kmodel输入,并获取输入shape + * @return None + */ + void set_input_init(); + + /** + * @brief 首次初始化kmodel输出,并获取输出shape + * @return None + */ + void set_output_init(); + + interpreter kmodel_interp_; // kmodel解释器,从kmodel文件构建,负责模型的加载、输入输出设置和推理 + vector kmodel_vec_; // 通过读取kmodel文件得到整个kmodel数据,用于传给kmodel解释器加载kmodel +}; +#endif \ No newline at end of file diff --git a/src/reference/ai_poc/crosswalk_detect/crosswalk_detect.cc b/src/reference/ai_poc/crosswalk_detect/crosswalk_detect.cc new file mode 100644 index 000000000..7d937a5b2 --- /dev/null +++ b/src/reference/ai_poc/crosswalk_detect/crosswalk_detect.cc @@ -0,0 +1,229 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.f + */ + +#include "crosswalk_detect.h" +// #include "utils.h" + + +// for image +crosswalkDetect::crosswalkDetect(const char *kmodel_file, float obj_thresh,float nms_thresh, const int debug_mode) +: obj_thresh_(obj_thresh),nms_thresh_(nms_thresh), AIBase(kmodel_file,"crosswalkDetect", debug_mode) +{ + + model_name_ = "crosswalkDetect"; + + ai2d_out_tensor_ = get_input_tensor(0); +} + +// for video +crosswalkDetect::crosswalkDetect(const char *kmodel_file, float obj_thresh,float nms_thresh, FrameCHWSize isp_shape, uintptr_t vaddr, uintptr_t paddr, const int debug_mode) +: obj_thresh_(obj_thresh),nms_thresh_(nms_thresh), AIBase(kmodel_file,"smokeDetect", debug_mode) +{ + model_name_ = "crosswalkDetect"; + + vaddr_ = vaddr; + + isp_shape_ = isp_shape; + dims_t in_shape{1, isp_shape_.channel, isp_shape_.height, isp_shape_.width}; + int isp_size = isp_shape_.channel * isp_shape_.height * isp_shape_.width; + #if 0 + ai2d_in_tensor_ = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, { (gsl::byte *)vaddr, isp_size }, + true, hrt::pool_shared).expect("cannot create input tensor"); + #else + ai2d_in_tensor_ = hrt::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("create ai2d input tensor failed"); + #endif + + // ai2d_out_tensor + ai2d_out_tensor_ = get_input_tensor(0); + // fixed padding resize param + Utils::padding_resize(isp_shape_, {input_shapes_[0][3], input_shapes_[0][2]}, ai2d_builder_, ai2d_in_tensor_, ai2d_out_tensor_, cv::Scalar(114, 114, 114)); +} + +crosswalkDetect::~crosswalkDetect() +{ + +} + +// ai2d for image +void crosswalkDetect::pre_process(cv::Mat ori_img) +{ + ScopedTiming st(model_name_ + " pre_process image", debug_mode_); + std::vector chw_vec; + Utils::hwc_to_chw(ori_img, chw_vec); + Utils::padding_resize({ori_img.channels(), ori_img.rows, ori_img.cols}, chw_vec, {input_shapes_[0][3], input_shapes_[0][2]}, ai2d_out_tensor_, cv::Scalar(114, 114, 114)); +} + +// ai2d for video +void crosswalkDetect::pre_process() +{ + ScopedTiming st(model_name_ + " pre_process video", debug_mode_); + #if 0 + ai2d_builder_->invoke().expect("error occurred in ai2d running"); + #else + size_t isp_size = isp_shape_.channel * isp_shape_.height * isp_shape_.width; + auto buf = ai2d_in_tensor_.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(buf.data()), (void *)vaddr_, isp_size); + hrt::sync(ai2d_in_tensor_, sync_op_t::sync_write_back, true).expect("sync write_back failed"); + //ai2d_builder_->invoke().expect("error occurred in ai2d running"); + ai2d_builder_->invoke(ai2d_in_tensor_,ai2d_out_tensor_).expect("error occurred in ai2d running"); + #endif +} + +void crosswalkDetect::inference() +{ + this->run(); + this->get_output(); +} + +static float sigmoid(float x) +{ + return 1.0f / (1.0f + expf(-x)); +} + +void crosswalkDetect::post_process(FrameSize frame_size,std::vector &result) +{ + ScopedTiming st(model_name_ + " post_process", debug_mode_); + int net_len = input_shapes_[0][2]; + // first output + { + + float *output_0 = p_outputs_[0]; + + auto boxes0 = decode_infer(output_0, net_len, 8, classes_num_, frame_size, anchors_0_, obj_thresh_); + result.insert(result.begin(), boxes0.begin(), boxes0.end()); + } + + // second output + { + + float *output_1 = p_outputs_[1]; + + auto boxes1 = decode_infer(output_1, net_len, 16, classes_num_, frame_size, anchors_1_, obj_thresh_); + result.insert(result.begin(), boxes1.begin(), boxes1.end()); + } + + // third output + { + float *output_2 = p_outputs_[2]; + + auto boxes2 = decode_infer(output_2, net_len, 32, classes_num_, frame_size, anchors_2_, obj_thresh_); + result.insert(result.begin(), boxes2.begin(), boxes2.end()); + } + + nms(result, nms_thresh_); +} + + +// for NHWC +std::vector crosswalkDetect::decode_infer(float *data, int net_size, int stride, int num_classes, FrameSize frame_size, float anchors[][2], float threshold) +{ + float ratiow = (float)net_size / frame_size.width; + float ratioh = (float)net_size / frame_size.height; + float gain = ratiow < ratioh ? ratiow : ratioh; + std::vector result; + int grid_size = net_size / stride; + int one_rsize = num_classes + 5; + float cx, cy, w, h; + for (int shift_y = 0; shift_y < grid_size; shift_y++) + { + for (int shift_x = 0; shift_x < grid_size; shift_x++) + { + int loc = shift_x + shift_y * grid_size; + for (int i = 0; i < 3; i++) + { + float *record = data + (loc * 3 + i) * one_rsize; + float *cls_ptr = record + 5; + for (int cls = 0; cls < num_classes; cls++) + { + // float score = sigmoid(cls_ptr[cls]) * sigmoid(record[4]); + float score = cls_ptr[cls] * record[4]; + if (score > threshold) + { + // cx = (sigmoid(record[0]) * 2.f - 0.5f + (float)shift_x) * (float)stride; + // cy = (sigmoid(record[1]) * 2.f - 0.5f + (float)shift_y) * (float)stride; + // w = pow(sigmoid(record[2]) * 2.f, 2) * anchors[i][0]; + // h = pow(sigmoid(record[3]) * 2.f, 2) * anchors[i][1]; + + cx = (record[0] * 2.f - 0.5f + (float)shift_x) * (float)stride; + cy = (record[1] * 2.f - 0.5f + (float)shift_y) * (float)stride; + w = pow(record[2] * 2.f, 2) * anchors[i][0]; + h = pow(record[3] * 2.f, 2) * anchors[i][1]; + + cx -= ((net_size - frame_size.width * gain) / 2); + cy -= ((net_size - frame_size.height * gain) / 2); + cx /= gain; + cy /= gain; + w /= gain; + h /= gain; + BoxInfo box; + box.x1 = std::max(0, std::min(frame_size.width, int(cx - w / 2.f))); + box.y1 = std::max(0, std::min(frame_size.height, int(cy - h / 2.f))); + box.x2 = std::max(0, std::min(frame_size.width, int(cx + w / 2.f))); + box.y2 = std::max(0, std::min(frame_size.height, int(cy + h / 2.f))); + box.score = score; + box.label = cls; + result.push_back(box); + } + } + } + } + } + return result; +} + + +void crosswalkDetect::nms(std::vector &input_boxes, float NMS_THRESH) +{ + std::sort(input_boxes.begin(), input_boxes.end(), [](BoxInfo a, BoxInfo b) { return a.score > b.score; }); + std::vector vArea(input_boxes.size()); + for (int i = 0; i < int(input_boxes.size()); ++i) + { + vArea[i] = (input_boxes.at(i).x2 - input_boxes.at(i).x1 + 1) + * (input_boxes.at(i).y2 - input_boxes.at(i).y1 + 1); + } + for (int i = 0; i < int(input_boxes.size()); ++i) + { + for (int j = i + 1; j < int(input_boxes.size());) + { + float xx1 = std::max(input_boxes[i].x1, input_boxes[j].x1); + float yy1 = std::max(input_boxes[i].y1, input_boxes[j].y1); + float xx2 = std::min(input_boxes[i].x2, input_boxes[j].x2); + float yy2 = std::min(input_boxes[i].y2, input_boxes[j].y2); + float w = std::max(float(0), xx2 - xx1 + 1); + float h = std::max(float(0), yy2 - yy1 + 1); + float inter = w * h; + float ovr = inter / (vArea[i] + vArea[j] - inter); + if (ovr >= NMS_THRESH) + { + input_boxes.erase(input_boxes.begin() + j); + vArea.erase(vArea.begin() + j); + } + else + { + j++; + } + } + } +} \ No newline at end of file diff --git a/src/reference/ai_poc/crosswalk_detect/crosswalk_detect.h b/src/reference/ai_poc/crosswalk_detect/crosswalk_detect.h new file mode 100644 index 000000000..69ac20bfa --- /dev/null +++ b/src/reference/ai_poc/crosswalk_detect/crosswalk_detect.h @@ -0,0 +1,140 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _CROSSWALK_DETECT +#define _CROSSWALK_DETECT + +#include +#include +#include "utils.h" +#include "ai_base.h" + + +/** + * @brief crosswalkDetect 人行横道检测 + * 主要封装了对于每一帧图片,从预处理、运行到后处理给出结果的过程 + */ +class crosswalkDetect: public AIBase +{ + public: + + /** + * for image + * @brief crosswalkDetect 构造函数,加载kmodel,并初始化kmodel输入、输出、类阈值和NMS阈值 + * @param kmodel_file kmodel文件路径 + * @param obj_thresh 检测框阈值 + * @param nms_thresh NMS阈值 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + crosswalkDetect(const char *kmodel_file, float obj_thresh,float nms_thresh, const int debug_mode); + + /** + * for video + * @brief crosswalkDetect 构造函数,加载kmodel,并初始化kmodel输入、输出、类阈值和NMS阈值 + * @param kmodel_file kmodel文件路径 + * @param obj_thresh 检测框阈值 + * @param nms_thresh NMS阈值 + * @param isp_shape isp输入大小(chw) + * @param vaddr isp对应虚拟地址 + * @param paddr isp对应物理地址 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + crosswalkDetect(const char *kmodel_file, float obj_thresh,float nms_thresh, FrameCHWSize isp_shape, uintptr_t vaddr, uintptr_t paddr, const int debug_mode); + /** + * @brief crosswalkDetect 析构函数 + * @return None + */ + ~crosswalkDetect(); + + /** + * @brief 图片预处理(ai2d for image) + * @param ori_img 原始图片 + * @return None + */ + void pre_process(cv::Mat ori_img); + + /** + * @brief 视频流预处理(ai2d for video) + * @return None + */ + void pre_process(); + + /** + * @brief kmodel推理 + * @return None + */ + void inference(); + + /** + * @brief postprocess 函数,对输出解码后的结果,进行NMS处理 + * @param frame_size 帧大小 + * @param result 所有候选检测框 + * @return None + */ + void post_process(FrameSize frame_size,std::vector &result); + + /** + * @brief 解码 + * @data kmodel 推理结果 + * @net_size kmodel 输入尺寸大小 + * @stride 步长 + * @num_classes 类别数 + * @frame_size 分辨率 + * @anchors 锚框 + * @threshold 检测框阈值 + **/ + std::vector decode_infer(float *data, int net_size, int stride, int num_classes, FrameSize frame_size, float anchors[][2], float threshold); + + /** + * @brief 非极大值抑制 + * @input_boxes 所有候选框 + * @NMS_THRESH NMS阈值 + * @return None + **/ + void nms(std::vector &input_boxes, float NMS_THRESH); + + std::vector labels { "crosswalk","None" }; + + private: + float obj_thresh_; // 检测框阈值 + float nms_thresh_; // NMS阈值 + + int anchors_num_ = 3; // 锚框个数 + int classes_num_ = 2; // 类别数 + int channels_ = anchors_num_ * (5 + classes_num_); // 通道数 + float anchors_0_[3][2] = { { 105,16 }, { 227,18 }, { 359,31 } }; // 第一组锚框 + float anchors_1_[3][2] = { { 319,71}, { 432,53}, { 536,68} }; // 第二组锚框 + float anchors_2_[3][2] = { { 468,109 }, { 556,92 }, { 641,121 } }; // 第三组锚框 + + std::unique_ptr ai2d_builder_; // ai2d构建器 + runtime_tensor ai2d_in_tensor_; // ai2d输入tensor + runtime_tensor ai2d_out_tensor_; // ai2d输出tensor + uintptr_t vaddr_; // isp的虚拟地址 + FrameCHWSize isp_shape_; // isp对应的地址大小 + +}; +#endif diff --git a/src/reference/ai_poc/crosswalk_detect/main.cc b/src/reference/ai_poc/crosswalk_detect/main.cc new file mode 100644 index 000000000..a4cae9b99 --- /dev/null +++ b/src/reference/ai_poc/crosswalk_detect/main.cc @@ -0,0 +1,227 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "utils.h" +#include "vi_vo.h" +#include "crosswalk_detect.h" + +using std::cerr; +using std::cout; +using std::endl; + +std::atomic isp_stop(false); + + +void print_usage(const char *name) +{ + cout << "Usage: " << name << " " << endl + << "For example: " << endl + << " [for img] ./crosswalk_detect.elf crosswalk.kmodel 0.5 0.45 cw.jpg 0" << endl + << " [for isp] ./crosswalk_detect.elf crosswalk.kmodel 0.5 0.45 None 0" << endl + << "Options:" << endl + << " 1> kmodel 人行横道检测kmodel文件路径 \n" + << " 2> cw_thresh 人行横道检测阈值\n" + << " 3> nms_thresh NMS阈值\n" + << " 4> input_mode 本地图片(图片路径)/ 摄像头(None) \n" + << " 5> debug_mode 是否需要调试,0、1、2分别表示不调试、简单调试、详细调试\n" + << "\n" + << endl; +} + +void video_proc(char *argv[]) +{ + vivcap_start(); + + k_video_frame_info vf_info; + void *pic_vaddr = NULL; //osd + + memset(&vf_info, 0, sizeof(vf_info)); + + vf_info.v_frame.width = osd_width; + vf_info.v_frame.height = osd_height; + vf_info.v_frame.stride[0] = osd_width; + vf_info.v_frame.pixel_format = PIXEL_FORMAT_ARGB_8888; + block = vo_insert_frame(&vf_info, &pic_vaddr); + + // alloc memory + size_t paddr = 0; + void *vaddr = nullptr; + size_t size = SENSOR_CHANNEL * SENSOR_HEIGHT * SENSOR_WIDTH; + int ret = kd_mpi_sys_mmz_alloc_cached(&paddr, &vaddr, "allocate", "anonymous", size); + if (ret) + { + std::cerr << "physical_memory_block::allocate failed: ret = " << ret << ", errno = " << strerror(errno) << std::endl; + std::abort(); + } + + crosswalkDetect cw(argv[1], atof(argv[2]),atof(argv[3]), {SENSOR_CHANNEL, SENSOR_HEIGHT, SENSOR_WIDTH}, reinterpret_cast(vaddr), reinterpret_cast(paddr), atoi(argv[5])); + + vector results; + + while (!isp_stop) + { + ScopedTiming st("total time", 1); + + { + ScopedTiming st("read capture", atoi(argv[5])); + // VICAP_CHN_ID_1 out rgb888p + memset(&dump_info, 0 , sizeof(k_video_frame_info)); + ret = kd_mpi_vicap_dump_frame(vicap_dev, VICAP_CHN_ID_1, VICAP_DUMP_YUV, &dump_info, 1000); + if (ret) { + printf("sample_vicap...kd_mpi_vicap_dump_frame failed.\n"); + continue; + } + } + + + { + ScopedTiming st("isp copy", atoi(argv[5])); + // 从vivcap中读取一帧图像到dump_info + auto vbvaddr = kd_mpi_sys_mmap_cached(dump_info.v_frame.phys_addr[0], size); + memcpy(vaddr, (void *)vbvaddr, SENSOR_HEIGHT * SENSOR_WIDTH * 3); // 这里以后可以去掉,不用copy + kd_mpi_sys_munmap(vbvaddr, size); + } + + results.clear(); + + cw.pre_process(); + cw.inference(); + cw.post_process({SENSOR_WIDTH, SENSOR_HEIGHT}, results); + + cv::Mat osd_frame(osd_height, osd_width, CV_8UC4, cv::Scalar(0, 0, 0, 0)); + + std::string text; + cv::Point origin; + std::vector scalars= { + cv::Scalar(255,0, 0, 255), // "crosswalk" + cv::Scalar(255,0, 255, 0), // "None" + cv::Scalar(255,255,0, 0), + cv::Scalar(255,255,0, 255) + }; + + for (auto r : results) + { + ScopedTiming st("draw boxes", atoi(argv[5])); + text = cw.labels[r.label] + ":" + std::to_string(round(r.score * 100) / 100).substr(0,4); + + int x1 = r.x1 / SENSOR_WIDTH * osd_width; + int y1 = r.y1 / SENSOR_HEIGHT * osd_height; + + origin.x = x1; + origin.y = y1-20; + + int w = (r.x2-r.x1) / SENSOR_WIDTH * osd_width; + int h = (r.y2-r.y1) / SENSOR_HEIGHT * osd_height; + + cv::rectangle(osd_frame, cv::Rect( x1,y1,w,h ), cv::Scalar(255, 255,0, 0), 6, 2, 0); // ARGB + cv::putText(osd_frame, text, origin, cv::FONT_HERSHEY_COMPLEX, 2, scalars[r.label+2], 1, 8, 0); + + } + + { + ScopedTiming st("osd copy", atoi(argv[5])); + memcpy(pic_vaddr, osd_frame.data, osd_width * osd_height * 4); + //显示通道插入帧 + kd_mpi_vo_chn_insert_frame(osd_id+3, &vf_info); //K_VO_OSD0 + // printf("kd_mpi_vo_chn_insert_frame success \n"); + + ret = kd_mpi_vicap_dump_release(vicap_dev, VICAP_CHN_ID_1, &dump_info); + if (ret) { + printf("sample_vicap...kd_mpi_vicap_dump_release failed.\n"); + } + } + } + + vo_osd_release_block(); + vivcap_stop(); + + + // free memory + ret = kd_mpi_sys_mmz_free(paddr, vaddr); + if (ret) + { + std::cerr << "free failed: ret = " << ret << ", errno = " << strerror(errno) << std::endl; + std::abort(); + } + +} + + +int main(int argc, char *argv[]) +{ + std::cout << "case " << argv[0] << " built at " << __DATE__ << " " << __TIME__ << std::endl; + if (argc != 6) + { + print_usage(argv[0]); + return -1; + } + + if (strcmp(argv[4], "None") == 0) + { + std::thread thread_isp(video_proc, argv); + while (getchar() != 'q') + { + usleep(10000); + } + + isp_stop = true; + thread_isp.join(); + } + else + { + cv::Mat ori_img = cv::imread(argv[4]); + int ori_w = ori_img.cols; + int ori_h = ori_img.rows; + + crosswalkDetect cw(argv[1], atof(argv[2]),atof(argv[3]), atoi(argv[5])); + + cw.pre_process(ori_img); + + cw.inference(); + + vector results; + cw.post_process({ori_w, ori_h}, results); + + cv::Point origin; + for (auto r : results) + { + ScopedTiming st("draw boxes", atoi(argv[5])); + + std::string text = cw.labels[r.label] + ":" + std::to_string(round(r.score * 100) / 100).substr(0,4); + // std::cout << "text = " << text << std::endl; + cv::rectangle(ori_img, cv::Rect(r.x1, r.y1, r.x2 - r.x1 + 1, r.y2 - r.y1 + 1), cv::Scalar(0, 0, 255), 6, 2, 0); + + origin.x = r.x1; + origin.y = r.y1 - 20; + + cv::putText(ori_img, text, origin, cv::FONT_HERSHEY_COMPLEX, 0.5, cv::Scalar(0, 255, 255), 1, 8, 0); + } + + cv::imwrite("crosswalk_res.jpg", ori_img); + } + return 0; +} \ No newline at end of file diff --git a/src/reference/ai_poc/crosswalk_detect/scoped_timing.hpp b/src/reference/ai_poc/crosswalk_detect/scoped_timing.hpp new file mode 100644 index 000000000..874ff1b17 --- /dev/null +++ b/src/reference/ai_poc/crosswalk_detect/scoped_timing.hpp @@ -0,0 +1,70 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include + +/** + * @brief 计时类 + * 统计在该类实例生命周期内的耗时 + */ +class ScopedTiming +{ +public: + /** + * @brief ScopedTiming构造函数,初始化计时对象名称并开始计时 + * @param info 计时对象名称 + * @param enable_profile 是否开始计时 + * @return None + */ + ScopedTiming(std::string info = "ScopedTiming", int enable_profile = 1) + : m_info(info), enable_profile(enable_profile) + { + if (enable_profile) + { + m_start = std::chrono::steady_clock::now(); + } + } + + /** + * @brief ScopedTiming析构,结束计时,并打印耗时 + * @return None + */ + ~ScopedTiming() + { + if (enable_profile) + { + m_stop = std::chrono::steady_clock::now(); + double elapsed_ms = std::chrono::duration(m_stop - m_start).count(); + std::cout << m_info << " took " << elapsed_ms << " ms" << std::endl; + } + } + +private: + int enable_profile; // 是否统计时间 + std::string m_info; // 计时对象名称 + std::chrono::steady_clock::time_point m_start; // 计时开始时间 + std::chrono::steady_clock::time_point m_stop; // 计时结束时间 +}; \ No newline at end of file diff --git a/src/reference/ai_poc/crosswalk_detect/utils.cc b/src/reference/ai_poc/crosswalk_detect/utils.cc new file mode 100644 index 000000000..4e34553e0 --- /dev/null +++ b/src/reference/ai_poc/crosswalk_detect/utils.cc @@ -0,0 +1,401 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +// utils.cpp +#include +#include "utils.h" + +using std::ofstream; +using std::vector; +auto cache = cv::Mat::zeros(1, 1, CV_32FC1); +void Utils::dump_binary_file(const char *file_name, char *data, const size_t size) +{ + // eg:Utils::dump_binary_file(out_name.c_str(),reinterpret_cast(p_outputs_[i]),each_output_size_by_byte_[i+1]-each_output_size_by_byte_[i]); + std::ofstream outf; + outf.open(file_name, std::ofstream::binary); + outf.write(data, size); + outf.close(); +} + +void Utils::dump_gray_image(const char *file_name, const FrameSize &frame_size, unsigned char *data) +{ + cv::Mat gray_image = cv::Mat(frame_size.height, frame_size.width, CV_8UC1, data); + cv::imwrite(file_name, gray_image); +} + +void Utils::dump_color_image(const char *file_name, const FrameSize &frame_size, unsigned char *data) +{ + cv::Mat image_r = cv::Mat(frame_size.height, frame_size.width, CV_8UC1, data); + cv::Mat image_g = cv::Mat(frame_size.height, frame_size.width, CV_8UC1, data+frame_size.height*frame_size.width); + cv::Mat image_b = cv::Mat(frame_size.height, frame_size.width, CV_8UC1, data+2*frame_size.height*frame_size.width); + + std::vector color_vec(3); + color_vec.clear(); + color_vec.push_back(image_b); + color_vec.push_back(image_g); + color_vec.push_back(image_r); + + cv::Mat color_img; + cv::merge(color_vec, color_img); + cv::imwrite(file_name, color_img); +} + +cv::Mat Utils::padding_resize(const cv::Mat img, const FrameSize &frame_size, const cv::Scalar &padding) +{ + // width:dst_width + int ori_w = img.cols; + int ori_h = img.rows; + float ratiow = (float)frame_size.width / ori_w; + float ratioh = (float)frame_size.height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(frame_size.width - new_w) / 2; + float dh = (float)(frame_size.height - new_h) / 2; + int top = (int)(roundf(0 - 0.1)); + int bottom = (int)(roundf(dh * 2 + 0.1)); + int left = (int)(roundf(0 - 0.1)); + int right = (int)(roundf(dw * 2 - 0.1)); + cv::Mat cropped_img; + { + if ((new_w != frame_size.width) || (new_h != frame_size.height)) + { + cv::resize(img, cropped_img, cv::Size(new_w, new_h), cv::INTER_AREA); + } + } + { + cv::copyMakeBorder(cropped_img, cropped_img, top, bottom, left, right, cv::BORDER_CONSTANT, padding); + } + return cropped_img; +} + +cv::Mat Utils::resize(const cv::Mat img, const FrameSize &frame_size) +{ + cv::Mat cropped_img; + cv::resize(img, cropped_img, cv::Size(frame_size.width, frame_size.height), cv::INTER_LINEAR); + return cropped_img; +} + +cv::Mat Utils::bgr_to_rgb(cv::Mat ori_img) +{ + cv::Mat rgb_img; + cv::cvtColor(ori_img, rgb_img, cv::COLOR_BGR2RGB); + return rgb_img; +} + +void Utils::hwc_to_chw(cv::Mat &ori_img, std::vector &chw_vec) +{ + // for rgb format + std::vector rgbChannels(3); + cv::split(ori_img, rgbChannels); + for (auto i = 0; i < rgbChannels.size(); i++) + { + std::vector data = std::vector(rgbChannels[i].reshape(1, 1)); + chw_vec.insert(chw_vec.end(), data.begin(), data.end()); + } +} + +void Utils::bgr2rgb_and_hwc2chw(cv::Mat &ori_img, std::vector &chw_vec) +{ + // for bgr format + std::vector bgrChannels(3); + cv::split(ori_img, bgrChannels); + for (auto i = 2; i > -1; i--) + { + std::vector data = std::vector(bgrChannels[i].reshape(1, 1)); + chw_vec.insert(chw_vec.end(), data.begin(), data.end()); + } +} + +void Utils::resize(FrameCHWSize ori_shape, std::vector &chw_vec, runtime_tensor &ai2d_out_tensor) +{ + // build ai2d_in_tensor + dims_t in_shape{1, ori_shape.channel, ori_shape.height, ori_shape.width}; + runtime_tensor ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), chw_vec.data(), chw_vec.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + // ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, typecode_t::dt_uint8, typecode_t::dt_uint8}; + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param { false, 30, 20, 400, 600 }; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, ai2d_pad_mode::constant, {114, 114, 114}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::resize(std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor) +{ + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param { false, 30, 20, 400, 600 }; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, ai2d_pad_mode::constant, {114, 114, 114}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::crop_resize(FrameCHWSize ori_shape, std::vector &chw_vec, Bbox &crop_info, runtime_tensor &ai2d_out_tensor) +{ + // build ai2d_in_tensor + dims_t in_shape{1, ori_shape.channel, ori_shape.height, ori_shape.width}; + runtime_tensor ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), chw_vec.data(), chw_vec.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{true, crop_info.x, crop_info.y, crop_info.w, crop_info.h}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, ai2d_pad_mode::constant, {114, 114, 114}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::crop_resize(Bbox &crop_info, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor) +{ + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{true, crop_info.x, crop_info.y, crop_info.w, crop_info.h}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, ai2d_pad_mode::constant, {114, 114, 114}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::padding_resize(FrameCHWSize ori_shape, std::vector &chw_vec, FrameSize resize_shape, runtime_tensor &ai2d_out_tensor, cv::Scalar padding) +{ + int ori_w = ori_shape.width; + int ori_h = ori_shape.height; + int width = resize_shape.width; + int height = resize_shape.height; + float ratiow = (float)width / ori_w; + float ratioh = (float)height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(width - new_w) / 2; + float dh = (float)(height - new_h) / 2; + int top = (int)(roundf(dh - 0.1)); + int bottom = (int)(roundf(dh + 0.1)); + int left = (int)(roundf(dw - 0.1)); + int right = (int)(roundf(dw - 0.1)); + + // create input + dims_t in_shape{1, ori_shape.channel, ori_h, ori_w}; + auto ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), chw_vec.data(), chw_vec.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{true, {{0, 0}, {0, 0}, {top, bottom}, {left, right}}, ai2d_pad_mode::constant, {padding[0], padding[1], padding[2]}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::padding_resize_one_side(FrameCHWSize ori_shape, std::vector &chw_vec, FrameSize resize_shape, runtime_tensor &ai2d_out_tensor, cv::Scalar padding) +{ + int ori_w = ori_shape.width; + int ori_h = ori_shape.height; + int width = resize_shape.width; + int height = resize_shape.height; + float ratiow = (float)width / ori_w; + float ratioh = (float)height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(width - new_w) / 2; + float dh = (float)(height - new_h) / 2; + int top = (int)(roundf(0)); + int bottom = (int)(roundf(dh * 2 + 0.1)); + int left = (int)(roundf(0)); + int right = (int)(roundf(dw * 2 - 0.1)); + + // create input + dims_t in_shape{1, ori_shape.channel, ori_h, ori_w}; + auto ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), chw_vec.data(), chw_vec.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{true, {{0, 0}, {0, 0}, {top, bottom}, {left, right}}, ai2d_pad_mode::constant, {padding[0], padding[1], padding[2]}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::padding_resize(FrameCHWSize ori_shape, FrameSize resize_shape, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor, const cv::Scalar padding) +{ + int ori_w = ori_shape.width; + int ori_h = ori_shape.height; + int width = resize_shape.width; + int height = resize_shape.height; + float ratiow = (float)width / ori_w; + float ratioh = (float)height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(width - new_w) / 2; + float dh = (float)(height - new_h) / 2; + int top = (int)(roundf(dh - 0.1)); + int bottom = (int)(roundf(dh + 0.1)); + int left = (int)(roundf(dw - 0.1)); + int right = (int)(roundf(dw - 0.1)); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{true, {{0, 0}, {0, 0}, {top, bottom}, {left, right}}, ai2d_pad_mode::constant, {padding[0], padding[1], padding[2]}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::padding_resize_one_side(FrameCHWSize ori_shape, FrameSize resize_shape, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor, const cv::Scalar padding) +{ + int ori_w = ori_shape.width; + int ori_h = ori_shape.height; + int width = resize_shape.width; + int height = resize_shape.height; + float ratiow = (float)width / ori_w; + float ratioh = (float)height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(width - new_w) / 2; + float dh = (float)(height - new_h) / 2; + int top = (int)(roundf(0)); + int bottom = (int)(roundf(dh * 2 + 0.1)); + int left = (int)(roundf(0)); + int right = (int)(roundf(dw * 2 - 0.1)); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{true, {{0, 0}, {0, 0}, {top, bottom}, {left, right}}, ai2d_pad_mode::constant, {padding[0], padding[1], padding[2]}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::affine(FrameCHWSize ori_shape, std::vector &ori_data, float *affine_matrix, runtime_tensor &ai2d_out_tensor) +{ + runtime_tensor ai2d_in_tensor; + // init ai2d in/out + dims_t in_shape{1, ori_shape.channel, ori_shape.height, ori_shape.width}; + ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + + // ai2d input + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), ori_data.data(), ori_data.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {10, 0}}, ai2d_pad_mode::constant, {255, 10, 5}}; + ai2d_resize_param_t resize_param{false, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{true, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {affine_matrix[0], affine_matrix[1], affine_matrix[2], affine_matrix[3], affine_matrix[4], affine_matrix[5]}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +// for video(只算一次即可) +void Utils::affine(float *affine_matrix, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor) +{ + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {10, 0}}, ai2d_pad_mode::constant, {255, 10, 5}}; + ai2d_resize_param_t resize_param{false, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{true, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {affine_matrix[0], affine_matrix[1], affine_matrix[2], affine_matrix[3], affine_matrix[4], affine_matrix[5]}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} diff --git a/src/reference/ai_poc/crosswalk_detect/utils.h b/src/reference/ai_poc/crosswalk_detect/utils.h new file mode 100644 index 000000000..b946f235a --- /dev/null +++ b/src/reference/ai_poc/crosswalk_detect/utils.h @@ -0,0 +1,321 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +// utils.h +#ifndef UTILS_H +#define UTILS_H + +#include +#include +#include +#include +#include +#include +#include + +using namespace nncase; +using namespace nncase::runtime; +using namespace nncase::runtime::k230; +using namespace nncase::F::k230; + +using cv::Mat; +using std::cout; +using std::endl; +using std::ifstream; +using std::vector; + +/** + * @brief 行人检测框信息 + */ +typedef struct BoxInfo +{ + float x1; // 行人检测框左上顶点x坐标 + float y1; // 行人检测框左上顶点y坐标 + float x2; // 行人检测框右下顶点x坐标 + float y2; // 行人检测框右下顶点y坐标 + float score; // 行人检测框的得分 + int label; // 行人检测框的标签 +} BoxInfo; + +/** + * @brief 人脸检测框 + */ +typedef struct Bbox +{ + float x; // 人脸检测框的左顶点x坐标 + float y; // 人脸检测框的左顶点x坐标 + float w; + float h; +} Bbox; + +/** + * @brief 人脸五官点 + */ +typedef struct SparseLandmarks +{ + float points[10]; // 人脸五官点,依次是图片的左眼(x,y)、右眼(x,y),鼻子(x,y),左嘴角(x,y),右嘴角 +} SparseLandmarks; + +/** + * @brief 单张/帧图片大小 + */ +typedef struct FrameSize +{ + size_t width; // 宽 + size_t height; // 高 +} FrameSize; + +/** + * @brief 单张/帧图片大小 + */ +typedef struct FrameCHWSize +{ + size_t channel; // 通道 + size_t height; // 高 + size_t width; // 宽 +} FrameCHWSize; + +/** + * @brief AI Demo工具类 + * 封装了AI Demo常用的函数,包括二进制文件读取、文件保存、图片预处理等操作 + */ +class Utils +{ +public: + /** + * @brief 读取2进制文件 + * @param file_name 文件路径 + * @return 文件对应类型的数据 + */ + template + static vector read_binary_file(const char *file_name) + { + ifstream ifs(file_name, std::ios::binary); + ifs.seekg(0, ifs.end); + size_t len = ifs.tellg(); + vector vec(len / sizeof(T), 0); + ifs.seekg(0, ifs.beg); + ifs.read(reinterpret_cast(vec.data()), len); + ifs.close(); + return vec; + } + + /** + * @brief 打印数据 + * @param data 需打印数据对应指针 + * @param size 需打印数据大小 + * @return None + */ + template + static void dump(const T *data, size_t size) + { + for (size_t i = 0; i < size; i++) + { + cout << data[i] << " "; + } + cout << endl; + } + + // 静态成员函数不依赖于类的实例,可以直接通过类名调用 + /** + * @brief 将数据以2进制方式保存为文件 + * @param file_name 保存文件路径+文件名 + * @param data 需要保存的数据 + * @param size 需要保存的长度 + * @return None + */ + static void dump_binary_file(const char *file_name, char *data, const size_t size); + + /** + * @brief 将数据保存为灰度图片 + * @param file_name 保存图片路径+文件名 + * @param frame_size 保存图片的宽、高 + * @param data 需要保存的数据 + * @return None + */ + static void dump_gray_image(const char *file_name, const FrameSize &frame_size, unsigned char *data); + + /** + * @brief 将数据保存为彩色图片 + * @param file_name 保存图片路径+文件名 + * @param frame_size 保存图片的宽、高 + * @param data 需要保存的数据 + * @return None + */ + static void dump_color_image(const char *file_name, const FrameSize &frame_size, unsigned char *data); + + + /*************************for img process********************/ + /** + * @brief 对图片进行先padding后resize的处理 + * @param ori_img 原始图片 + * @param frame_size 需要resize图像的宽高 + * @param padding 需要padding的像素,默认是cv::Scalar(114, 114, 114),BGR + * @return 处理后图像 + */ + static cv::Mat padding_resize(const cv::Mat img, const FrameSize &frame_size, const cv::Scalar &padding = cv::Scalar(114, 114, 114)); + + /** + * @brief 对图片resize + * @param ori_img 原始图片 + * @param frame_size 需要resize图像的宽高 + * @param padding 需要padding的像素,默认是cv::Scalar(114, 114, 114),BGR + * @return 处理后图像 + */ + static cv::Mat resize(const cv::Mat ori_img, const FrameSize &frame_size); + + /** + * @brief 将图片从bgr转为rgb + * @param ori_img 原始图片 + * @return 处理后图像 + */ + static cv::Mat bgr_to_rgb(cv::Mat ori_img); + + /** + * @brief 将RGB或RGB图片从hwc转为chw + * @param ori_img 原始图片 + * @param chw_vec 转为chw后的数据 + * @return None + */ + static void hwc_to_chw(cv::Mat &ori_img, std::vector &chw_vec); // for rgb data + + /** + * @brief 将BGR图片从hwc转为chw + * @param ori_img 原始图片 + * @param chw_vec 转为chw后的数据 + * @return None + */ + static void bgr2rgb_and_hwc2chw(cv::Mat &ori_img, std::vector &chw_vec); + + /*************************for ai2d ori_img process********************/ + // resize + /** + * @brief resize函数,对chw数据进行resize + * @param ori_shape 原始数据chw + * @param chw_vec 原始数据 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + void resize(FrameCHWSize ori_shape, std::vector &chw_vec, runtime_tensor &ai2d_out_tensor); + + /** + * @brief resize函数 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + void resize(std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor); + + // crop resize + /** + * @brief resize函数,对chw数据进行crop & resize + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + void crop_resize(FrameCHWSize ori_shape, std::vector &chw_vec, Bbox &crop_info, runtime_tensor &ai2d_out_tensor); + + /** + * @brief crop_resize函数,对chw数据进行crop & resize + * @param crop_info 需要crop的位置,x,y,w,h + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + void crop_resize(Bbox &crop_info, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor); + + // padding resize + /** + * @brief padding_resize函数(上下左右padding),对chw数据进行padding & resize + * @param ori_shape 原始数据chw + * @param chw_vec 原始数据 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + static void padding_resize(FrameCHWSize ori_shape, std::vector &chw_vec, FrameSize resize_shape, runtime_tensor &ai2d_out_tensor, cv::Scalar padding); + + /** + * @brief padding_resize函数(右或下padding),对chw数据进行padding & resize + * @param ori_shape 原始数据chw + * @param chw_vec 原始数据 + * @param resize_shape resize之后的大小 + * @param ai2d_out_tensor ai2d输出 + * @param padding 填充值,用于resize时的等比例变换 + * @return None + */ + static void padding_resize_one_side(FrameCHWSize ori_shape, std::vector &chw_vec, FrameSize resize_shape, runtime_tensor &ai2d_out_tensor, cv::Scalar padding); + + /** + * @brief padding_resize函数(上下左右padding),对chw数据进行padding & resize + * @param ori_shape 原始数据chw + * @param resize_shape resize之后的大小 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @param padding 填充值,用于resize时的等比例变换 + * @return None + */ + static void padding_resize(FrameCHWSize ori_shape, FrameSize resize_shape, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor, cv::Scalar padding); + + /** + * @brief padding_resize函数(右或下padding),对chw数据进行padding & resize + * @param ori_shape 原始数据chw + * @param resize_shape resize之后的大小 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @param padding 填充值,用于resize时的等比例变换 + * @return None + */ + static void padding_resize_one_side(FrameCHWSize ori_shape, FrameSize resize_shape, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor, const cv::Scalar padding); + + // affine + /** + * @brief 仿射变换函数,对chw数据进行仿射变换(for imgae) + * @param ori_shape 原始数据chw大小 + * @param ori_data 原始数据 + * @param affine_matrix 仿射变换矩阵 + * @param ai2d_out_tensor 仿射变换后的数据 + * @return None + */ + static void affine(FrameCHWSize ori_shape, std::vector &ori_data, float *affine_matrix, runtime_tensor &ai2d_out_tensor); + + /** + * @brief 仿射变换函数,对chw数据进行仿射变换(for video) + * @param affine_matrix 仿射变换矩阵 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + static void affine(float *affine_matrix, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor); + +}; + +#endif diff --git a/src/reference/ai_poc/crosswalk_detect/vi_vo.h b/src/reference/ai_poc/crosswalk_detect/vi_vo.h new file mode 100644 index 000000000..76be47ac2 --- /dev/null +++ b/src/reference/ai_poc/crosswalk_detect/vi_vo.h @@ -0,0 +1,627 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include "mpi_sys_api.h" + +/* vicap */ +#include +#include +#include +#include +#include + +#include "k_module.h" +#include "k_type.h" +#include "k_vb_comm.h" +#include "k_video_comm.h" +#include "k_sys_comm.h" +#include "mpi_vb_api.h" +#include "mpi_vicap_api.h" +#include "mpi_isp_api.h" +#include "mpi_sys_api.h" +#include "k_vo_comm.h" +#include "mpi_vo_api.h" + +#include "vo_test_case.h" + +#include "k_connector_comm.h" +#include "mpi_connector_api.h" +#include "k_autoconf_comm.h" + +#if defined(CONFIG_BOARD_K230_CANMV) +#define SENSOR_CHANNEL (3) // isp通道数 +#define SENSOR_HEIGHT (720) // isp高度,ai输入,竖屏 +#define SENSOR_WIDTH (1280) // isp宽度,ai输入,竖屏 +#define ISP_CHN0_WIDTH (1920)//(1920) +#define ISP_CHN0_HEIGHT (1080)//(1080) +#define vicap_install_osd (1) +#define osd_id K_VO_OSD3 +#define osd_width (1920) +#define osd_height (1080) +#else +#define SENSOR_CHANNEL (3) // isp通道数 +#define SENSOR_HEIGHT (1280) // isp高度,ai输入,竖屏 +#define SENSOR_WIDTH (720) // isp宽度,ai输入,竖屏 +#define ISP_CHN0_WIDTH (1088)//(1920) +#define ISP_CHN0_HEIGHT (1920)//(1080) +#define vicap_install_osd (1) +#define osd_id K_VO_OSD3 +#define osd_width (1080) +#define osd_height (1920) +#endif + + +k_vb_config config; +k_vicap_dev vicap_dev; +k_vicap_chn vicap_chn; +k_vicap_dev_attr dev_attr; +k_vicap_chn_attr chn_attr; +k_vicap_sensor_info sensor_info; +k_vicap_sensor_type sensor_type; +k_mpp_chn vicap_mpp_chn; +k_mpp_chn vo_mpp_chn; + +k_video_frame_info dump_info; + +k_vo_draw_frame vo_frame = (k_vo_draw_frame) { + 1, + 16, + 16, + 128, + 128, + 1 +}; + +static k_vb_blk_handle block; +k_u32 g_pool_id; + +int vo_creat_layer_test(k_vo_layer chn_id, layer_info *info) +{ + k_vo_video_layer_attr attr; + + // check layer + if ((chn_id >= K_MAX_VO_LAYER_NUM) || ((info->func & K_VO_SCALER_ENABLE) && (chn_id != K_VO_LAYER0)) + || ((info->func != 0) && (chn_id == K_VO_LAYER2))) + { + printf("input layer num failed \n"); + return -1 ; + } + + // check scaler + + // set offset + attr.display_rect = info->offset; + // set act + attr.img_size = info->act_size; + // sget size + info->size = info->act_size.height * info->act_size.width * 3 / 2; + //set pixel format + attr.pixel_format = info->format; + if (info->format != PIXEL_FORMAT_YVU_PLANAR_420) + { + printf("input pix format failed \n"); + return -1; + } + // set stride + attr.stride = (info->act_size.width / 8 - 1) + ((info->act_size.height - 1) << 16); + // set function + attr.func = info->func; + // set scaler attr + attr.scaler_attr = info->attr; + + // set video layer atrr + kd_mpi_vo_set_video_layer_attr(chn_id, &attr); + + // enable layer + kd_mpi_vo_enable_video_layer(chn_id); + + return 0; +} + +k_vb_blk_handle vo_insert_frame(k_video_frame_info *vf_info, void **pic_vaddr) +{ + k_u64 phys_addr = 0; + k_u32 *virt_addr; + k_vb_blk_handle handle; + k_s32 size; + + if (vf_info == NULL) + return K_FALSE; + + if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_ABGR_8888 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_ARGB_8888) + size = vf_info->v_frame.height * vf_info->v_frame.width * 4; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_RGB_565 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_BGR_565) + size = vf_info->v_frame.height * vf_info->v_frame.width * 2; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_ABGR_4444 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_ARGB_4444) + size = vf_info->v_frame.height * vf_info->v_frame.width * 2; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_RGB_888 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_BGR_888) + size = vf_info->v_frame.height * vf_info->v_frame.width * 3; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_ARGB_1555 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_ABGR_1555) + size = vf_info->v_frame.height * vf_info->v_frame.width * 2; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_YVU_PLANAR_420) + size = vf_info->v_frame.height * vf_info->v_frame.width * 3 / 2; + + size = size + 4096; // 强制4K ,后边得删了 + + printf("vb block size is %x \n", size); + + handle = kd_mpi_vb_get_block(g_pool_id, size, NULL); + if (handle == VB_INVALID_HANDLE) + { + printf("%s get vb block error\n", __func__); + return K_FAILED; + } + + phys_addr = kd_mpi_vb_handle_to_phyaddr(handle); + if (phys_addr == 0) + { + printf("%s get phys addr error\n", __func__); + return K_FAILED; + } + + virt_addr = (k_u32 *)kd_mpi_sys_mmap(phys_addr, size); + // virt_addr = (k_u32 *)kd_mpi_sys_mmap_cached(phys_addr, size); + + if (virt_addr == NULL) + { + printf("%s mmap error\n", __func__); + return K_FAILED; + } + + vf_info->mod_id = K_ID_VO; + vf_info->pool_id = g_pool_id; + vf_info->v_frame.phys_addr[0] = phys_addr; + if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_YVU_PLANAR_420) + vf_info->v_frame.phys_addr[1] = phys_addr + (vf_info->v_frame.height * vf_info->v_frame.stride[0]); + *pic_vaddr = virt_addr; + + printf("phys_addr is %lx g_pool_id is %d \n", phys_addr, g_pool_id); + + return handle; +} + +k_u32 vo_creat_osd_test(k_vo_osd osd, osd_info *info) +{ + k_vo_video_osd_attr attr; + + // set attr + attr.global_alptha = info->global_alptha; + + if (info->format == PIXEL_FORMAT_ABGR_8888 || info->format == PIXEL_FORMAT_ARGB_8888) + { + info->size = info->act_size.width * info->act_size.height * 4; + info->stride = info->act_size.width * 4 / 8; + } + else if (info->format == PIXEL_FORMAT_RGB_565 || info->format == PIXEL_FORMAT_BGR_565) + { + info->size = info->act_size.width * info->act_size.height * 2; + info->stride = info->act_size.width * 2 / 8; + } + else if (info->format == PIXEL_FORMAT_RGB_888 || info->format == PIXEL_FORMAT_BGR_888) + { + info->size = info->act_size.width * info->act_size.height * 3; + info->stride = info->act_size.width * 3 / 8; + } + else if(info->format == PIXEL_FORMAT_ARGB_4444 || info->format == PIXEL_FORMAT_ABGR_4444) + { + info->size = info->act_size.width * info->act_size.height * 2; + info->stride = info->act_size.width * 2 / 8; + } + else if(info->format == PIXEL_FORMAT_ARGB_1555 || info->format == PIXEL_FORMAT_ABGR_1555) + { + info->size = info->act_size.width * info->act_size.height * 2; + info->stride = info->act_size.width * 2 / 8; + } + else + { + printf("set osd pixel format failed \n"); + } + + attr.stride = info->stride; + attr.pixel_format = info->format; + attr.display_rect = info->offset; + attr.img_size = info->act_size; + kd_mpi_vo_set_video_osd_attr(osd, &attr); + + kd_mpi_vo_osd_enable(osd); + + return 0; +} + +void sample_vicap_install_osd(void) +{ + osd_info osd; + + osd.act_size.width = osd_width ; + osd.act_size.height = osd_height; + osd.offset.x = 0; + osd.offset.y = 0; + osd.global_alptha = 0xff; + // osd.global_alptha = 0x32; + osd.format = PIXEL_FORMAT_ARGB_8888;//PIXEL_FORMAT_ARGB_4444; //PIXEL_FORMAT_ARGB_1555;//PIXEL_FORMAT_ARGB_8888; + + vo_creat_osd_test(osd_id, &osd); +} + +void vo_osd_release_block(void) +{ + if(vicap_install_osd == 1) + { + kd_mpi_vo_osd_disable(osd_id); + kd_mpi_vb_release_block(block); + } + +} + +static k_s32 sample_connector_init(void) +{ + k_u32 ret = 0; + k_s32 connector_fd; +#if defined(CONFIG_BOARD_K230_CANMV) + k_connector_type connector_type = LT9611_MIPI_4LAN_1920X1080_30FPS;// HX8377_V2_MIPI_4LAN_1080X1920_30FPS; +#else + k_connector_type connector_type = HX8377_V2_MIPI_4LAN_1080X1920_30FPS; +#endif + k_connector_info connector_info; + + memset(&connector_info, 0, sizeof(k_connector_info)); + + //connector get sensor info + ret = kd_mpi_get_connector_info(connector_type, &connector_info); + if (ret) { + printf("sample_vicap, the sensor type not supported!\n"); + return ret; + } + + connector_fd = kd_mpi_connector_open(connector_info.connector_name); + if (connector_fd < 0) { + printf("%s, connector open failed.\n", __func__); + return K_ERR_VO_NOTREADY; + } + + // set connect power + kd_mpi_connector_power_set(connector_fd, K_TRUE); + // connector init + kd_mpi_connector_init(connector_fd, connector_info); + + return 0; +} + +static k_s32 vo_layer_vdss_bind_vo_config(void) +{ + layer_info info; + + k_vo_layer chn_id = K_VO_LAYER1; + + memset(&info, 0, sizeof(info)); + + sample_connector_init(); + + // config lyaer + info.act_size.width = ISP_CHN0_WIDTH;//ISP_CHN0_HEIGHT;//1080;//640;//1080; + info.act_size.height = ISP_CHN0_HEIGHT;//ISP_CHN0_WIDTH;//1920;//480;//1920; + info.format = PIXEL_FORMAT_YVU_PLANAR_420; + info.func = 0;//K_ROTATION_180;////K_ROTATION_90; + info.global_alptha = 0xff; + info.offset.x = 0;//(1080-w)/2, + info.offset.y = 0;//(1920-h)/2; + vo_creat_layer_test(chn_id, &info); + + if(vicap_install_osd == 1) + sample_vicap_install_osd(); + + //exit ; + return 0; +} + +static void sample_vicap_bind_vo(k_mpp_chn vicap_mpp_chn, k_mpp_chn vo_mpp_chn) +{ + k_s32 ret; + + ret = kd_mpi_sys_bind(&vicap_mpp_chn, &vo_mpp_chn); + if (ret) { + printf("kd_mpi_sys_unbind failed:0x%x\n", ret); + } + + return; +} + +static void sample_vicap_unbind_vo(k_mpp_chn vicap_mpp_chn, k_mpp_chn vo_mpp_chn) +{ + k_s32 ret; + + ret = kd_mpi_sys_unbind(&vicap_mpp_chn, &vo_mpp_chn); + if (ret) { + printf("kd_mpi_sys_unbind failed:0x%x\n", ret); + } + + return; +} + +int vivcap_start() +{ + k_s32 ret = 0; + + k_u32 pool_id; + k_vb_pool_config pool_config; + + printf("sample_vicap ...\n"); + +#if defined(CONFIG_BOARD_K230_CANMV) + sensor_type = OV_OV5647_MIPI_CSI0_1920X1080_30FPS_10BIT_LINEAR; + kd_mpi_vicap_set_mclk(VICAP_MCLK0, VICAP_PLL0_CLK_DIV4, 16, 1); +#else + sensor_type = IMX335_MIPI_2LANE_RAW12_2592X1944_30FPS_LINEAR; +#endif + vicap_dev = VICAP_DEV_ID_0; + + memset(&config, 0, sizeof(config)); + config.max_pool_cnt = 64; + //VB for YUV420SP output + config.comm_pool[0].blk_cnt = 5; + config.comm_pool[0].mode = VB_REMAP_MODE_NOCACHE; + config.comm_pool[0].blk_size = VICAP_ALIGN_UP((ISP_CHN0_WIDTH * ISP_CHN0_HEIGHT * 3 / 2), VICAP_ALIGN_1K); + + //VB for RGB888 output + config.comm_pool[1].blk_cnt = 5; + config.comm_pool[1].mode = VB_REMAP_MODE_NOCACHE; + config.comm_pool[1].blk_size = VICAP_ALIGN_UP((SENSOR_HEIGHT * SENSOR_WIDTH * 3 ), VICAP_ALIGN_1K); + + ret = kd_mpi_vb_set_config(&config); + if (ret) { + printf("vb_set_config failed ret:%d\n", ret); + return ret; + } + + k_vb_supplement_config supplement_config; + memset(&supplement_config, 0, sizeof(supplement_config)); + supplement_config.supplement_config |= VB_SUPPLEMENT_JPEG_MASK; + + ret = kd_mpi_vb_set_supplement_config(&supplement_config); + if (ret) { + printf("vb_set_supplement_config failed ret:%d\n", ret); + return ret; + } + + ret = kd_mpi_vb_init(); + if (ret) { + printf("vb_init failed ret:%d\n", ret); + return ret; + } + printf("sample_vicap ...kd_mpi_vicap_get_sensor_info\n"); + + // dwc_dsi_init(); + vo_layer_vdss_bind_vo_config(); + + if(vicap_install_osd == 1) + { + memset(&pool_config, 0, sizeof(pool_config)); + pool_config.blk_size = VICAP_ALIGN_UP((osd_width * osd_height * 4 * 2), VICAP_ALIGN_1K); + pool_config.blk_cnt = 4; + pool_config.mode = VB_REMAP_MODE_NOCACHE; + pool_id = kd_mpi_vb_create_pool(&pool_config); // osd0 - 3 argb 320 x 240 + g_pool_id = pool_id; + + printf("--------aa--------------g_pool_id is %d pool_id is %d \n",g_pool_id, pool_id); + } + + memset(&sensor_info, 0, sizeof(k_vicap_sensor_info)); + ret = kd_mpi_vicap_get_sensor_info(sensor_type, &sensor_info); + if (ret) { + printf("sample_vicap, the sensor type not supported!\n"); + return ret; + } + + memset(&dev_attr, 0, sizeof(k_vicap_dev_attr)); + dev_attr.acq_win.h_start = 0; + dev_attr.acq_win.v_start = 0; +#if defined (CONFIG_BOARD_K230_CANMV) + dev_attr.acq_win.width = ISP_CHN0_WIDTH; + dev_attr.acq_win.height = ISP_CHN0_HEIGHT; +#else + dev_attr.acq_win.width = 2592;//SENSOR_HEIGHT; + dev_attr.acq_win.height = 1944;//SENSOR_WIDTH; +#endif + dev_attr.mode = VICAP_WORK_ONLINE_MODE; + + dev_attr.pipe_ctrl.data = 0xFFFFFFFF; + dev_attr.pipe_ctrl.bits.af_enable = 0; + dev_attr.pipe_ctrl.bits.ahdr_enable = 0; + + + dev_attr.cpature_frame = 0; + memcpy(&dev_attr.sensor_info, &sensor_info, sizeof(k_vicap_sensor_info)); + + ret = kd_mpi_vicap_set_dev_attr(vicap_dev, dev_attr); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_set_dev_attr failed.\n"); + return ret; + } + + memset(&chn_attr, 0, sizeof(k_vicap_chn_attr)); + + //set chn0 output yuv420sp + chn_attr.out_win.h_start = 0; + chn_attr.out_win.v_start = 0; + chn_attr.out_win.width = ISP_CHN0_WIDTH; + chn_attr.out_win.height = ISP_CHN0_HEIGHT; + + +#if defined(CONFIG_BOARD_K230_CANMV) + chn_attr.crop_win = dev_attr.acq_win; +#else + // chn_attr.crop_win = dev_attr.acq_win; + chn_attr.crop_win.h_start = 768; + chn_attr.crop_win.v_start = 16; + chn_attr.crop_win.width = ISP_CHN0_WIDTH; + chn_attr.crop_win.height = ISP_CHN0_HEIGHT; +#endif + + chn_attr.scale_win = chn_attr.out_win; + chn_attr.crop_enable = K_FALSE; + chn_attr.scale_enable = K_FALSE; + // chn_attr.dw_enable = K_FALSE; + chn_attr.chn_enable = K_TRUE; + chn_attr.pix_format = PIXEL_FORMAT_YVU_PLANAR_420; + chn_attr.buffer_num = VICAP_MAX_FRAME_COUNT;//at least 3 buffers for isp + chn_attr.buffer_size = config.comm_pool[0].blk_size; + vicap_chn = VICAP_CHN_ID_0; + + printf("sample_vicap ...kd_mpi_vicap_set_chn_attr, buffer_size[%d]\n", chn_attr.buffer_size); + ret = kd_mpi_vicap_set_chn_attr(vicap_dev, vicap_chn, chn_attr); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_set_chn_attr failed.\n"); + return ret; + } + + //bind vicap chn 0 to vo + vicap_mpp_chn.mod_id = K_ID_VI; + vicap_mpp_chn.dev_id = vicap_dev; + vicap_mpp_chn.chn_id = vicap_chn; + + vo_mpp_chn.mod_id = K_ID_VO; + vo_mpp_chn.dev_id = K_VO_DISPLAY_DEV_ID; + vo_mpp_chn.chn_id = K_VO_DISPLAY_CHN_ID1; + + sample_vicap_bind_vo(vicap_mpp_chn, vo_mpp_chn); + printf("sample_vicap ...dwc_dsi_init\n"); + + //set chn1 output rgb888p + chn_attr.out_win.h_start = 0; + chn_attr.out_win.v_start = 0; + chn_attr.out_win.width = SENSOR_WIDTH ; + chn_attr.out_win.height = SENSOR_HEIGHT; + // chn_attr.crop_win = dev_attr.acq_win; + +#if defined(CONFIG_BOARD_K230_CANMV) + chn_attr.crop_win = dev_attr.acq_win; +#else + chn_attr.crop_win.h_start = 768; + chn_attr.crop_win.v_start = 16; + chn_attr.crop_win.width = ISP_CHN0_WIDTH; + chn_attr.crop_win.height = ISP_CHN0_HEIGHT; +#endif + + chn_attr.scale_win = chn_attr.out_win; + chn_attr.crop_enable = K_FALSE; + chn_attr.scale_enable = K_FALSE; + // chn_attr.dw_enable = K_FALSE; + chn_attr.chn_enable = K_TRUE; + chn_attr.pix_format = PIXEL_FORMAT_BGR_888_PLANAR; + chn_attr.buffer_num = VICAP_MAX_FRAME_COUNT;//at least 3 buffers for isp + chn_attr.buffer_size = config.comm_pool[1].blk_size; + + printf("sample_vicap ...kd_mpi_vicap_set_chn_attr, buffer_size[%d]\n", chn_attr.buffer_size); + ret = kd_mpi_vicap_set_chn_attr(vicap_dev, VICAP_CHN_ID_1, chn_attr); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_set_chn_attr failed.\n"); + return ret; + } + + printf("sample_vicap ...kd_mpi_vicap_init\n"); + ret = kd_mpi_vicap_init(vicap_dev); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_init failed.\n"); + // goto err_exit; + } + + printf("sample_vicap ...kd_mpi_vicap_start_stream\n"); + ret = kd_mpi_vicap_start_stream(vicap_dev); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_init failed.\n"); + // goto err_exit; + } + + return ret; +} + +int vivcap_stop() +{ + printf("sample_vicap ...kd_mpi_vicap_stop_stream\n"); + int ret = kd_mpi_vicap_stop_stream(vicap_dev); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_init failed.\n"); + return ret; + } + + ret = kd_mpi_vicap_deinit(vicap_dev); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_deinit failed.\n"); + return ret; + } + + kd_mpi_vo_disable_video_layer(K_VO_LAYER1); + + vicap_mpp_chn.mod_id = K_ID_VI; + vicap_mpp_chn.dev_id = vicap_dev; + vicap_mpp_chn.chn_id = vicap_chn; + + vo_mpp_chn.mod_id = K_ID_VO; + vo_mpp_chn.dev_id = K_VO_DISPLAY_DEV_ID; + vo_mpp_chn.chn_id = K_VO_DISPLAY_CHN_ID1; + + sample_vicap_unbind_vo(vicap_mpp_chn, vo_mpp_chn); + + /*Allow one frame time for the VO to release the VB block*/ + k_u32 display_ms = 1000 / 33; + usleep(1000 * display_ms); + + ret = kd_mpi_vb_exit(); + if (ret) { + printf("sample_vicap, kd_mpi_vb_exit failed.\n"); + return ret; + } + + return 0; +} + +void yuv_rotate_90(char *des, char *src,int width,int height) +{ + int n = 0; + int hw = width>>1; + int hh = height>>1; + int size = width * height; + int hsize = size>>2; + + int pos = 0; + + for(int i = width-1;i >= 0;i--) + { + pos = 0; + for(int j= 0;j < height;j++) + { + des[n++]= src[pos+i]; + pos += width; + } + } + +} + diff --git a/src/reference/ai_poc/dynamic_gesture/main.cc b/src/reference/ai_poc/dynamic_gesture/main.cc index d4bf41130..0a04f4d6a 100755 --- a/src/reference/ai_poc/dynamic_gesture/main.cc +++ b/src/reference/ai_poc/dynamic_gesture/main.cc @@ -110,10 +110,11 @@ void video_proc(char *argv[]) cv::Mat right_argb; cv::Mat middle_argb; #if defined(CONFIG_BOARD_K230_CANMV) - int show_x = 500; - int show_y = 40; + int show_x = 580; + int show_y = 90; int show_width = 1160; int show_height = 1000; + float ratio = 0.9; cv::Mat trigger_argb_tmp; cv::Mat up_argb_tmp; @@ -125,27 +126,33 @@ void video_proc(char *argv[]) Utils::bin_2_mat("trigger.bin", show_height, show_width, trigger_argb_tmp); transpose(trigger_argb_tmp, trigger_argb); flip(trigger_argb, trigger_argb, 1); - std::cout<<"trigger_argb size: "< +Options: + kmodel_det 人脸检测kmodel路径 + obj_thres 人脸检测阈值 + nms_thres 人脸检测nms阈值 + kmodel_align 人脸对齐kmodel路径 + kmodel_align_post 人脸对齐后处理kmodel路径 + input_mode 本地图片(图片路径)/ 摄像头(None) + output_mode 渲染方式(depth、pncc) + debug_mode 是否需要调试,0、1、2分别表示不调试、简单调试、详细调试 + + #单图推理示例:(face_alignment_image.sh) +./face_alignment.elf face_detection_320.kmodel 0.6 0.2 face_alignment.kmodel face_alignment_post.kmodel 1024x768.jpg depth 1 + + #视频流推理:(face_alignment_isp.sh) +./face_alignment.elf face_detection_320.kmodel 0.6 0.2 face_alignment.kmodel face_alignment_post.kmodel None depth 0 +``` +## 2.2 效果展示 + +人脸深度图 + +人脸pncc图 + + diff --git a/src/reference/ai_poc/face_alignment/ai_base.cc b/src/reference/ai_poc/face_alignment/ai_base.cc new file mode 100644 index 000000000..2bc809473 --- /dev/null +++ b/src/reference/ai_poc/face_alignment/ai_base.cc @@ -0,0 +1,184 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "ai_base.h" + +#include +#include +#include +#include + +#include +#include "utils.h" + +using std::cout; +using std::endl; +using namespace nncase; +using namespace nncase::runtime::detail; + +AIBase::AIBase(const char *kmodel_file,const string model_name, const int debug_mode) : debug_mode_(debug_mode),model_name_(model_name) +{ + if (debug_mode > 1) + cout << "kmodel_file:" << kmodel_file << endl; + std::ifstream ifs(kmodel_file, std::ios::binary); + kmodel_interp_.load_model(ifs).expect("Invalid kmodel"); + set_input_init(); + set_output_init(); +} + +AIBase::~AIBase() +{ +} + +void AIBase::set_input_init() +{ + ScopedTiming st(model_name_ + " set_input init", debug_mode_); + int input_total_size = 0; + each_input_size_by_byte_.push_back(0); // 先补0,为之后做准备 + for (int i = 0; i < kmodel_interp_.inputs_size(); ++i) + { + auto desc = kmodel_interp_.input_desc(i); + auto shape = kmodel_interp_.input_shape(i); + auto tensor = host_runtime_tensor::create(desc.datatype, shape, hrt::pool_shared).expect("cannot create input tensor"); + kmodel_interp_.input_tensor(i, tensor).expect("cannot set input tensor"); + vector in_shape; + if (debug_mode_ > 1) + cout<<"input "<< std::to_string(i) <<" : "< 1) + cout << shape[j] << ","; + } + if (debug_mode_ > 1) + cout << endl; + input_shapes_.push_back(in_shape); + // DEFINE_TYPECODE(uint8, u8, 0x06) + // DEFINE_TYPECODE(float32, f32, 0x0B) + if (desc.datatype == dt_int8 || desc.datatype == dt_uint8) + { + input_total_size += dsize; + } + else if (desc.datatype == dt_int16 || desc.datatype == dt_uint16 || desc.datatype == dt_float16 || desc.datatype == dt_bfloat16) + { + input_total_size += (dsize * 2); + } + else if (desc.datatype == dt_int32 || desc.datatype == dt_uint32 || desc.datatype == dt_float32) + { + input_total_size += (dsize * 4); + } + else if(desc.datatype == dt_int64 || desc.datatype == dt_uint64 || desc.datatype == dt_float64) + { + input_total_size += (dsize * 8); + } + else + { + printf("input data type:%d",desc.datatype); + assert(("unsupported kmodel output data type", 0)); + } + each_input_size_by_byte_.push_back(input_total_size); + + } + each_input_size_by_byte_.push_back(input_total_size); // 最后一个保存总大小 +} + +runtime_tensor AIBase::get_input_tensor(size_t idx) +{ + return kmodel_interp_.input_tensor(idx).expect("cannot get input tensor"); +} + +void AIBase::set_output_init() +{ + ScopedTiming st(model_name_ + " set_output_init", debug_mode_); + each_output_size_by_byte_.clear(); + int output_total_size = 0; + each_output_size_by_byte_.push_back(0); + for (size_t i = 0; i < kmodel_interp_.outputs_size(); i++) + { + auto desc = kmodel_interp_.output_desc(i); + auto shape = kmodel_interp_.output_shape(i); + vector out_shape; + if (debug_mode_ > 1) + cout<<"output "< 1) + cout << shape[j] << ","; + } + if (debug_mode_ > 1) + cout << endl; + output_shapes_.push_back(out_shape); + if (desc.datatype == dt_int8 || desc.datatype == dt_uint8) + { + output_total_size += dsize; + } + else if (desc.datatype == dt_int16 || desc.datatype == dt_uint16 || desc.datatype == dt_float16 || desc.datatype == dt_bfloat16) + { + output_total_size += (dsize * 2); + } + else if (desc.datatype == dt_int32 || desc.datatype == dt_uint32 || desc.datatype == dt_float32) + { + output_total_size += (dsize * 4); + } + else if(desc.datatype == dt_int64 || desc.datatype == dt_uint64 || desc.datatype == dt_float64) + { + output_total_size += (dsize * 8); + } + else + { + printf("output data type:%d",desc.datatype); + assert(("unsupported kmodel output data type", 0)); + } + + each_output_size_by_byte_.push_back(output_total_size); + auto tensor = host_runtime_tensor::create(desc.datatype, shape, hrt::pool_shared).expect("cannot create output tensor"); + kmodel_interp_.output_tensor(i, tensor).expect("cannot set output tensor"); + } +} + +void AIBase::run() +{ + ScopedTiming st(model_name_ + " run", debug_mode_); + kmodel_interp_.run().expect("error occurred in running model"); +} + +void AIBase::get_output() +{ + ScopedTiming st(model_name_ + " get_output", debug_mode_); + p_outputs_.clear(); + for (int i = 0; i < kmodel_interp_.outputs_size(); i++) + { + auto out = kmodel_interp_.output_tensor(i).expect("cannot get output tensor"); + // auto mapped_buf = std::move(hrt::map(out, map_access_::map_read).unwrap()); + // float *p_out = reinterpret_cast(mapped_buf.buffer().data()); + auto buf = out.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_read).unwrap().buffer(); + float *p_out = reinterpret_cast(buf.data()); + p_outputs_.push_back(p_out); + } +} diff --git a/src/reference/ai_poc/face_alignment/ai_base.h b/src/reference/ai_poc/face_alignment/ai_base.h new file mode 100644 index 000000000..7486c9d35 --- /dev/null +++ b/src/reference/ai_poc/face_alignment/ai_base.h @@ -0,0 +1,104 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +// ai_base.h +#ifndef AI_BASE_H +#define AI_BASE_H + +#include +#include +#include + +#include +#include "scoped_timing.hpp" + +using std::string; +using std::vector; +using namespace nncase::runtime; + +/** + * @brief AI基类,封装nncase相关操作 + * 主要封装了nncase的加载、设置输入、运行、获取输出操作,后续开发demo只需要关注模型的前处理、后处理即可 + */ +class AIBase +{ +public: + /** + * @brief AI基类构造函数,加载kmodel,并初始化kmodel输入、输出 + * @param kmodel_file kmodel文件路径 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + AIBase(const char *kmodel_file,const string model_name, const int debug_mode = 1); + + /** + * @brief AI基类析构函数 + * @return None + */ + ~AIBase(); + + /** + * @brief 根据索引获取kmodel输入tensor + * @param idx 输入数据指针 + * @return None + */ + runtime_tensor get_input_tensor(size_t idx); + + /** + * @brief 推理kmodel + * @return None + */ + void run(); + + /** + * @brief 获取kmodel输出,结果保存在对应的类属性中 + * @return None + */ + void get_output(); + +protected: + string model_name_; // 模型名字 + int debug_mode_; // 调试模型,0(不打印),1(打印时间),2(打印所有) + vector p_outputs_; // kmodel输出对应的指针列表 + vector> input_shapes_; //{{N,C,H,W},{N,C,H,W}...} + vector> output_shapes_; //{{N,C,H,W},{N,C,H,W}...}} 或 {{N,C},{N,C}...}}等 + vector each_input_size_by_byte_; //{0,layer1_length,layer1_length+layer2_length,...} + vector each_output_size_by_byte_; //{0,layer1_length,layer1_length+layer2_length,...} +private: + /** + * @brief 首次初始化kmodel输入,并获取输入shape + * @return None + */ + void set_input_init(); + + /** + * @brief 首次初始化kmodel输出,并获取输出shape + * @return None + */ + void set_output_init(); + + interpreter kmodel_interp_; // kmodel解释器,从kmodel文件构建,负责模型的加载、输入输出设置和推理 + vector kmodel_vec_; // 通过读取kmodel文件得到整个kmodel数据,用于传给kmodel解释器加载kmodel +}; +#endif \ No newline at end of file diff --git a/src/reference/ai_poc/face_alignment/anchors_320.cc b/src/reference/ai_poc/face_alignment/anchors_320.cc new file mode 100644 index 000000000..f4d166abe --- /dev/null +++ b/src/reference/ai_poc/face_alignment/anchors_320.cc @@ -0,0 +1,25 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +float kAnchors320[4200][4] = {{0.012500,0.012500,0.050000,0.050000},{0.012500,0.012500,0.100000,0.100000},{0.037500,0.012500,0.050000,0.050000},{0.037500,0.012500,0.100000,0.100000},{0.062500,0.012500,0.050000,0.050000},{0.062500,0.012500,0.100000,0.100000},{0.087500,0.012500,0.050000,0.050000},{0.087500,0.012500,0.100000,0.100000},{0.112500,0.012500,0.050000,0.050000},{0.112500,0.012500,0.100000,0.100000},{0.137500,0.012500,0.050000,0.050000},{0.137500,0.012500,0.100000,0.100000},{0.162500,0.012500,0.050000,0.050000},{0.162500,0.012500,0.100000,0.100000},{0.187500,0.012500,0.050000,0.050000},{0.187500,0.012500,0.100000,0.100000},{0.212500,0.012500,0.050000,0.050000},{0.212500,0.012500,0.100000,0.100000},{0.237500,0.012500,0.050000,0.050000},{0.237500,0.012500,0.100000,0.100000},{0.262500,0.012500,0.050000,0.050000},{0.262500,0.012500,0.100000,0.100000},{0.287500,0.012500,0.050000,0.050000},{0.287500,0.012500,0.100000,0.100000},{0.312500,0.012500,0.050000,0.050000},{0.312500,0.012500,0.100000,0.100000},{0.337500,0.012500,0.050000,0.050000},{0.337500,0.012500,0.100000,0.100000},{0.362500,0.012500,0.050000,0.050000},{0.362500,0.012500,0.100000,0.100000},{0.387500,0.012500,0.050000,0.050000},{0.387500,0.012500,0.100000,0.100000},{0.412500,0.012500,0.050000,0.050000},{0.412500,0.012500,0.100000,0.100000},{0.437500,0.012500,0.050000,0.050000},{0.437500,0.012500,0.100000,0.100000},{0.462500,0.012500,0.050000,0.050000},{0.462500,0.012500,0.100000,0.100000},{0.487500,0.012500,0.050000,0.050000},{0.487500,0.012500,0.100000,0.100000},{0.512500,0.012500,0.050000,0.050000},{0.512500,0.012500,0.100000,0.100000},{0.537500,0.012500,0.050000,0.050000},{0.537500,0.012500,0.100000,0.100000},{0.562500,0.012500,0.050000,0.050000},{0.562500,0.012500,0.100000,0.100000},{0.587500,0.012500,0.050000,0.050000},{0.587500,0.012500,0.100000,0.100000},{0.612500,0.012500,0.050000,0.050000},{0.612500,0.012500,0.100000,0.100000},{0.637500,0.012500,0.050000,0.050000},{0.637500,0.012500,0.100000,0.100000},{0.662500,0.012500,0.050000,0.050000},{0.662500,0.012500,0.100000,0.100000},{0.687500,0.012500,0.050000,0.050000},{0.687500,0.012500,0.100000,0.100000},{0.712500,0.012500,0.050000,0.050000},{0.712500,0.012500,0.100000,0.100000},{0.737500,0.012500,0.050000,0.050000},{0.737500,0.012500,0.100000,0.100000},{0.762500,0.012500,0.050000,0.050000},{0.762500,0.012500,0.100000,0.100000},{0.787500,0.012500,0.050000,0.050000},{0.787500,0.012500,0.100000,0.100000},{0.812500,0.012500,0.050000,0.050000},{0.812500,0.012500,0.100000,0.100000},{0.837500,0.012500,0.050000,0.050000},{0.837500,0.012500,0.100000,0.100000},{0.862500,0.012500,0.050000,0.050000},{0.862500,0.012500,0.100000,0.100000},{0.887500,0.012500,0.050000,0.050000},{0.887500,0.012500,0.100000,0.100000},{0.912500,0.012500,0.050000,0.050000},{0.912500,0.012500,0.100000,0.100000},{0.937500,0.012500,0.050000,0.050000},{0.937500,0.012500,0.100000,0.100000},{0.962500,0.012500,0.050000,0.050000},{0.962500,0.012500,0.100000,0.100000},{0.987500,0.012500,0.050000,0.050000},{0.987500,0.012500,0.100000,0.100000},{0.012500,0.037500,0.050000,0.050000},{0.012500,0.037500,0.100000,0.100000},{0.037500,0.037500,0.050000,0.050000},{0.037500,0.037500,0.100000,0.100000},{0.062500,0.037500,0.050000,0.050000},{0.062500,0.037500,0.100000,0.100000},{0.087500,0.037500,0.050000,0.050000},{0.087500,0.037500,0.100000,0.100000},{0.112500,0.037500,0.050000,0.050000},{0.112500,0.037500,0.100000,0.100000},{0.137500,0.037500,0.050000,0.050000},{0.137500,0.037500,0.100000,0.100000},{0.162500,0.037500,0.050000,0.050000},{0.162500,0.037500,0.100000,0.100000},{0.187500,0.037500,0.050000,0.050000},{0.187500,0.037500,0.100000,0.100000},{0.212500,0.037500,0.050000,0.050000},{0.212500,0.037500,0.100000,0.100000},{0.237500,0.037500,0.050000,0.050000},{0.237500,0.037500,0.100000,0.100000},{0.262500,0.037500,0.050000,0.050000},{0.262500,0.037500,0.100000,0.100000},{0.287500,0.037500,0.050000,0.050000},{0.287500,0.037500,0.100000,0.100000},{0.312500,0.037500,0.050000,0.050000},{0.312500,0.037500,0.100000,0.100000},{0.337500,0.037500,0.050000,0.050000},{0.337500,0.037500,0.100000,0.100000},{0.362500,0.037500,0.050000,0.050000},{0.362500,0.037500,0.100000,0.100000},{0.387500,0.037500,0.050000,0.050000},{0.387500,0.037500,0.100000,0.100000},{0.412500,0.037500,0.050000,0.050000},{0.412500,0.037500,0.100000,0.100000},{0.437500,0.037500,0.050000,0.050000},{0.437500,0.037500,0.100000,0.100000},{0.462500,0.037500,0.050000,0.050000},{0.462500,0.037500,0.100000,0.100000},{0.487500,0.037500,0.050000,0.050000},{0.487500,0.037500,0.100000,0.100000},{0.512500,0.037500,0.050000,0.050000},{0.512500,0.037500,0.100000,0.100000},{0.537500,0.037500,0.050000,0.050000},{0.537500,0.037500,0.100000,0.100000},{0.562500,0.037500,0.050000,0.050000},{0.562500,0.037500,0.100000,0.100000},{0.587500,0.037500,0.050000,0.050000},{0.587500,0.037500,0.100000,0.100000},{0.612500,0.037500,0.050000,0.050000},{0.612500,0.037500,0.100000,0.100000},{0.637500,0.037500,0.050000,0.050000},{0.637500,0.037500,0.100000,0.100000},{0.662500,0.037500,0.050000,0.050000},{0.662500,0.037500,0.100000,0.100000},{0.687500,0.037500,0.050000,0.050000},{0.687500,0.037500,0.100000,0.100000},{0.712500,0.037500,0.050000,0.050000},{0.712500,0.037500,0.100000,0.100000},{0.737500,0.037500,0.050000,0.050000},{0.737500,0.037500,0.100000,0.100000},{0.762500,0.037500,0.050000,0.050000},{0.762500,0.037500,0.100000,0.100000},{0.787500,0.037500,0.050000,0.050000},{0.787500,0.037500,0.100000,0.100000},{0.812500,0.037500,0.050000,0.050000},{0.812500,0.037500,0.100000,0.100000},{0.837500,0.037500,0.050000,0.050000},{0.837500,0.037500,0.100000,0.100000},{0.862500,0.037500,0.050000,0.050000},{0.862500,0.037500,0.100000,0.100000},{0.887500,0.037500,0.050000,0.050000},{0.887500,0.037500,0.100000,0.100000},{0.912500,0.037500,0.050000,0.050000},{0.912500,0.037500,0.100000,0.100000},{0.937500,0.037500,0.050000,0.050000},{0.937500,0.037500,0.100000,0.100000},{0.962500,0.037500,0.050000,0.050000},{0.962500,0.037500,0.100000,0.100000},{0.987500,0.037500,0.050000,0.050000},{0.987500,0.037500,0.100000,0.100000},{0.012500,0.062500,0.050000,0.050000},{0.012500,0.062500,0.100000,0.100000},{0.037500,0.062500,0.050000,0.050000},{0.037500,0.062500,0.100000,0.100000},{0.062500,0.062500,0.050000,0.050000},{0.062500,0.062500,0.100000,0.100000},{0.087500,0.062500,0.050000,0.050000},{0.087500,0.062500,0.100000,0.100000},{0.112500,0.062500,0.050000,0.050000},{0.112500,0.062500,0.100000,0.100000},{0.137500,0.062500,0.050000,0.050000},{0.137500,0.062500,0.100000,0.100000},{0.162500,0.062500,0.050000,0.050000},{0.162500,0.062500,0.100000,0.100000},{0.187500,0.062500,0.050000,0.050000},{0.187500,0.062500,0.100000,0.100000},{0.212500,0.062500,0.050000,0.050000},{0.212500,0.062500,0.100000,0.100000},{0.237500,0.062500,0.050000,0.050000},{0.237500,0.062500,0.100000,0.100000},{0.262500,0.062500,0.050000,0.050000},{0.262500,0.062500,0.100000,0.100000},{0.287500,0.062500,0.050000,0.050000},{0.287500,0.062500,0.100000,0.100000},{0.312500,0.062500,0.050000,0.050000},{0.312500,0.062500,0.100000,0.100000},{0.337500,0.062500,0.050000,0.050000},{0.337500,0.062500,0.100000,0.100000},{0.362500,0.062500,0.050000,0.050000},{0.362500,0.062500,0.100000,0.100000},{0.387500,0.062500,0.050000,0.050000},{0.387500,0.062500,0.100000,0.100000},{0.412500,0.062500,0.050000,0.050000},{0.412500,0.062500,0.100000,0.100000},{0.437500,0.062500,0.050000,0.050000},{0.437500,0.062500,0.100000,0.100000},{0.462500,0.062500,0.050000,0.050000},{0.462500,0.062500,0.100000,0.100000},{0.487500,0.062500,0.050000,0.050000},{0.487500,0.062500,0.100000,0.100000},{0.512500,0.062500,0.050000,0.050000},{0.512500,0.062500,0.100000,0.100000},{0.537500,0.062500,0.050000,0.050000},{0.537500,0.062500,0.100000,0.100000},{0.562500,0.062500,0.050000,0.050000},{0.562500,0.062500,0.100000,0.100000},{0.587500,0.062500,0.050000,0.050000},{0.587500,0.062500,0.100000,0.100000},{0.612500,0.062500,0.050000,0.050000},{0.612500,0.062500,0.100000,0.100000},{0.637500,0.062500,0.050000,0.050000},{0.637500,0.062500,0.100000,0.100000},{0.662500,0.062500,0.050000,0.050000},{0.662500,0.062500,0.100000,0.100000},{0.687500,0.062500,0.050000,0.050000},{0.687500,0.062500,0.100000,0.100000},{0.712500,0.062500,0.050000,0.050000},{0.712500,0.062500,0.100000,0.100000},{0.737500,0.062500,0.050000,0.050000},{0.737500,0.062500,0.100000,0.100000},{0.762500,0.062500,0.050000,0.050000},{0.762500,0.062500,0.100000,0.100000},{0.787500,0.062500,0.050000,0.050000},{0.787500,0.062500,0.100000,0.100000},{0.812500,0.062500,0.050000,0.050000},{0.812500,0.062500,0.100000,0.100000},{0.837500,0.062500,0.050000,0.050000},{0.837500,0.062500,0.100000,0.100000},{0.862500,0.062500,0.050000,0.050000},{0.862500,0.062500,0.100000,0.100000},{0.887500,0.062500,0.050000,0.050000},{0.887500,0.062500,0.100000,0.100000},{0.912500,0.062500,0.050000,0.050000},{0.912500,0.062500,0.100000,0.100000},{0.937500,0.062500,0.050000,0.050000},{0.937500,0.062500,0.100000,0.100000},{0.962500,0.062500,0.050000,0.050000},{0.962500,0.062500,0.100000,0.100000},{0.987500,0.062500,0.050000,0.050000},{0.987500,0.062500,0.100000,0.100000},{0.012500,0.087500,0.050000,0.050000},{0.012500,0.087500,0.100000,0.100000},{0.037500,0.087500,0.050000,0.050000},{0.037500,0.087500,0.100000,0.100000},{0.062500,0.087500,0.050000,0.050000},{0.062500,0.087500,0.100000,0.100000},{0.087500,0.087500,0.050000,0.050000},{0.087500,0.087500,0.100000,0.100000},{0.112500,0.087500,0.050000,0.050000},{0.112500,0.087500,0.100000,0.100000},{0.137500,0.087500,0.050000,0.050000},{0.137500,0.087500,0.100000,0.100000},{0.162500,0.087500,0.050000,0.050000},{0.162500,0.087500,0.100000,0.100000},{0.187500,0.087500,0.050000,0.050000},{0.187500,0.087500,0.100000,0.100000},{0.212500,0.087500,0.050000,0.050000},{0.212500,0.087500,0.100000,0.100000},{0.237500,0.087500,0.050000,0.050000},{0.237500,0.087500,0.100000,0.100000},{0.262500,0.087500,0.050000,0.050000},{0.262500,0.087500,0.100000,0.100000},{0.287500,0.087500,0.050000,0.050000},{0.287500,0.087500,0.100000,0.100000},{0.312500,0.087500,0.050000,0.050000},{0.312500,0.087500,0.100000,0.100000},{0.337500,0.087500,0.050000,0.050000},{0.337500,0.087500,0.100000,0.100000},{0.362500,0.087500,0.050000,0.050000},{0.362500,0.087500,0.100000,0.100000},{0.387500,0.087500,0.050000,0.050000},{0.387500,0.087500,0.100000,0.100000},{0.412500,0.087500,0.050000,0.050000},{0.412500,0.087500,0.100000,0.100000},{0.437500,0.087500,0.050000,0.050000},{0.437500,0.087500,0.100000,0.100000},{0.462500,0.087500,0.050000,0.050000},{0.462500,0.087500,0.100000,0.100000},{0.487500,0.087500,0.050000,0.050000},{0.487500,0.087500,0.100000,0.100000},{0.512500,0.087500,0.050000,0.050000},{0.512500,0.087500,0.100000,0.100000},{0.537500,0.087500,0.050000,0.050000},{0.537500,0.087500,0.100000,0.100000},{0.562500,0.087500,0.050000,0.050000},{0.562500,0.087500,0.100000,0.100000},{0.587500,0.087500,0.050000,0.050000},{0.587500,0.087500,0.100000,0.100000},{0.612500,0.087500,0.050000,0.050000},{0.612500,0.087500,0.100000,0.100000},{0.637500,0.087500,0.050000,0.050000},{0.637500,0.087500,0.100000,0.100000},{0.662500,0.087500,0.050000,0.050000},{0.662500,0.087500,0.100000,0.100000},{0.687500,0.087500,0.050000,0.050000},{0.687500,0.087500,0.100000,0.100000},{0.712500,0.087500,0.050000,0.050000},{0.712500,0.087500,0.100000,0.100000},{0.737500,0.087500,0.050000,0.050000},{0.737500,0.087500,0.100000,0.100000},{0.762500,0.087500,0.050000,0.050000},{0.762500,0.087500,0.100000,0.100000},{0.787500,0.087500,0.050000,0.050000},{0.787500,0.087500,0.100000,0.100000},{0.812500,0.087500,0.050000,0.050000},{0.812500,0.087500,0.100000,0.100000},{0.837500,0.087500,0.050000,0.050000},{0.837500,0.087500,0.100000,0.100000},{0.862500,0.087500,0.050000,0.050000},{0.862500,0.087500,0.100000,0.100000},{0.887500,0.087500,0.050000,0.050000},{0.887500,0.087500,0.100000,0.100000},{0.912500,0.087500,0.050000,0.050000},{0.912500,0.087500,0.100000,0.100000},{0.937500,0.087500,0.050000,0.050000},{0.937500,0.087500,0.100000,0.100000},{0.962500,0.087500,0.050000,0.050000},{0.962500,0.087500,0.100000,0.100000},{0.987500,0.087500,0.050000,0.050000},{0.987500,0.087500,0.100000,0.100000},{0.012500,0.112500,0.050000,0.050000},{0.012500,0.112500,0.100000,0.100000},{0.037500,0.112500,0.050000,0.050000},{0.037500,0.112500,0.100000,0.100000},{0.062500,0.112500,0.050000,0.050000},{0.062500,0.112500,0.100000,0.100000},{0.087500,0.112500,0.050000,0.050000},{0.087500,0.112500,0.100000,0.100000},{0.112500,0.112500,0.050000,0.050000},{0.112500,0.112500,0.100000,0.100000},{0.137500,0.112500,0.050000,0.050000},{0.137500,0.112500,0.100000,0.100000},{0.162500,0.112500,0.050000,0.050000},{0.162500,0.112500,0.100000,0.100000},{0.187500,0.112500,0.050000,0.050000},{0.187500,0.112500,0.100000,0.100000},{0.212500,0.112500,0.050000,0.050000},{0.212500,0.112500,0.100000,0.100000},{0.237500,0.112500,0.050000,0.050000},{0.237500,0.112500,0.100000,0.100000},{0.262500,0.112500,0.050000,0.050000},{0.262500,0.112500,0.100000,0.100000},{0.287500,0.112500,0.050000,0.050000},{0.287500,0.112500,0.100000,0.100000},{0.312500,0.112500,0.050000,0.050000},{0.312500,0.112500,0.100000,0.100000},{0.337500,0.112500,0.050000,0.050000},{0.337500,0.112500,0.100000,0.100000},{0.362500,0.112500,0.050000,0.050000},{0.362500,0.112500,0.100000,0.100000},{0.387500,0.112500,0.050000,0.050000},{0.387500,0.112500,0.100000,0.100000},{0.412500,0.112500,0.050000,0.050000},{0.412500,0.112500,0.100000,0.100000},{0.437500,0.112500,0.050000,0.050000},{0.437500,0.112500,0.100000,0.100000},{0.462500,0.112500,0.050000,0.050000},{0.462500,0.112500,0.100000,0.100000},{0.487500,0.112500,0.050000,0.050000},{0.487500,0.112500,0.100000,0.100000},{0.512500,0.112500,0.050000,0.050000},{0.512500,0.112500,0.100000,0.100000},{0.537500,0.112500,0.050000,0.050000},{0.537500,0.112500,0.100000,0.100000},{0.562500,0.112500,0.050000,0.050000},{0.562500,0.112500,0.100000,0.100000},{0.587500,0.112500,0.050000,0.050000},{0.587500,0.112500,0.100000,0.100000},{0.612500,0.112500,0.050000,0.050000},{0.612500,0.112500,0.100000,0.100000},{0.637500,0.112500,0.050000,0.050000},{0.637500,0.112500,0.100000,0.100000},{0.662500,0.112500,0.050000,0.050000},{0.662500,0.112500,0.100000,0.100000},{0.687500,0.112500,0.050000,0.050000},{0.687500,0.112500,0.100000,0.100000},{0.712500,0.112500,0.050000,0.050000},{0.712500,0.112500,0.100000,0.100000},{0.737500,0.112500,0.050000,0.050000},{0.737500,0.112500,0.100000,0.100000},{0.762500,0.112500,0.050000,0.050000},{0.762500,0.112500,0.100000,0.100000},{0.787500,0.112500,0.050000,0.050000},{0.787500,0.112500,0.100000,0.100000},{0.812500,0.112500,0.050000,0.050000},{0.812500,0.112500,0.100000,0.100000},{0.837500,0.112500,0.050000,0.050000},{0.837500,0.112500,0.100000,0.100000},{0.862500,0.112500,0.050000,0.050000},{0.862500,0.112500,0.100000,0.100000},{0.887500,0.112500,0.050000,0.050000},{0.887500,0.112500,0.100000,0.100000},{0.912500,0.112500,0.050000,0.050000},{0.912500,0.112500,0.100000,0.100000},{0.937500,0.112500,0.050000,0.050000},{0.937500,0.112500,0.100000,0.100000},{0.962500,0.112500,0.050000,0.050000},{0.962500,0.112500,0.100000,0.100000},{0.987500,0.112500,0.050000,0.050000},{0.987500,0.112500,0.100000,0.100000},{0.012500,0.137500,0.050000,0.050000},{0.012500,0.137500,0.100000,0.100000},{0.037500,0.137500,0.050000,0.050000},{0.037500,0.137500,0.100000,0.100000},{0.062500,0.137500,0.050000,0.050000},{0.062500,0.137500,0.100000,0.100000},{0.087500,0.137500,0.050000,0.050000},{0.087500,0.137500,0.100000,0.100000},{0.112500,0.137500,0.050000,0.050000},{0.112500,0.137500,0.100000,0.100000},{0.137500,0.137500,0.050000,0.050000},{0.137500,0.137500,0.100000,0.100000},{0.162500,0.137500,0.050000,0.050000},{0.162500,0.137500,0.100000,0.100000},{0.187500,0.137500,0.050000,0.050000},{0.187500,0.137500,0.100000,0.100000},{0.212500,0.137500,0.050000,0.050000},{0.212500,0.137500,0.100000,0.100000},{0.237500,0.137500,0.050000,0.050000},{0.237500,0.137500,0.100000,0.100000},{0.262500,0.137500,0.050000,0.050000},{0.262500,0.137500,0.100000,0.100000},{0.287500,0.137500,0.050000,0.050000},{0.287500,0.137500,0.100000,0.100000},{0.312500,0.137500,0.050000,0.050000},{0.312500,0.137500,0.100000,0.100000},{0.337500,0.137500,0.050000,0.050000},{0.337500,0.137500,0.100000,0.100000},{0.362500,0.137500,0.050000,0.050000},{0.362500,0.137500,0.100000,0.100000},{0.387500,0.137500,0.050000,0.050000},{0.387500,0.137500,0.100000,0.100000},{0.412500,0.137500,0.050000,0.050000},{0.412500,0.137500,0.100000,0.100000},{0.437500,0.137500,0.050000,0.050000},{0.437500,0.137500,0.100000,0.100000},{0.462500,0.137500,0.050000,0.050000},{0.462500,0.137500,0.100000,0.100000},{0.487500,0.137500,0.050000,0.050000},{0.487500,0.137500,0.100000,0.100000},{0.512500,0.137500,0.050000,0.050000},{0.512500,0.137500,0.100000,0.100000},{0.537500,0.137500,0.050000,0.050000},{0.537500,0.137500,0.100000,0.100000},{0.562500,0.137500,0.050000,0.050000},{0.562500,0.137500,0.100000,0.100000},{0.587500,0.137500,0.050000,0.050000},{0.587500,0.137500,0.100000,0.100000},{0.612500,0.137500,0.050000,0.050000},{0.612500,0.137500,0.100000,0.100000},{0.637500,0.137500,0.050000,0.050000},{0.637500,0.137500,0.100000,0.100000},{0.662500,0.137500,0.050000,0.050000},{0.662500,0.137500,0.100000,0.100000},{0.687500,0.137500,0.050000,0.050000},{0.687500,0.137500,0.100000,0.100000},{0.712500,0.137500,0.050000,0.050000},{0.712500,0.137500,0.100000,0.100000},{0.737500,0.137500,0.050000,0.050000},{0.737500,0.137500,0.100000,0.100000},{0.762500,0.137500,0.050000,0.050000},{0.762500,0.137500,0.100000,0.100000},{0.787500,0.137500,0.050000,0.050000},{0.787500,0.137500,0.100000,0.100000},{0.812500,0.137500,0.050000,0.050000},{0.812500,0.137500,0.100000,0.100000},{0.837500,0.137500,0.050000,0.050000},{0.837500,0.137500,0.100000,0.100000},{0.862500,0.137500,0.050000,0.050000},{0.862500,0.137500,0.100000,0.100000},{0.887500,0.137500,0.050000,0.050000},{0.887500,0.137500,0.100000,0.100000},{0.912500,0.137500,0.050000,0.050000},{0.912500,0.137500,0.100000,0.100000},{0.937500,0.137500,0.050000,0.050000},{0.937500,0.137500,0.100000,0.100000},{0.962500,0.137500,0.050000,0.050000},{0.962500,0.137500,0.100000,0.100000},{0.987500,0.137500,0.050000,0.050000},{0.987500,0.137500,0.100000,0.100000},{0.012500,0.162500,0.050000,0.050000},{0.012500,0.162500,0.100000,0.100000},{0.037500,0.162500,0.050000,0.050000},{0.037500,0.162500,0.100000,0.100000},{0.062500,0.162500,0.050000,0.050000},{0.062500,0.162500,0.100000,0.100000},{0.087500,0.162500,0.050000,0.050000},{0.087500,0.162500,0.100000,0.100000},{0.112500,0.162500,0.050000,0.050000},{0.112500,0.162500,0.100000,0.100000},{0.137500,0.162500,0.050000,0.050000},{0.137500,0.162500,0.100000,0.100000},{0.162500,0.162500,0.050000,0.050000},{0.162500,0.162500,0.100000,0.100000},{0.187500,0.162500,0.050000,0.050000},{0.187500,0.162500,0.100000,0.100000},{0.212500,0.162500,0.050000,0.050000},{0.212500,0.162500,0.100000,0.100000},{0.237500,0.162500,0.050000,0.050000},{0.237500,0.162500,0.100000,0.100000},{0.262500,0.162500,0.050000,0.050000},{0.262500,0.162500,0.100000,0.100000},{0.287500,0.162500,0.050000,0.050000},{0.287500,0.162500,0.100000,0.100000},{0.312500,0.162500,0.050000,0.050000},{0.312500,0.162500,0.100000,0.100000},{0.337500,0.162500,0.050000,0.050000},{0.337500,0.162500,0.100000,0.100000},{0.362500,0.162500,0.050000,0.050000},{0.362500,0.162500,0.100000,0.100000},{0.387500,0.162500,0.050000,0.050000},{0.387500,0.162500,0.100000,0.100000},{0.412500,0.162500,0.050000,0.050000},{0.412500,0.162500,0.100000,0.100000},{0.437500,0.162500,0.050000,0.050000},{0.437500,0.162500,0.100000,0.100000},{0.462500,0.162500,0.050000,0.050000},{0.462500,0.162500,0.100000,0.100000},{0.487500,0.162500,0.050000,0.050000},{0.487500,0.162500,0.100000,0.100000},{0.512500,0.162500,0.050000,0.050000},{0.512500,0.162500,0.100000,0.100000},{0.537500,0.162500,0.050000,0.050000},{0.537500,0.162500,0.100000,0.100000},{0.562500,0.162500,0.050000,0.050000},{0.562500,0.162500,0.100000,0.100000},{0.587500,0.162500,0.050000,0.050000},{0.587500,0.162500,0.100000,0.100000},{0.612500,0.162500,0.050000,0.050000},{0.612500,0.162500,0.100000,0.100000},{0.637500,0.162500,0.050000,0.050000},{0.637500,0.162500,0.100000,0.100000},{0.662500,0.162500,0.050000,0.050000},{0.662500,0.162500,0.100000,0.100000},{0.687500,0.162500,0.050000,0.050000},{0.687500,0.162500,0.100000,0.100000},{0.712500,0.162500,0.050000,0.050000},{0.712500,0.162500,0.100000,0.100000},{0.737500,0.162500,0.050000,0.050000},{0.737500,0.162500,0.100000,0.100000},{0.762500,0.162500,0.050000,0.050000},{0.762500,0.162500,0.100000,0.100000},{0.787500,0.162500,0.050000,0.050000},{0.787500,0.162500,0.100000,0.100000},{0.812500,0.162500,0.050000,0.050000},{0.812500,0.162500,0.100000,0.100000},{0.837500,0.162500,0.050000,0.050000},{0.837500,0.162500,0.100000,0.100000},{0.862500,0.162500,0.050000,0.050000},{0.862500,0.162500,0.100000,0.100000},{0.887500,0.162500,0.050000,0.050000},{0.887500,0.162500,0.100000,0.100000},{0.912500,0.162500,0.050000,0.050000},{0.912500,0.162500,0.100000,0.100000},{0.937500,0.162500,0.050000,0.050000},{0.937500,0.162500,0.100000,0.100000},{0.962500,0.162500,0.050000,0.050000},{0.962500,0.162500,0.100000,0.100000},{0.987500,0.162500,0.050000,0.050000},{0.987500,0.162500,0.100000,0.100000},{0.012500,0.187500,0.050000,0.050000},{0.012500,0.187500,0.100000,0.100000},{0.037500,0.187500,0.050000,0.050000},{0.037500,0.187500,0.100000,0.100000},{0.062500,0.187500,0.050000,0.050000},{0.062500,0.187500,0.100000,0.100000},{0.087500,0.187500,0.050000,0.050000},{0.087500,0.187500,0.100000,0.100000},{0.112500,0.187500,0.050000,0.050000},{0.112500,0.187500,0.100000,0.100000},{0.137500,0.187500,0.050000,0.050000},{0.137500,0.187500,0.100000,0.100000},{0.162500,0.187500,0.050000,0.050000},{0.162500,0.187500,0.100000,0.100000},{0.187500,0.187500,0.050000,0.050000},{0.187500,0.187500,0.100000,0.100000},{0.212500,0.187500,0.050000,0.050000},{0.212500,0.187500,0.100000,0.100000},{0.237500,0.187500,0.050000,0.050000},{0.237500,0.187500,0.100000,0.100000},{0.262500,0.187500,0.050000,0.050000},{0.262500,0.187500,0.100000,0.100000},{0.287500,0.187500,0.050000,0.050000},{0.287500,0.187500,0.100000,0.100000},{0.312500,0.187500,0.050000,0.050000},{0.312500,0.187500,0.100000,0.100000},{0.337500,0.187500,0.050000,0.050000},{0.337500,0.187500,0.100000,0.100000},{0.362500,0.187500,0.050000,0.050000},{0.362500,0.187500,0.100000,0.100000},{0.387500,0.187500,0.050000,0.050000},{0.387500,0.187500,0.100000,0.100000},{0.412500,0.187500,0.050000,0.050000},{0.412500,0.187500,0.100000,0.100000},{0.437500,0.187500,0.050000,0.050000},{0.437500,0.187500,0.100000,0.100000},{0.462500,0.187500,0.050000,0.050000},{0.462500,0.187500,0.100000,0.100000},{0.487500,0.187500,0.050000,0.050000},{0.487500,0.187500,0.100000,0.100000},{0.512500,0.187500,0.050000,0.050000},{0.512500,0.187500,0.100000,0.100000},{0.537500,0.187500,0.050000,0.050000},{0.537500,0.187500,0.100000,0.100000},{0.562500,0.187500,0.050000,0.050000},{0.562500,0.187500,0.100000,0.100000},{0.587500,0.187500,0.050000,0.050000},{0.587500,0.187500,0.100000,0.100000},{0.612500,0.187500,0.050000,0.050000},{0.612500,0.187500,0.100000,0.100000},{0.637500,0.187500,0.050000,0.050000},{0.637500,0.187500,0.100000,0.100000},{0.662500,0.187500,0.050000,0.050000},{0.662500,0.187500,0.100000,0.100000},{0.687500,0.187500,0.050000,0.050000},{0.687500,0.187500,0.100000,0.100000},{0.712500,0.187500,0.050000,0.050000},{0.712500,0.187500,0.100000,0.100000},{0.737500,0.187500,0.050000,0.050000},{0.737500,0.187500,0.100000,0.100000},{0.762500,0.187500,0.050000,0.050000},{0.762500,0.187500,0.100000,0.100000},{0.787500,0.187500,0.050000,0.050000},{0.787500,0.187500,0.100000,0.100000},{0.812500,0.187500,0.050000,0.050000},{0.812500,0.187500,0.100000,0.100000},{0.837500,0.187500,0.050000,0.050000},{0.837500,0.187500,0.100000,0.100000},{0.862500,0.187500,0.050000,0.050000},{0.862500,0.187500,0.100000,0.100000},{0.887500,0.187500,0.050000,0.050000},{0.887500,0.187500,0.100000,0.100000},{0.912500,0.187500,0.050000,0.050000},{0.912500,0.187500,0.100000,0.100000},{0.937500,0.187500,0.050000,0.050000},{0.937500,0.187500,0.100000,0.100000},{0.962500,0.187500,0.050000,0.050000},{0.962500,0.187500,0.100000,0.100000},{0.987500,0.187500,0.050000,0.050000},{0.987500,0.187500,0.100000,0.100000},{0.012500,0.212500,0.050000,0.050000},{0.012500,0.212500,0.100000,0.100000},{0.037500,0.212500,0.050000,0.050000},{0.037500,0.212500,0.100000,0.100000},{0.062500,0.212500,0.050000,0.050000},{0.062500,0.212500,0.100000,0.100000},{0.087500,0.212500,0.050000,0.050000},{0.087500,0.212500,0.100000,0.100000},{0.112500,0.212500,0.050000,0.050000},{0.112500,0.212500,0.100000,0.100000},{0.137500,0.212500,0.050000,0.050000},{0.137500,0.212500,0.100000,0.100000},{0.162500,0.212500,0.050000,0.050000},{0.162500,0.212500,0.100000,0.100000},{0.187500,0.212500,0.050000,0.050000},{0.187500,0.212500,0.100000,0.100000},{0.212500,0.212500,0.050000,0.050000},{0.212500,0.212500,0.100000,0.100000},{0.237500,0.212500,0.050000,0.050000},{0.237500,0.212500,0.100000,0.100000},{0.262500,0.212500,0.050000,0.050000},{0.262500,0.212500,0.100000,0.100000},{0.287500,0.212500,0.050000,0.050000},{0.287500,0.212500,0.100000,0.100000},{0.312500,0.212500,0.050000,0.050000},{0.312500,0.212500,0.100000,0.100000},{0.337500,0.212500,0.050000,0.050000},{0.337500,0.212500,0.100000,0.100000},{0.362500,0.212500,0.050000,0.050000},{0.362500,0.212500,0.100000,0.100000},{0.387500,0.212500,0.050000,0.050000},{0.387500,0.212500,0.100000,0.100000},{0.412500,0.212500,0.050000,0.050000},{0.412500,0.212500,0.100000,0.100000},{0.437500,0.212500,0.050000,0.050000},{0.437500,0.212500,0.100000,0.100000},{0.462500,0.212500,0.050000,0.050000},{0.462500,0.212500,0.100000,0.100000},{0.487500,0.212500,0.050000,0.050000},{0.487500,0.212500,0.100000,0.100000},{0.512500,0.212500,0.050000,0.050000},{0.512500,0.212500,0.100000,0.100000},{0.537500,0.212500,0.050000,0.050000},{0.537500,0.212500,0.100000,0.100000},{0.562500,0.212500,0.050000,0.050000},{0.562500,0.212500,0.100000,0.100000},{0.587500,0.212500,0.050000,0.050000},{0.587500,0.212500,0.100000,0.100000},{0.612500,0.212500,0.050000,0.050000},{0.612500,0.212500,0.100000,0.100000},{0.637500,0.212500,0.050000,0.050000},{0.637500,0.212500,0.100000,0.100000},{0.662500,0.212500,0.050000,0.050000},{0.662500,0.212500,0.100000,0.100000},{0.687500,0.212500,0.050000,0.050000},{0.687500,0.212500,0.100000,0.100000},{0.712500,0.212500,0.050000,0.050000},{0.712500,0.212500,0.100000,0.100000},{0.737500,0.212500,0.050000,0.050000},{0.737500,0.212500,0.100000,0.100000},{0.762500,0.212500,0.050000,0.050000},{0.762500,0.212500,0.100000,0.100000},{0.787500,0.212500,0.050000,0.050000},{0.787500,0.212500,0.100000,0.100000},{0.812500,0.212500,0.050000,0.050000},{0.812500,0.212500,0.100000,0.100000},{0.837500,0.212500,0.050000,0.050000},{0.837500,0.212500,0.100000,0.100000},{0.862500,0.212500,0.050000,0.050000},{0.862500,0.212500,0.100000,0.100000},{0.887500,0.212500,0.050000,0.050000},{0.887500,0.212500,0.100000,0.100000},{0.912500,0.212500,0.050000,0.050000},{0.912500,0.212500,0.100000,0.100000},{0.937500,0.212500,0.050000,0.050000},{0.937500,0.212500,0.100000,0.100000},{0.962500,0.212500,0.050000,0.050000},{0.962500,0.212500,0.100000,0.100000},{0.987500,0.212500,0.050000,0.050000},{0.987500,0.212500,0.100000,0.100000},{0.012500,0.237500,0.050000,0.050000},{0.012500,0.237500,0.100000,0.100000},{0.037500,0.237500,0.050000,0.050000},{0.037500,0.237500,0.100000,0.100000},{0.062500,0.237500,0.050000,0.050000},{0.062500,0.237500,0.100000,0.100000},{0.087500,0.237500,0.050000,0.050000},{0.087500,0.237500,0.100000,0.100000},{0.112500,0.237500,0.050000,0.050000},{0.112500,0.237500,0.100000,0.100000},{0.137500,0.237500,0.050000,0.050000},{0.137500,0.237500,0.100000,0.100000},{0.162500,0.237500,0.050000,0.050000},{0.162500,0.237500,0.100000,0.100000},{0.187500,0.237500,0.050000,0.050000},{0.187500,0.237500,0.100000,0.100000},{0.212500,0.237500,0.050000,0.050000},{0.212500,0.237500,0.100000,0.100000},{0.237500,0.237500,0.050000,0.050000},{0.237500,0.237500,0.100000,0.100000},{0.262500,0.237500,0.050000,0.050000},{0.262500,0.237500,0.100000,0.100000},{0.287500,0.237500,0.050000,0.050000},{0.287500,0.237500,0.100000,0.100000},{0.312500,0.237500,0.050000,0.050000},{0.312500,0.237500,0.100000,0.100000},{0.337500,0.237500,0.050000,0.050000},{0.337500,0.237500,0.100000,0.100000},{0.362500,0.237500,0.050000,0.050000},{0.362500,0.237500,0.100000,0.100000},{0.387500,0.237500,0.050000,0.050000},{0.387500,0.237500,0.100000,0.100000},{0.412500,0.237500,0.050000,0.050000},{0.412500,0.237500,0.100000,0.100000},{0.437500,0.237500,0.050000,0.050000},{0.437500,0.237500,0.100000,0.100000},{0.462500,0.237500,0.050000,0.050000},{0.462500,0.237500,0.100000,0.100000},{0.487500,0.237500,0.050000,0.050000},{0.487500,0.237500,0.100000,0.100000},{0.512500,0.237500,0.050000,0.050000},{0.512500,0.237500,0.100000,0.100000},{0.537500,0.237500,0.050000,0.050000},{0.537500,0.237500,0.100000,0.100000},{0.562500,0.237500,0.050000,0.050000},{0.562500,0.237500,0.100000,0.100000},{0.587500,0.237500,0.050000,0.050000},{0.587500,0.237500,0.100000,0.100000},{0.612500,0.237500,0.050000,0.050000},{0.612500,0.237500,0.100000,0.100000},{0.637500,0.237500,0.050000,0.050000},{0.637500,0.237500,0.100000,0.100000},{0.662500,0.237500,0.050000,0.050000},{0.662500,0.237500,0.100000,0.100000},{0.687500,0.237500,0.050000,0.050000},{0.687500,0.237500,0.100000,0.100000},{0.712500,0.237500,0.050000,0.050000},{0.712500,0.237500,0.100000,0.100000},{0.737500,0.237500,0.050000,0.050000},{0.737500,0.237500,0.100000,0.100000},{0.762500,0.237500,0.050000,0.050000},{0.762500,0.237500,0.100000,0.100000},{0.787500,0.237500,0.050000,0.050000},{0.787500,0.237500,0.100000,0.100000},{0.812500,0.237500,0.050000,0.050000},{0.812500,0.237500,0.100000,0.100000},{0.837500,0.237500,0.050000,0.050000},{0.837500,0.237500,0.100000,0.100000},{0.862500,0.237500,0.050000,0.050000},{0.862500,0.237500,0.100000,0.100000},{0.887500,0.237500,0.050000,0.050000},{0.887500,0.237500,0.100000,0.100000},{0.912500,0.237500,0.050000,0.050000},{0.912500,0.237500,0.100000,0.100000},{0.937500,0.237500,0.050000,0.050000},{0.937500,0.237500,0.100000,0.100000},{0.962500,0.237500,0.050000,0.050000},{0.962500,0.237500,0.100000,0.100000},{0.987500,0.237500,0.050000,0.050000},{0.987500,0.237500,0.100000,0.100000},{0.012500,0.262500,0.050000,0.050000},{0.012500,0.262500,0.100000,0.100000},{0.037500,0.262500,0.050000,0.050000},{0.037500,0.262500,0.100000,0.100000},{0.062500,0.262500,0.050000,0.050000},{0.062500,0.262500,0.100000,0.100000},{0.087500,0.262500,0.050000,0.050000},{0.087500,0.262500,0.100000,0.100000},{0.112500,0.262500,0.050000,0.050000},{0.112500,0.262500,0.100000,0.100000},{0.137500,0.262500,0.050000,0.050000},{0.137500,0.262500,0.100000,0.100000},{0.162500,0.262500,0.050000,0.050000},{0.162500,0.262500,0.100000,0.100000},{0.187500,0.262500,0.050000,0.050000},{0.187500,0.262500,0.100000,0.100000},{0.212500,0.262500,0.050000,0.050000},{0.212500,0.262500,0.100000,0.100000},{0.237500,0.262500,0.050000,0.050000},{0.237500,0.262500,0.100000,0.100000},{0.262500,0.262500,0.050000,0.050000},{0.262500,0.262500,0.100000,0.100000},{0.287500,0.262500,0.050000,0.050000},{0.287500,0.262500,0.100000,0.100000},{0.312500,0.262500,0.050000,0.050000},{0.312500,0.262500,0.100000,0.100000},{0.337500,0.262500,0.050000,0.050000},{0.337500,0.262500,0.100000,0.100000},{0.362500,0.262500,0.050000,0.050000},{0.362500,0.262500,0.100000,0.100000},{0.387500,0.262500,0.050000,0.050000},{0.387500,0.262500,0.100000,0.100000},{0.412500,0.262500,0.050000,0.050000},{0.412500,0.262500,0.100000,0.100000},{0.437500,0.262500,0.050000,0.050000},{0.437500,0.262500,0.100000,0.100000},{0.462500,0.262500,0.050000,0.050000},{0.462500,0.262500,0.100000,0.100000},{0.487500,0.262500,0.050000,0.050000},{0.487500,0.262500,0.100000,0.100000},{0.512500,0.262500,0.050000,0.050000},{0.512500,0.262500,0.100000,0.100000},{0.537500,0.262500,0.050000,0.050000},{0.537500,0.262500,0.100000,0.100000},{0.562500,0.262500,0.050000,0.050000},{0.562500,0.262500,0.100000,0.100000},{0.587500,0.262500,0.050000,0.050000},{0.587500,0.262500,0.100000,0.100000},{0.612500,0.262500,0.050000,0.050000},{0.612500,0.262500,0.100000,0.100000},{0.637500,0.262500,0.050000,0.050000},{0.637500,0.262500,0.100000,0.100000},{0.662500,0.262500,0.050000,0.050000},{0.662500,0.262500,0.100000,0.100000},{0.687500,0.262500,0.050000,0.050000},{0.687500,0.262500,0.100000,0.100000},{0.712500,0.262500,0.050000,0.050000},{0.712500,0.262500,0.100000,0.100000},{0.737500,0.262500,0.050000,0.050000},{0.737500,0.262500,0.100000,0.100000},{0.762500,0.262500,0.050000,0.050000},{0.762500,0.262500,0.100000,0.100000},{0.787500,0.262500,0.050000,0.050000},{0.787500,0.262500,0.100000,0.100000},{0.812500,0.262500,0.050000,0.050000},{0.812500,0.262500,0.100000,0.100000},{0.837500,0.262500,0.050000,0.050000},{0.837500,0.262500,0.100000,0.100000},{0.862500,0.262500,0.050000,0.050000},{0.862500,0.262500,0.100000,0.100000},{0.887500,0.262500,0.050000,0.050000},{0.887500,0.262500,0.100000,0.100000},{0.912500,0.262500,0.050000,0.050000},{0.912500,0.262500,0.100000,0.100000},{0.937500,0.262500,0.050000,0.050000},{0.937500,0.262500,0.100000,0.100000},{0.962500,0.262500,0.050000,0.050000},{0.962500,0.262500,0.100000,0.100000},{0.987500,0.262500,0.050000,0.050000},{0.987500,0.262500,0.100000,0.100000},{0.012500,0.287500,0.050000,0.050000},{0.012500,0.287500,0.100000,0.100000},{0.037500,0.287500,0.050000,0.050000},{0.037500,0.287500,0.100000,0.100000},{0.062500,0.287500,0.050000,0.050000},{0.062500,0.287500,0.100000,0.100000},{0.087500,0.287500,0.050000,0.050000},{0.087500,0.287500,0.100000,0.100000},{0.112500,0.287500,0.050000,0.050000},{0.112500,0.287500,0.100000,0.100000},{0.137500,0.287500,0.050000,0.050000},{0.137500,0.287500,0.100000,0.100000},{0.162500,0.287500,0.050000,0.050000},{0.162500,0.287500,0.100000,0.100000},{0.187500,0.287500,0.050000,0.050000},{0.187500,0.287500,0.100000,0.100000},{0.212500,0.287500,0.050000,0.050000},{0.212500,0.287500,0.100000,0.100000},{0.237500,0.287500,0.050000,0.050000},{0.237500,0.287500,0.100000,0.100000},{0.262500,0.287500,0.050000,0.050000},{0.262500,0.287500,0.100000,0.100000},{0.287500,0.287500,0.050000,0.050000},{0.287500,0.287500,0.100000,0.100000},{0.312500,0.287500,0.050000,0.050000},{0.312500,0.287500,0.100000,0.100000},{0.337500,0.287500,0.050000,0.050000},{0.337500,0.287500,0.100000,0.100000},{0.362500,0.287500,0.050000,0.050000},{0.362500,0.287500,0.100000,0.100000},{0.387500,0.287500,0.050000,0.050000},{0.387500,0.287500,0.100000,0.100000},{0.412500,0.287500,0.050000,0.050000},{0.412500,0.287500,0.100000,0.100000},{0.437500,0.287500,0.050000,0.050000},{0.437500,0.287500,0.100000,0.100000},{0.462500,0.287500,0.050000,0.050000},{0.462500,0.287500,0.100000,0.100000},{0.487500,0.287500,0.050000,0.050000},{0.487500,0.287500,0.100000,0.100000},{0.512500,0.287500,0.050000,0.050000},{0.512500,0.287500,0.100000,0.100000},{0.537500,0.287500,0.050000,0.050000},{0.537500,0.287500,0.100000,0.100000},{0.562500,0.287500,0.050000,0.050000},{0.562500,0.287500,0.100000,0.100000},{0.587500,0.287500,0.050000,0.050000},{0.587500,0.287500,0.100000,0.100000},{0.612500,0.287500,0.050000,0.050000},{0.612500,0.287500,0.100000,0.100000},{0.637500,0.287500,0.050000,0.050000},{0.637500,0.287500,0.100000,0.100000},{0.662500,0.287500,0.050000,0.050000},{0.662500,0.287500,0.100000,0.100000},{0.687500,0.287500,0.050000,0.050000},{0.687500,0.287500,0.100000,0.100000},{0.712500,0.287500,0.050000,0.050000},{0.712500,0.287500,0.100000,0.100000},{0.737500,0.287500,0.050000,0.050000},{0.737500,0.287500,0.100000,0.100000},{0.762500,0.287500,0.050000,0.050000},{0.762500,0.287500,0.100000,0.100000},{0.787500,0.287500,0.050000,0.050000},{0.787500,0.287500,0.100000,0.100000},{0.812500,0.287500,0.050000,0.050000},{0.812500,0.287500,0.100000,0.100000},{0.837500,0.287500,0.050000,0.050000},{0.837500,0.287500,0.100000,0.100000},{0.862500,0.287500,0.050000,0.050000},{0.862500,0.287500,0.100000,0.100000},{0.887500,0.287500,0.050000,0.050000},{0.887500,0.287500,0.100000,0.100000},{0.912500,0.287500,0.050000,0.050000},{0.912500,0.287500,0.100000,0.100000},{0.937500,0.287500,0.050000,0.050000},{0.937500,0.287500,0.100000,0.100000},{0.962500,0.287500,0.050000,0.050000},{0.962500,0.287500,0.100000,0.100000},{0.987500,0.287500,0.050000,0.050000},{0.987500,0.287500,0.100000,0.100000},{0.012500,0.312500,0.050000,0.050000},{0.012500,0.312500,0.100000,0.100000},{0.037500,0.312500,0.050000,0.050000},{0.037500,0.312500,0.100000,0.100000},{0.062500,0.312500,0.050000,0.050000},{0.062500,0.312500,0.100000,0.100000},{0.087500,0.312500,0.050000,0.050000},{0.087500,0.312500,0.100000,0.100000},{0.112500,0.312500,0.050000,0.050000},{0.112500,0.312500,0.100000,0.100000},{0.137500,0.312500,0.050000,0.050000},{0.137500,0.312500,0.100000,0.100000},{0.162500,0.312500,0.050000,0.050000},{0.162500,0.312500,0.100000,0.100000},{0.187500,0.312500,0.050000,0.050000},{0.187500,0.312500,0.100000,0.100000},{0.212500,0.312500,0.050000,0.050000},{0.212500,0.312500,0.100000,0.100000},{0.237500,0.312500,0.050000,0.050000},{0.237500,0.312500,0.100000,0.100000},{0.262500,0.312500,0.050000,0.050000},{0.262500,0.312500,0.100000,0.100000},{0.287500,0.312500,0.050000,0.050000},{0.287500,0.312500,0.100000,0.100000},{0.312500,0.312500,0.050000,0.050000},{0.312500,0.312500,0.100000,0.100000},{0.337500,0.312500,0.050000,0.050000},{0.337500,0.312500,0.100000,0.100000},{0.362500,0.312500,0.050000,0.050000},{0.362500,0.312500,0.100000,0.100000},{0.387500,0.312500,0.050000,0.050000},{0.387500,0.312500,0.100000,0.100000},{0.412500,0.312500,0.050000,0.050000},{0.412500,0.312500,0.100000,0.100000},{0.437500,0.312500,0.050000,0.050000},{0.437500,0.312500,0.100000,0.100000},{0.462500,0.312500,0.050000,0.050000},{0.462500,0.312500,0.100000,0.100000},{0.487500,0.312500,0.050000,0.050000},{0.487500,0.312500,0.100000,0.100000},{0.512500,0.312500,0.050000,0.050000},{0.512500,0.312500,0.100000,0.100000},{0.537500,0.312500,0.050000,0.050000},{0.537500,0.312500,0.100000,0.100000},{0.562500,0.312500,0.050000,0.050000},{0.562500,0.312500,0.100000,0.100000},{0.587500,0.312500,0.050000,0.050000},{0.587500,0.312500,0.100000,0.100000},{0.612500,0.312500,0.050000,0.050000},{0.612500,0.312500,0.100000,0.100000},{0.637500,0.312500,0.050000,0.050000},{0.637500,0.312500,0.100000,0.100000},{0.662500,0.312500,0.050000,0.050000},{0.662500,0.312500,0.100000,0.100000},{0.687500,0.312500,0.050000,0.050000},{0.687500,0.312500,0.100000,0.100000},{0.712500,0.312500,0.050000,0.050000},{0.712500,0.312500,0.100000,0.100000},{0.737500,0.312500,0.050000,0.050000},{0.737500,0.312500,0.100000,0.100000},{0.762500,0.312500,0.050000,0.050000},{0.762500,0.312500,0.100000,0.100000},{0.787500,0.312500,0.050000,0.050000},{0.787500,0.312500,0.100000,0.100000},{0.812500,0.312500,0.050000,0.050000},{0.812500,0.312500,0.100000,0.100000},{0.837500,0.312500,0.050000,0.050000},{0.837500,0.312500,0.100000,0.100000},{0.862500,0.312500,0.050000,0.050000},{0.862500,0.312500,0.100000,0.100000},{0.887500,0.312500,0.050000,0.050000},{0.887500,0.312500,0.100000,0.100000},{0.912500,0.312500,0.050000,0.050000},{0.912500,0.312500,0.100000,0.100000},{0.937500,0.312500,0.050000,0.050000},{0.937500,0.312500,0.100000,0.100000},{0.962500,0.312500,0.050000,0.050000},{0.962500,0.312500,0.100000,0.100000},{0.987500,0.312500,0.050000,0.050000},{0.987500,0.312500,0.100000,0.100000},{0.012500,0.337500,0.050000,0.050000},{0.012500,0.337500,0.100000,0.100000},{0.037500,0.337500,0.050000,0.050000},{0.037500,0.337500,0.100000,0.100000},{0.062500,0.337500,0.050000,0.050000},{0.062500,0.337500,0.100000,0.100000},{0.087500,0.337500,0.050000,0.050000},{0.087500,0.337500,0.100000,0.100000},{0.112500,0.337500,0.050000,0.050000},{0.112500,0.337500,0.100000,0.100000},{0.137500,0.337500,0.050000,0.050000},{0.137500,0.337500,0.100000,0.100000},{0.162500,0.337500,0.050000,0.050000},{0.162500,0.337500,0.100000,0.100000},{0.187500,0.337500,0.050000,0.050000},{0.187500,0.337500,0.100000,0.100000},{0.212500,0.337500,0.050000,0.050000},{0.212500,0.337500,0.100000,0.100000},{0.237500,0.337500,0.050000,0.050000},{0.237500,0.337500,0.100000,0.100000},{0.262500,0.337500,0.050000,0.050000},{0.262500,0.337500,0.100000,0.100000},{0.287500,0.337500,0.050000,0.050000},{0.287500,0.337500,0.100000,0.100000},{0.312500,0.337500,0.050000,0.050000},{0.312500,0.337500,0.100000,0.100000},{0.337500,0.337500,0.050000,0.050000},{0.337500,0.337500,0.100000,0.100000},{0.362500,0.337500,0.050000,0.050000},{0.362500,0.337500,0.100000,0.100000},{0.387500,0.337500,0.050000,0.050000},{0.387500,0.337500,0.100000,0.100000},{0.412500,0.337500,0.050000,0.050000},{0.412500,0.337500,0.100000,0.100000},{0.437500,0.337500,0.050000,0.050000},{0.437500,0.337500,0.100000,0.100000},{0.462500,0.337500,0.050000,0.050000},{0.462500,0.337500,0.100000,0.100000},{0.487500,0.337500,0.050000,0.050000},{0.487500,0.337500,0.100000,0.100000},{0.512500,0.337500,0.050000,0.050000},{0.512500,0.337500,0.100000,0.100000},{0.537500,0.337500,0.050000,0.050000},{0.537500,0.337500,0.100000,0.100000},{0.562500,0.337500,0.050000,0.050000},{0.562500,0.337500,0.100000,0.100000},{0.587500,0.337500,0.050000,0.050000},{0.587500,0.337500,0.100000,0.100000},{0.612500,0.337500,0.050000,0.050000},{0.612500,0.337500,0.100000,0.100000},{0.637500,0.337500,0.050000,0.050000},{0.637500,0.337500,0.100000,0.100000},{0.662500,0.337500,0.050000,0.050000},{0.662500,0.337500,0.100000,0.100000},{0.687500,0.337500,0.050000,0.050000},{0.687500,0.337500,0.100000,0.100000},{0.712500,0.337500,0.050000,0.050000},{0.712500,0.337500,0.100000,0.100000},{0.737500,0.337500,0.050000,0.050000},{0.737500,0.337500,0.100000,0.100000},{0.762500,0.337500,0.050000,0.050000},{0.762500,0.337500,0.100000,0.100000},{0.787500,0.337500,0.050000,0.050000},{0.787500,0.337500,0.100000,0.100000},{0.812500,0.337500,0.050000,0.050000},{0.812500,0.337500,0.100000,0.100000},{0.837500,0.337500,0.050000,0.050000},{0.837500,0.337500,0.100000,0.100000},{0.862500,0.337500,0.050000,0.050000},{0.862500,0.337500,0.100000,0.100000},{0.887500,0.337500,0.050000,0.050000},{0.887500,0.337500,0.100000,0.100000},{0.912500,0.337500,0.050000,0.050000},{0.912500,0.337500,0.100000,0.100000},{0.937500,0.337500,0.050000,0.050000},{0.937500,0.337500,0.100000,0.100000},{0.962500,0.337500,0.050000,0.050000},{0.962500,0.337500,0.100000,0.100000},{0.987500,0.337500,0.050000,0.050000},{0.987500,0.337500,0.100000,0.100000},{0.012500,0.362500,0.050000,0.050000},{0.012500,0.362500,0.100000,0.100000},{0.037500,0.362500,0.050000,0.050000},{0.037500,0.362500,0.100000,0.100000},{0.062500,0.362500,0.050000,0.050000},{0.062500,0.362500,0.100000,0.100000},{0.087500,0.362500,0.050000,0.050000},{0.087500,0.362500,0.100000,0.100000},{0.112500,0.362500,0.050000,0.050000},{0.112500,0.362500,0.100000,0.100000},{0.137500,0.362500,0.050000,0.050000},{0.137500,0.362500,0.100000,0.100000},{0.162500,0.362500,0.050000,0.050000},{0.162500,0.362500,0.100000,0.100000},{0.187500,0.362500,0.050000,0.050000},{0.187500,0.362500,0.100000,0.100000},{0.212500,0.362500,0.050000,0.050000},{0.212500,0.362500,0.100000,0.100000},{0.237500,0.362500,0.050000,0.050000},{0.237500,0.362500,0.100000,0.100000},{0.262500,0.362500,0.050000,0.050000},{0.262500,0.362500,0.100000,0.100000},{0.287500,0.362500,0.050000,0.050000},{0.287500,0.362500,0.100000,0.100000},{0.312500,0.362500,0.050000,0.050000},{0.312500,0.362500,0.100000,0.100000},{0.337500,0.362500,0.050000,0.050000},{0.337500,0.362500,0.100000,0.100000},{0.362500,0.362500,0.050000,0.050000},{0.362500,0.362500,0.100000,0.100000},{0.387500,0.362500,0.050000,0.050000},{0.387500,0.362500,0.100000,0.100000},{0.412500,0.362500,0.050000,0.050000},{0.412500,0.362500,0.100000,0.100000},{0.437500,0.362500,0.050000,0.050000},{0.437500,0.362500,0.100000,0.100000},{0.462500,0.362500,0.050000,0.050000},{0.462500,0.362500,0.100000,0.100000},{0.487500,0.362500,0.050000,0.050000},{0.487500,0.362500,0.100000,0.100000},{0.512500,0.362500,0.050000,0.050000},{0.512500,0.362500,0.100000,0.100000},{0.537500,0.362500,0.050000,0.050000},{0.537500,0.362500,0.100000,0.100000},{0.562500,0.362500,0.050000,0.050000},{0.562500,0.362500,0.100000,0.100000},{0.587500,0.362500,0.050000,0.050000},{0.587500,0.362500,0.100000,0.100000},{0.612500,0.362500,0.050000,0.050000},{0.612500,0.362500,0.100000,0.100000},{0.637500,0.362500,0.050000,0.050000},{0.637500,0.362500,0.100000,0.100000},{0.662500,0.362500,0.050000,0.050000},{0.662500,0.362500,0.100000,0.100000},{0.687500,0.362500,0.050000,0.050000},{0.687500,0.362500,0.100000,0.100000},{0.712500,0.362500,0.050000,0.050000},{0.712500,0.362500,0.100000,0.100000},{0.737500,0.362500,0.050000,0.050000},{0.737500,0.362500,0.100000,0.100000},{0.762500,0.362500,0.050000,0.050000},{0.762500,0.362500,0.100000,0.100000},{0.787500,0.362500,0.050000,0.050000},{0.787500,0.362500,0.100000,0.100000},{0.812500,0.362500,0.050000,0.050000},{0.812500,0.362500,0.100000,0.100000},{0.837500,0.362500,0.050000,0.050000},{0.837500,0.362500,0.100000,0.100000},{0.862500,0.362500,0.050000,0.050000},{0.862500,0.362500,0.100000,0.100000},{0.887500,0.362500,0.050000,0.050000},{0.887500,0.362500,0.100000,0.100000},{0.912500,0.362500,0.050000,0.050000},{0.912500,0.362500,0.100000,0.100000},{0.937500,0.362500,0.050000,0.050000},{0.937500,0.362500,0.100000,0.100000},{0.962500,0.362500,0.050000,0.050000},{0.962500,0.362500,0.100000,0.100000},{0.987500,0.362500,0.050000,0.050000},{0.987500,0.362500,0.100000,0.100000},{0.012500,0.387500,0.050000,0.050000},{0.012500,0.387500,0.100000,0.100000},{0.037500,0.387500,0.050000,0.050000},{0.037500,0.387500,0.100000,0.100000},{0.062500,0.387500,0.050000,0.050000},{0.062500,0.387500,0.100000,0.100000},{0.087500,0.387500,0.050000,0.050000},{0.087500,0.387500,0.100000,0.100000},{0.112500,0.387500,0.050000,0.050000},{0.112500,0.387500,0.100000,0.100000},{0.137500,0.387500,0.050000,0.050000},{0.137500,0.387500,0.100000,0.100000},{0.162500,0.387500,0.050000,0.050000},{0.162500,0.387500,0.100000,0.100000},{0.187500,0.387500,0.050000,0.050000},{0.187500,0.387500,0.100000,0.100000},{0.212500,0.387500,0.050000,0.050000},{0.212500,0.387500,0.100000,0.100000},{0.237500,0.387500,0.050000,0.050000},{0.237500,0.387500,0.100000,0.100000},{0.262500,0.387500,0.050000,0.050000},{0.262500,0.387500,0.100000,0.100000},{0.287500,0.387500,0.050000,0.050000},{0.287500,0.387500,0.100000,0.100000},{0.312500,0.387500,0.050000,0.050000},{0.312500,0.387500,0.100000,0.100000},{0.337500,0.387500,0.050000,0.050000},{0.337500,0.387500,0.100000,0.100000},{0.362500,0.387500,0.050000,0.050000},{0.362500,0.387500,0.100000,0.100000},{0.387500,0.387500,0.050000,0.050000},{0.387500,0.387500,0.100000,0.100000},{0.412500,0.387500,0.050000,0.050000},{0.412500,0.387500,0.100000,0.100000},{0.437500,0.387500,0.050000,0.050000},{0.437500,0.387500,0.100000,0.100000},{0.462500,0.387500,0.050000,0.050000},{0.462500,0.387500,0.100000,0.100000},{0.487500,0.387500,0.050000,0.050000},{0.487500,0.387500,0.100000,0.100000},{0.512500,0.387500,0.050000,0.050000},{0.512500,0.387500,0.100000,0.100000},{0.537500,0.387500,0.050000,0.050000},{0.537500,0.387500,0.100000,0.100000},{0.562500,0.387500,0.050000,0.050000},{0.562500,0.387500,0.100000,0.100000},{0.587500,0.387500,0.050000,0.050000},{0.587500,0.387500,0.100000,0.100000},{0.612500,0.387500,0.050000,0.050000},{0.612500,0.387500,0.100000,0.100000},{0.637500,0.387500,0.050000,0.050000},{0.637500,0.387500,0.100000,0.100000},{0.662500,0.387500,0.050000,0.050000},{0.662500,0.387500,0.100000,0.100000},{0.687500,0.387500,0.050000,0.050000},{0.687500,0.387500,0.100000,0.100000},{0.712500,0.387500,0.050000,0.050000},{0.712500,0.387500,0.100000,0.100000},{0.737500,0.387500,0.050000,0.050000},{0.737500,0.387500,0.100000,0.100000},{0.762500,0.387500,0.050000,0.050000},{0.762500,0.387500,0.100000,0.100000},{0.787500,0.387500,0.050000,0.050000},{0.787500,0.387500,0.100000,0.100000},{0.812500,0.387500,0.050000,0.050000},{0.812500,0.387500,0.100000,0.100000},{0.837500,0.387500,0.050000,0.050000},{0.837500,0.387500,0.100000,0.100000},{0.862500,0.387500,0.050000,0.050000},{0.862500,0.387500,0.100000,0.100000},{0.887500,0.387500,0.050000,0.050000},{0.887500,0.387500,0.100000,0.100000},{0.912500,0.387500,0.050000,0.050000},{0.912500,0.387500,0.100000,0.100000},{0.937500,0.387500,0.050000,0.050000},{0.937500,0.387500,0.100000,0.100000},{0.962500,0.387500,0.050000,0.050000},{0.962500,0.387500,0.100000,0.100000},{0.987500,0.387500,0.050000,0.050000},{0.987500,0.387500,0.100000,0.100000},{0.012500,0.412500,0.050000,0.050000},{0.012500,0.412500,0.100000,0.100000},{0.037500,0.412500,0.050000,0.050000},{0.037500,0.412500,0.100000,0.100000},{0.062500,0.412500,0.050000,0.050000},{0.062500,0.412500,0.100000,0.100000},{0.087500,0.412500,0.050000,0.050000},{0.087500,0.412500,0.100000,0.100000},{0.112500,0.412500,0.050000,0.050000},{0.112500,0.412500,0.100000,0.100000},{0.137500,0.412500,0.050000,0.050000},{0.137500,0.412500,0.100000,0.100000},{0.162500,0.412500,0.050000,0.050000},{0.162500,0.412500,0.100000,0.100000},{0.187500,0.412500,0.050000,0.050000},{0.187500,0.412500,0.100000,0.100000},{0.212500,0.412500,0.050000,0.050000},{0.212500,0.412500,0.100000,0.100000},{0.237500,0.412500,0.050000,0.050000},{0.237500,0.412500,0.100000,0.100000},{0.262500,0.412500,0.050000,0.050000},{0.262500,0.412500,0.100000,0.100000},{0.287500,0.412500,0.050000,0.050000},{0.287500,0.412500,0.100000,0.100000},{0.312500,0.412500,0.050000,0.050000},{0.312500,0.412500,0.100000,0.100000},{0.337500,0.412500,0.050000,0.050000},{0.337500,0.412500,0.100000,0.100000},{0.362500,0.412500,0.050000,0.050000},{0.362500,0.412500,0.100000,0.100000},{0.387500,0.412500,0.050000,0.050000},{0.387500,0.412500,0.100000,0.100000},{0.412500,0.412500,0.050000,0.050000},{0.412500,0.412500,0.100000,0.100000},{0.437500,0.412500,0.050000,0.050000},{0.437500,0.412500,0.100000,0.100000},{0.462500,0.412500,0.050000,0.050000},{0.462500,0.412500,0.100000,0.100000},{0.487500,0.412500,0.050000,0.050000},{0.487500,0.412500,0.100000,0.100000},{0.512500,0.412500,0.050000,0.050000},{0.512500,0.412500,0.100000,0.100000},{0.537500,0.412500,0.050000,0.050000},{0.537500,0.412500,0.100000,0.100000},{0.562500,0.412500,0.050000,0.050000},{0.562500,0.412500,0.100000,0.100000},{0.587500,0.412500,0.050000,0.050000},{0.587500,0.412500,0.100000,0.100000},{0.612500,0.412500,0.050000,0.050000},{0.612500,0.412500,0.100000,0.100000},{0.637500,0.412500,0.050000,0.050000},{0.637500,0.412500,0.100000,0.100000},{0.662500,0.412500,0.050000,0.050000},{0.662500,0.412500,0.100000,0.100000},{0.687500,0.412500,0.050000,0.050000},{0.687500,0.412500,0.100000,0.100000},{0.712500,0.412500,0.050000,0.050000},{0.712500,0.412500,0.100000,0.100000},{0.737500,0.412500,0.050000,0.050000},{0.737500,0.412500,0.100000,0.100000},{0.762500,0.412500,0.050000,0.050000},{0.762500,0.412500,0.100000,0.100000},{0.787500,0.412500,0.050000,0.050000},{0.787500,0.412500,0.100000,0.100000},{0.812500,0.412500,0.050000,0.050000},{0.812500,0.412500,0.100000,0.100000},{0.837500,0.412500,0.050000,0.050000},{0.837500,0.412500,0.100000,0.100000},{0.862500,0.412500,0.050000,0.050000},{0.862500,0.412500,0.100000,0.100000},{0.887500,0.412500,0.050000,0.050000},{0.887500,0.412500,0.100000,0.100000},{0.912500,0.412500,0.050000,0.050000},{0.912500,0.412500,0.100000,0.100000},{0.937500,0.412500,0.050000,0.050000},{0.937500,0.412500,0.100000,0.100000},{0.962500,0.412500,0.050000,0.050000},{0.962500,0.412500,0.100000,0.100000},{0.987500,0.412500,0.050000,0.050000},{0.987500,0.412500,0.100000,0.100000},{0.012500,0.437500,0.050000,0.050000},{0.012500,0.437500,0.100000,0.100000},{0.037500,0.437500,0.050000,0.050000},{0.037500,0.437500,0.100000,0.100000},{0.062500,0.437500,0.050000,0.050000},{0.062500,0.437500,0.100000,0.100000},{0.087500,0.437500,0.050000,0.050000},{0.087500,0.437500,0.100000,0.100000},{0.112500,0.437500,0.050000,0.050000},{0.112500,0.437500,0.100000,0.100000},{0.137500,0.437500,0.050000,0.050000},{0.137500,0.437500,0.100000,0.100000},{0.162500,0.437500,0.050000,0.050000},{0.162500,0.437500,0.100000,0.100000},{0.187500,0.437500,0.050000,0.050000},{0.187500,0.437500,0.100000,0.100000},{0.212500,0.437500,0.050000,0.050000},{0.212500,0.437500,0.100000,0.100000},{0.237500,0.437500,0.050000,0.050000},{0.237500,0.437500,0.100000,0.100000},{0.262500,0.437500,0.050000,0.050000},{0.262500,0.437500,0.100000,0.100000},{0.287500,0.437500,0.050000,0.050000},{0.287500,0.437500,0.100000,0.100000},{0.312500,0.437500,0.050000,0.050000},{0.312500,0.437500,0.100000,0.100000},{0.337500,0.437500,0.050000,0.050000},{0.337500,0.437500,0.100000,0.100000},{0.362500,0.437500,0.050000,0.050000},{0.362500,0.437500,0.100000,0.100000},{0.387500,0.437500,0.050000,0.050000},{0.387500,0.437500,0.100000,0.100000},{0.412500,0.437500,0.050000,0.050000},{0.412500,0.437500,0.100000,0.100000},{0.437500,0.437500,0.050000,0.050000},{0.437500,0.437500,0.100000,0.100000},{0.462500,0.437500,0.050000,0.050000},{0.462500,0.437500,0.100000,0.100000},{0.487500,0.437500,0.050000,0.050000},{0.487500,0.437500,0.100000,0.100000},{0.512500,0.437500,0.050000,0.050000},{0.512500,0.437500,0.100000,0.100000},{0.537500,0.437500,0.050000,0.050000},{0.537500,0.437500,0.100000,0.100000},{0.562500,0.437500,0.050000,0.050000},{0.562500,0.437500,0.100000,0.100000},{0.587500,0.437500,0.050000,0.050000},{0.587500,0.437500,0.100000,0.100000},{0.612500,0.437500,0.050000,0.050000},{0.612500,0.437500,0.100000,0.100000},{0.637500,0.437500,0.050000,0.050000},{0.637500,0.437500,0.100000,0.100000},{0.662500,0.437500,0.050000,0.050000},{0.662500,0.437500,0.100000,0.100000},{0.687500,0.437500,0.050000,0.050000},{0.687500,0.437500,0.100000,0.100000},{0.712500,0.437500,0.050000,0.050000},{0.712500,0.437500,0.100000,0.100000},{0.737500,0.437500,0.050000,0.050000},{0.737500,0.437500,0.100000,0.100000},{0.762500,0.437500,0.050000,0.050000},{0.762500,0.437500,0.100000,0.100000},{0.787500,0.437500,0.050000,0.050000},{0.787500,0.437500,0.100000,0.100000},{0.812500,0.437500,0.050000,0.050000},{0.812500,0.437500,0.100000,0.100000},{0.837500,0.437500,0.050000,0.050000},{0.837500,0.437500,0.100000,0.100000},{0.862500,0.437500,0.050000,0.050000},{0.862500,0.437500,0.100000,0.100000},{0.887500,0.437500,0.050000,0.050000},{0.887500,0.437500,0.100000,0.100000},{0.912500,0.437500,0.050000,0.050000},{0.912500,0.437500,0.100000,0.100000},{0.937500,0.437500,0.050000,0.050000},{0.937500,0.437500,0.100000,0.100000},{0.962500,0.437500,0.050000,0.050000},{0.962500,0.437500,0.100000,0.100000},{0.987500,0.437500,0.050000,0.050000},{0.987500,0.437500,0.100000,0.100000},{0.012500,0.462500,0.050000,0.050000},{0.012500,0.462500,0.100000,0.100000},{0.037500,0.462500,0.050000,0.050000},{0.037500,0.462500,0.100000,0.100000},{0.062500,0.462500,0.050000,0.050000},{0.062500,0.462500,0.100000,0.100000},{0.087500,0.462500,0.050000,0.050000},{0.087500,0.462500,0.100000,0.100000},{0.112500,0.462500,0.050000,0.050000},{0.112500,0.462500,0.100000,0.100000},{0.137500,0.462500,0.050000,0.050000},{0.137500,0.462500,0.100000,0.100000},{0.162500,0.462500,0.050000,0.050000},{0.162500,0.462500,0.100000,0.100000},{0.187500,0.462500,0.050000,0.050000},{0.187500,0.462500,0.100000,0.100000},{0.212500,0.462500,0.050000,0.050000},{0.212500,0.462500,0.100000,0.100000},{0.237500,0.462500,0.050000,0.050000},{0.237500,0.462500,0.100000,0.100000},{0.262500,0.462500,0.050000,0.050000},{0.262500,0.462500,0.100000,0.100000},{0.287500,0.462500,0.050000,0.050000},{0.287500,0.462500,0.100000,0.100000},{0.312500,0.462500,0.050000,0.050000},{0.312500,0.462500,0.100000,0.100000},{0.337500,0.462500,0.050000,0.050000},{0.337500,0.462500,0.100000,0.100000},{0.362500,0.462500,0.050000,0.050000},{0.362500,0.462500,0.100000,0.100000},{0.387500,0.462500,0.050000,0.050000},{0.387500,0.462500,0.100000,0.100000},{0.412500,0.462500,0.050000,0.050000},{0.412500,0.462500,0.100000,0.100000},{0.437500,0.462500,0.050000,0.050000},{0.437500,0.462500,0.100000,0.100000},{0.462500,0.462500,0.050000,0.050000},{0.462500,0.462500,0.100000,0.100000},{0.487500,0.462500,0.050000,0.050000},{0.487500,0.462500,0.100000,0.100000},{0.512500,0.462500,0.050000,0.050000},{0.512500,0.462500,0.100000,0.100000},{0.537500,0.462500,0.050000,0.050000},{0.537500,0.462500,0.100000,0.100000},{0.562500,0.462500,0.050000,0.050000},{0.562500,0.462500,0.100000,0.100000},{0.587500,0.462500,0.050000,0.050000},{0.587500,0.462500,0.100000,0.100000},{0.612500,0.462500,0.050000,0.050000},{0.612500,0.462500,0.100000,0.100000},{0.637500,0.462500,0.050000,0.050000},{0.637500,0.462500,0.100000,0.100000},{0.662500,0.462500,0.050000,0.050000},{0.662500,0.462500,0.100000,0.100000},{0.687500,0.462500,0.050000,0.050000},{0.687500,0.462500,0.100000,0.100000},{0.712500,0.462500,0.050000,0.050000},{0.712500,0.462500,0.100000,0.100000},{0.737500,0.462500,0.050000,0.050000},{0.737500,0.462500,0.100000,0.100000},{0.762500,0.462500,0.050000,0.050000},{0.762500,0.462500,0.100000,0.100000},{0.787500,0.462500,0.050000,0.050000},{0.787500,0.462500,0.100000,0.100000},{0.812500,0.462500,0.050000,0.050000},{0.812500,0.462500,0.100000,0.100000},{0.837500,0.462500,0.050000,0.050000},{0.837500,0.462500,0.100000,0.100000},{0.862500,0.462500,0.050000,0.050000},{0.862500,0.462500,0.100000,0.100000},{0.887500,0.462500,0.050000,0.050000},{0.887500,0.462500,0.100000,0.100000},{0.912500,0.462500,0.050000,0.050000},{0.912500,0.462500,0.100000,0.100000},{0.937500,0.462500,0.050000,0.050000},{0.937500,0.462500,0.100000,0.100000},{0.962500,0.462500,0.050000,0.050000},{0.962500,0.462500,0.100000,0.100000},{0.987500,0.462500,0.050000,0.050000},{0.987500,0.462500,0.100000,0.100000},{0.012500,0.487500,0.050000,0.050000},{0.012500,0.487500,0.100000,0.100000},{0.037500,0.487500,0.050000,0.050000},{0.037500,0.487500,0.100000,0.100000},{0.062500,0.487500,0.050000,0.050000},{0.062500,0.487500,0.100000,0.100000},{0.087500,0.487500,0.050000,0.050000},{0.087500,0.487500,0.100000,0.100000},{0.112500,0.487500,0.050000,0.050000},{0.112500,0.487500,0.100000,0.100000},{0.137500,0.487500,0.050000,0.050000},{0.137500,0.487500,0.100000,0.100000},{0.162500,0.487500,0.050000,0.050000},{0.162500,0.487500,0.100000,0.100000},{0.187500,0.487500,0.050000,0.050000},{0.187500,0.487500,0.100000,0.100000},{0.212500,0.487500,0.050000,0.050000},{0.212500,0.487500,0.100000,0.100000},{0.237500,0.487500,0.050000,0.050000},{0.237500,0.487500,0.100000,0.100000},{0.262500,0.487500,0.050000,0.050000},{0.262500,0.487500,0.100000,0.100000},{0.287500,0.487500,0.050000,0.050000},{0.287500,0.487500,0.100000,0.100000},{0.312500,0.487500,0.050000,0.050000},{0.312500,0.487500,0.100000,0.100000},{0.337500,0.487500,0.050000,0.050000},{0.337500,0.487500,0.100000,0.100000},{0.362500,0.487500,0.050000,0.050000},{0.362500,0.487500,0.100000,0.100000},{0.387500,0.487500,0.050000,0.050000},{0.387500,0.487500,0.100000,0.100000},{0.412500,0.487500,0.050000,0.050000},{0.412500,0.487500,0.100000,0.100000},{0.437500,0.487500,0.050000,0.050000},{0.437500,0.487500,0.100000,0.100000},{0.462500,0.487500,0.050000,0.050000},{0.462500,0.487500,0.100000,0.100000},{0.487500,0.487500,0.050000,0.050000},{0.487500,0.487500,0.100000,0.100000},{0.512500,0.487500,0.050000,0.050000},{0.512500,0.487500,0.100000,0.100000},{0.537500,0.487500,0.050000,0.050000},{0.537500,0.487500,0.100000,0.100000},{0.562500,0.487500,0.050000,0.050000},{0.562500,0.487500,0.100000,0.100000},{0.587500,0.487500,0.050000,0.050000},{0.587500,0.487500,0.100000,0.100000},{0.612500,0.487500,0.050000,0.050000},{0.612500,0.487500,0.100000,0.100000},{0.637500,0.487500,0.050000,0.050000},{0.637500,0.487500,0.100000,0.100000},{0.662500,0.487500,0.050000,0.050000},{0.662500,0.487500,0.100000,0.100000},{0.687500,0.487500,0.050000,0.050000},{0.687500,0.487500,0.100000,0.100000},{0.712500,0.487500,0.050000,0.050000},{0.712500,0.487500,0.100000,0.100000},{0.737500,0.487500,0.050000,0.050000},{0.737500,0.487500,0.100000,0.100000},{0.762500,0.487500,0.050000,0.050000},{0.762500,0.487500,0.100000,0.100000},{0.787500,0.487500,0.050000,0.050000},{0.787500,0.487500,0.100000,0.100000},{0.812500,0.487500,0.050000,0.050000},{0.812500,0.487500,0.100000,0.100000},{0.837500,0.487500,0.050000,0.050000},{0.837500,0.487500,0.100000,0.100000},{0.862500,0.487500,0.050000,0.050000},{0.862500,0.487500,0.100000,0.100000},{0.887500,0.487500,0.050000,0.050000},{0.887500,0.487500,0.100000,0.100000},{0.912500,0.487500,0.050000,0.050000},{0.912500,0.487500,0.100000,0.100000},{0.937500,0.487500,0.050000,0.050000},{0.937500,0.487500,0.100000,0.100000},{0.962500,0.487500,0.050000,0.050000},{0.962500,0.487500,0.100000,0.100000},{0.987500,0.487500,0.050000,0.050000},{0.987500,0.487500,0.100000,0.100000},{0.012500,0.512500,0.050000,0.050000},{0.012500,0.512500,0.100000,0.100000},{0.037500,0.512500,0.050000,0.050000},{0.037500,0.512500,0.100000,0.100000},{0.062500,0.512500,0.050000,0.050000},{0.062500,0.512500,0.100000,0.100000},{0.087500,0.512500,0.050000,0.050000},{0.087500,0.512500,0.100000,0.100000},{0.112500,0.512500,0.050000,0.050000},{0.112500,0.512500,0.100000,0.100000},{0.137500,0.512500,0.050000,0.050000},{0.137500,0.512500,0.100000,0.100000},{0.162500,0.512500,0.050000,0.050000},{0.162500,0.512500,0.100000,0.100000},{0.187500,0.512500,0.050000,0.050000},{0.187500,0.512500,0.100000,0.100000},{0.212500,0.512500,0.050000,0.050000},{0.212500,0.512500,0.100000,0.100000},{0.237500,0.512500,0.050000,0.050000},{0.237500,0.512500,0.100000,0.100000},{0.262500,0.512500,0.050000,0.050000},{0.262500,0.512500,0.100000,0.100000},{0.287500,0.512500,0.050000,0.050000},{0.287500,0.512500,0.100000,0.100000},{0.312500,0.512500,0.050000,0.050000},{0.312500,0.512500,0.100000,0.100000},{0.337500,0.512500,0.050000,0.050000},{0.337500,0.512500,0.100000,0.100000},{0.362500,0.512500,0.050000,0.050000},{0.362500,0.512500,0.100000,0.100000},{0.387500,0.512500,0.050000,0.050000},{0.387500,0.512500,0.100000,0.100000},{0.412500,0.512500,0.050000,0.050000},{0.412500,0.512500,0.100000,0.100000},{0.437500,0.512500,0.050000,0.050000},{0.437500,0.512500,0.100000,0.100000},{0.462500,0.512500,0.050000,0.050000},{0.462500,0.512500,0.100000,0.100000},{0.487500,0.512500,0.050000,0.050000},{0.487500,0.512500,0.100000,0.100000},{0.512500,0.512500,0.050000,0.050000},{0.512500,0.512500,0.100000,0.100000},{0.537500,0.512500,0.050000,0.050000},{0.537500,0.512500,0.100000,0.100000},{0.562500,0.512500,0.050000,0.050000},{0.562500,0.512500,0.100000,0.100000},{0.587500,0.512500,0.050000,0.050000},{0.587500,0.512500,0.100000,0.100000},{0.612500,0.512500,0.050000,0.050000},{0.612500,0.512500,0.100000,0.100000},{0.637500,0.512500,0.050000,0.050000},{0.637500,0.512500,0.100000,0.100000},{0.662500,0.512500,0.050000,0.050000},{0.662500,0.512500,0.100000,0.100000},{0.687500,0.512500,0.050000,0.050000},{0.687500,0.512500,0.100000,0.100000},{0.712500,0.512500,0.050000,0.050000},{0.712500,0.512500,0.100000,0.100000},{0.737500,0.512500,0.050000,0.050000},{0.737500,0.512500,0.100000,0.100000},{0.762500,0.512500,0.050000,0.050000},{0.762500,0.512500,0.100000,0.100000},{0.787500,0.512500,0.050000,0.050000},{0.787500,0.512500,0.100000,0.100000},{0.812500,0.512500,0.050000,0.050000},{0.812500,0.512500,0.100000,0.100000},{0.837500,0.512500,0.050000,0.050000},{0.837500,0.512500,0.100000,0.100000},{0.862500,0.512500,0.050000,0.050000},{0.862500,0.512500,0.100000,0.100000},{0.887500,0.512500,0.050000,0.050000},{0.887500,0.512500,0.100000,0.100000},{0.912500,0.512500,0.050000,0.050000},{0.912500,0.512500,0.100000,0.100000},{0.937500,0.512500,0.050000,0.050000},{0.937500,0.512500,0.100000,0.100000},{0.962500,0.512500,0.050000,0.050000},{0.962500,0.512500,0.100000,0.100000},{0.987500,0.512500,0.050000,0.050000},{0.987500,0.512500,0.100000,0.100000},{0.012500,0.537500,0.050000,0.050000},{0.012500,0.537500,0.100000,0.100000},{0.037500,0.537500,0.050000,0.050000},{0.037500,0.537500,0.100000,0.100000},{0.062500,0.537500,0.050000,0.050000},{0.062500,0.537500,0.100000,0.100000},{0.087500,0.537500,0.050000,0.050000},{0.087500,0.537500,0.100000,0.100000},{0.112500,0.537500,0.050000,0.050000},{0.112500,0.537500,0.100000,0.100000},{0.137500,0.537500,0.050000,0.050000},{0.137500,0.537500,0.100000,0.100000},{0.162500,0.537500,0.050000,0.050000},{0.162500,0.537500,0.100000,0.100000},{0.187500,0.537500,0.050000,0.050000},{0.187500,0.537500,0.100000,0.100000},{0.212500,0.537500,0.050000,0.050000},{0.212500,0.537500,0.100000,0.100000},{0.237500,0.537500,0.050000,0.050000},{0.237500,0.537500,0.100000,0.100000},{0.262500,0.537500,0.050000,0.050000},{0.262500,0.537500,0.100000,0.100000},{0.287500,0.537500,0.050000,0.050000},{0.287500,0.537500,0.100000,0.100000},{0.312500,0.537500,0.050000,0.050000},{0.312500,0.537500,0.100000,0.100000},{0.337500,0.537500,0.050000,0.050000},{0.337500,0.537500,0.100000,0.100000},{0.362500,0.537500,0.050000,0.050000},{0.362500,0.537500,0.100000,0.100000},{0.387500,0.537500,0.050000,0.050000},{0.387500,0.537500,0.100000,0.100000},{0.412500,0.537500,0.050000,0.050000},{0.412500,0.537500,0.100000,0.100000},{0.437500,0.537500,0.050000,0.050000},{0.437500,0.537500,0.100000,0.100000},{0.462500,0.537500,0.050000,0.050000},{0.462500,0.537500,0.100000,0.100000},{0.487500,0.537500,0.050000,0.050000},{0.487500,0.537500,0.100000,0.100000},{0.512500,0.537500,0.050000,0.050000},{0.512500,0.537500,0.100000,0.100000},{0.537500,0.537500,0.050000,0.050000},{0.537500,0.537500,0.100000,0.100000},{0.562500,0.537500,0.050000,0.050000},{0.562500,0.537500,0.100000,0.100000},{0.587500,0.537500,0.050000,0.050000},{0.587500,0.537500,0.100000,0.100000},{0.612500,0.537500,0.050000,0.050000},{0.612500,0.537500,0.100000,0.100000},{0.637500,0.537500,0.050000,0.050000},{0.637500,0.537500,0.100000,0.100000},{0.662500,0.537500,0.050000,0.050000},{0.662500,0.537500,0.100000,0.100000},{0.687500,0.537500,0.050000,0.050000},{0.687500,0.537500,0.100000,0.100000},{0.712500,0.537500,0.050000,0.050000},{0.712500,0.537500,0.100000,0.100000},{0.737500,0.537500,0.050000,0.050000},{0.737500,0.537500,0.100000,0.100000},{0.762500,0.537500,0.050000,0.050000},{0.762500,0.537500,0.100000,0.100000},{0.787500,0.537500,0.050000,0.050000},{0.787500,0.537500,0.100000,0.100000},{0.812500,0.537500,0.050000,0.050000},{0.812500,0.537500,0.100000,0.100000},{0.837500,0.537500,0.050000,0.050000},{0.837500,0.537500,0.100000,0.100000},{0.862500,0.537500,0.050000,0.050000},{0.862500,0.537500,0.100000,0.100000},{0.887500,0.537500,0.050000,0.050000},{0.887500,0.537500,0.100000,0.100000},{0.912500,0.537500,0.050000,0.050000},{0.912500,0.537500,0.100000,0.100000},{0.937500,0.537500,0.050000,0.050000},{0.937500,0.537500,0.100000,0.100000},{0.962500,0.537500,0.050000,0.050000},{0.962500,0.537500,0.100000,0.100000},{0.987500,0.537500,0.050000,0.050000},{0.987500,0.537500,0.100000,0.100000},{0.012500,0.562500,0.050000,0.050000},{0.012500,0.562500,0.100000,0.100000},{0.037500,0.562500,0.050000,0.050000},{0.037500,0.562500,0.100000,0.100000},{0.062500,0.562500,0.050000,0.050000},{0.062500,0.562500,0.100000,0.100000},{0.087500,0.562500,0.050000,0.050000},{0.087500,0.562500,0.100000,0.100000},{0.112500,0.562500,0.050000,0.050000},{0.112500,0.562500,0.100000,0.100000},{0.137500,0.562500,0.050000,0.050000},{0.137500,0.562500,0.100000,0.100000},{0.162500,0.562500,0.050000,0.050000},{0.162500,0.562500,0.100000,0.100000},{0.187500,0.562500,0.050000,0.050000},{0.187500,0.562500,0.100000,0.100000},{0.212500,0.562500,0.050000,0.050000},{0.212500,0.562500,0.100000,0.100000},{0.237500,0.562500,0.050000,0.050000},{0.237500,0.562500,0.100000,0.100000},{0.262500,0.562500,0.050000,0.050000},{0.262500,0.562500,0.100000,0.100000},{0.287500,0.562500,0.050000,0.050000},{0.287500,0.562500,0.100000,0.100000},{0.312500,0.562500,0.050000,0.050000},{0.312500,0.562500,0.100000,0.100000},{0.337500,0.562500,0.050000,0.050000},{0.337500,0.562500,0.100000,0.100000},{0.362500,0.562500,0.050000,0.050000},{0.362500,0.562500,0.100000,0.100000},{0.387500,0.562500,0.050000,0.050000},{0.387500,0.562500,0.100000,0.100000},{0.412500,0.562500,0.050000,0.050000},{0.412500,0.562500,0.100000,0.100000},{0.437500,0.562500,0.050000,0.050000},{0.437500,0.562500,0.100000,0.100000},{0.462500,0.562500,0.050000,0.050000},{0.462500,0.562500,0.100000,0.100000},{0.487500,0.562500,0.050000,0.050000},{0.487500,0.562500,0.100000,0.100000},{0.512500,0.562500,0.050000,0.050000},{0.512500,0.562500,0.100000,0.100000},{0.537500,0.562500,0.050000,0.050000},{0.537500,0.562500,0.100000,0.100000},{0.562500,0.562500,0.050000,0.050000},{0.562500,0.562500,0.100000,0.100000},{0.587500,0.562500,0.050000,0.050000},{0.587500,0.562500,0.100000,0.100000},{0.612500,0.562500,0.050000,0.050000},{0.612500,0.562500,0.100000,0.100000},{0.637500,0.562500,0.050000,0.050000},{0.637500,0.562500,0.100000,0.100000},{0.662500,0.562500,0.050000,0.050000},{0.662500,0.562500,0.100000,0.100000},{0.687500,0.562500,0.050000,0.050000},{0.687500,0.562500,0.100000,0.100000},{0.712500,0.562500,0.050000,0.050000},{0.712500,0.562500,0.100000,0.100000},{0.737500,0.562500,0.050000,0.050000},{0.737500,0.562500,0.100000,0.100000},{0.762500,0.562500,0.050000,0.050000},{0.762500,0.562500,0.100000,0.100000},{0.787500,0.562500,0.050000,0.050000},{0.787500,0.562500,0.100000,0.100000},{0.812500,0.562500,0.050000,0.050000},{0.812500,0.562500,0.100000,0.100000},{0.837500,0.562500,0.050000,0.050000},{0.837500,0.562500,0.100000,0.100000},{0.862500,0.562500,0.050000,0.050000},{0.862500,0.562500,0.100000,0.100000},{0.887500,0.562500,0.050000,0.050000},{0.887500,0.562500,0.100000,0.100000},{0.912500,0.562500,0.050000,0.050000},{0.912500,0.562500,0.100000,0.100000},{0.937500,0.562500,0.050000,0.050000},{0.937500,0.562500,0.100000,0.100000},{0.962500,0.562500,0.050000,0.050000},{0.962500,0.562500,0.100000,0.100000},{0.987500,0.562500,0.050000,0.050000},{0.987500,0.562500,0.100000,0.100000},{0.012500,0.587500,0.050000,0.050000},{0.012500,0.587500,0.100000,0.100000},{0.037500,0.587500,0.050000,0.050000},{0.037500,0.587500,0.100000,0.100000},{0.062500,0.587500,0.050000,0.050000},{0.062500,0.587500,0.100000,0.100000},{0.087500,0.587500,0.050000,0.050000},{0.087500,0.587500,0.100000,0.100000},{0.112500,0.587500,0.050000,0.050000},{0.112500,0.587500,0.100000,0.100000},{0.137500,0.587500,0.050000,0.050000},{0.137500,0.587500,0.100000,0.100000},{0.162500,0.587500,0.050000,0.050000},{0.162500,0.587500,0.100000,0.100000},{0.187500,0.587500,0.050000,0.050000},{0.187500,0.587500,0.100000,0.100000},{0.212500,0.587500,0.050000,0.050000},{0.212500,0.587500,0.100000,0.100000},{0.237500,0.587500,0.050000,0.050000},{0.237500,0.587500,0.100000,0.100000},{0.262500,0.587500,0.050000,0.050000},{0.262500,0.587500,0.100000,0.100000},{0.287500,0.587500,0.050000,0.050000},{0.287500,0.587500,0.100000,0.100000},{0.312500,0.587500,0.050000,0.050000},{0.312500,0.587500,0.100000,0.100000},{0.337500,0.587500,0.050000,0.050000},{0.337500,0.587500,0.100000,0.100000},{0.362500,0.587500,0.050000,0.050000},{0.362500,0.587500,0.100000,0.100000},{0.387500,0.587500,0.050000,0.050000},{0.387500,0.587500,0.100000,0.100000},{0.412500,0.587500,0.050000,0.050000},{0.412500,0.587500,0.100000,0.100000},{0.437500,0.587500,0.050000,0.050000},{0.437500,0.587500,0.100000,0.100000},{0.462500,0.587500,0.050000,0.050000},{0.462500,0.587500,0.100000,0.100000},{0.487500,0.587500,0.050000,0.050000},{0.487500,0.587500,0.100000,0.100000},{0.512500,0.587500,0.050000,0.050000},{0.512500,0.587500,0.100000,0.100000},{0.537500,0.587500,0.050000,0.050000},{0.537500,0.587500,0.100000,0.100000},{0.562500,0.587500,0.050000,0.050000},{0.562500,0.587500,0.100000,0.100000},{0.587500,0.587500,0.050000,0.050000},{0.587500,0.587500,0.100000,0.100000},{0.612500,0.587500,0.050000,0.050000},{0.612500,0.587500,0.100000,0.100000},{0.637500,0.587500,0.050000,0.050000},{0.637500,0.587500,0.100000,0.100000},{0.662500,0.587500,0.050000,0.050000},{0.662500,0.587500,0.100000,0.100000},{0.687500,0.587500,0.050000,0.050000},{0.687500,0.587500,0.100000,0.100000},{0.712500,0.587500,0.050000,0.050000},{0.712500,0.587500,0.100000,0.100000},{0.737500,0.587500,0.050000,0.050000},{0.737500,0.587500,0.100000,0.100000},{0.762500,0.587500,0.050000,0.050000},{0.762500,0.587500,0.100000,0.100000},{0.787500,0.587500,0.050000,0.050000},{0.787500,0.587500,0.100000,0.100000},{0.812500,0.587500,0.050000,0.050000},{0.812500,0.587500,0.100000,0.100000},{0.837500,0.587500,0.050000,0.050000},{0.837500,0.587500,0.100000,0.100000},{0.862500,0.587500,0.050000,0.050000},{0.862500,0.587500,0.100000,0.100000},{0.887500,0.587500,0.050000,0.050000},{0.887500,0.587500,0.100000,0.100000},{0.912500,0.587500,0.050000,0.050000},{0.912500,0.587500,0.100000,0.100000},{0.937500,0.587500,0.050000,0.050000},{0.937500,0.587500,0.100000,0.100000},{0.962500,0.587500,0.050000,0.050000},{0.962500,0.587500,0.100000,0.100000},{0.987500,0.587500,0.050000,0.050000},{0.987500,0.587500,0.100000,0.100000},{0.012500,0.612500,0.050000,0.050000},{0.012500,0.612500,0.100000,0.100000},{0.037500,0.612500,0.050000,0.050000},{0.037500,0.612500,0.100000,0.100000},{0.062500,0.612500,0.050000,0.050000},{0.062500,0.612500,0.100000,0.100000},{0.087500,0.612500,0.050000,0.050000},{0.087500,0.612500,0.100000,0.100000},{0.112500,0.612500,0.050000,0.050000},{0.112500,0.612500,0.100000,0.100000},{0.137500,0.612500,0.050000,0.050000},{0.137500,0.612500,0.100000,0.100000},{0.162500,0.612500,0.050000,0.050000},{0.162500,0.612500,0.100000,0.100000},{0.187500,0.612500,0.050000,0.050000},{0.187500,0.612500,0.100000,0.100000},{0.212500,0.612500,0.050000,0.050000},{0.212500,0.612500,0.100000,0.100000},{0.237500,0.612500,0.050000,0.050000},{0.237500,0.612500,0.100000,0.100000},{0.262500,0.612500,0.050000,0.050000},{0.262500,0.612500,0.100000,0.100000},{0.287500,0.612500,0.050000,0.050000},{0.287500,0.612500,0.100000,0.100000},{0.312500,0.612500,0.050000,0.050000},{0.312500,0.612500,0.100000,0.100000},{0.337500,0.612500,0.050000,0.050000},{0.337500,0.612500,0.100000,0.100000},{0.362500,0.612500,0.050000,0.050000},{0.362500,0.612500,0.100000,0.100000},{0.387500,0.612500,0.050000,0.050000},{0.387500,0.612500,0.100000,0.100000},{0.412500,0.612500,0.050000,0.050000},{0.412500,0.612500,0.100000,0.100000},{0.437500,0.612500,0.050000,0.050000},{0.437500,0.612500,0.100000,0.100000},{0.462500,0.612500,0.050000,0.050000},{0.462500,0.612500,0.100000,0.100000},{0.487500,0.612500,0.050000,0.050000},{0.487500,0.612500,0.100000,0.100000},{0.512500,0.612500,0.050000,0.050000},{0.512500,0.612500,0.100000,0.100000},{0.537500,0.612500,0.050000,0.050000},{0.537500,0.612500,0.100000,0.100000},{0.562500,0.612500,0.050000,0.050000},{0.562500,0.612500,0.100000,0.100000},{0.587500,0.612500,0.050000,0.050000},{0.587500,0.612500,0.100000,0.100000},{0.612500,0.612500,0.050000,0.050000},{0.612500,0.612500,0.100000,0.100000},{0.637500,0.612500,0.050000,0.050000},{0.637500,0.612500,0.100000,0.100000},{0.662500,0.612500,0.050000,0.050000},{0.662500,0.612500,0.100000,0.100000},{0.687500,0.612500,0.050000,0.050000},{0.687500,0.612500,0.100000,0.100000},{0.712500,0.612500,0.050000,0.050000},{0.712500,0.612500,0.100000,0.100000},{0.737500,0.612500,0.050000,0.050000},{0.737500,0.612500,0.100000,0.100000},{0.762500,0.612500,0.050000,0.050000},{0.762500,0.612500,0.100000,0.100000},{0.787500,0.612500,0.050000,0.050000},{0.787500,0.612500,0.100000,0.100000},{0.812500,0.612500,0.050000,0.050000},{0.812500,0.612500,0.100000,0.100000},{0.837500,0.612500,0.050000,0.050000},{0.837500,0.612500,0.100000,0.100000},{0.862500,0.612500,0.050000,0.050000},{0.862500,0.612500,0.100000,0.100000},{0.887500,0.612500,0.050000,0.050000},{0.887500,0.612500,0.100000,0.100000},{0.912500,0.612500,0.050000,0.050000},{0.912500,0.612500,0.100000,0.100000},{0.937500,0.612500,0.050000,0.050000},{0.937500,0.612500,0.100000,0.100000},{0.962500,0.612500,0.050000,0.050000},{0.962500,0.612500,0.100000,0.100000},{0.987500,0.612500,0.050000,0.050000},{0.987500,0.612500,0.100000,0.100000},{0.012500,0.637500,0.050000,0.050000},{0.012500,0.637500,0.100000,0.100000},{0.037500,0.637500,0.050000,0.050000},{0.037500,0.637500,0.100000,0.100000},{0.062500,0.637500,0.050000,0.050000},{0.062500,0.637500,0.100000,0.100000},{0.087500,0.637500,0.050000,0.050000},{0.087500,0.637500,0.100000,0.100000},{0.112500,0.637500,0.050000,0.050000},{0.112500,0.637500,0.100000,0.100000},{0.137500,0.637500,0.050000,0.050000},{0.137500,0.637500,0.100000,0.100000},{0.162500,0.637500,0.050000,0.050000},{0.162500,0.637500,0.100000,0.100000},{0.187500,0.637500,0.050000,0.050000},{0.187500,0.637500,0.100000,0.100000},{0.212500,0.637500,0.050000,0.050000},{0.212500,0.637500,0.100000,0.100000},{0.237500,0.637500,0.050000,0.050000},{0.237500,0.637500,0.100000,0.100000},{0.262500,0.637500,0.050000,0.050000},{0.262500,0.637500,0.100000,0.100000},{0.287500,0.637500,0.050000,0.050000},{0.287500,0.637500,0.100000,0.100000},{0.312500,0.637500,0.050000,0.050000},{0.312500,0.637500,0.100000,0.100000},{0.337500,0.637500,0.050000,0.050000},{0.337500,0.637500,0.100000,0.100000},{0.362500,0.637500,0.050000,0.050000},{0.362500,0.637500,0.100000,0.100000},{0.387500,0.637500,0.050000,0.050000},{0.387500,0.637500,0.100000,0.100000},{0.412500,0.637500,0.050000,0.050000},{0.412500,0.637500,0.100000,0.100000},{0.437500,0.637500,0.050000,0.050000},{0.437500,0.637500,0.100000,0.100000},{0.462500,0.637500,0.050000,0.050000},{0.462500,0.637500,0.100000,0.100000},{0.487500,0.637500,0.050000,0.050000},{0.487500,0.637500,0.100000,0.100000},{0.512500,0.637500,0.050000,0.050000},{0.512500,0.637500,0.100000,0.100000},{0.537500,0.637500,0.050000,0.050000},{0.537500,0.637500,0.100000,0.100000},{0.562500,0.637500,0.050000,0.050000},{0.562500,0.637500,0.100000,0.100000},{0.587500,0.637500,0.050000,0.050000},{0.587500,0.637500,0.100000,0.100000},{0.612500,0.637500,0.050000,0.050000},{0.612500,0.637500,0.100000,0.100000},{0.637500,0.637500,0.050000,0.050000},{0.637500,0.637500,0.100000,0.100000},{0.662500,0.637500,0.050000,0.050000},{0.662500,0.637500,0.100000,0.100000},{0.687500,0.637500,0.050000,0.050000},{0.687500,0.637500,0.100000,0.100000},{0.712500,0.637500,0.050000,0.050000},{0.712500,0.637500,0.100000,0.100000},{0.737500,0.637500,0.050000,0.050000},{0.737500,0.637500,0.100000,0.100000},{0.762500,0.637500,0.050000,0.050000},{0.762500,0.637500,0.100000,0.100000},{0.787500,0.637500,0.050000,0.050000},{0.787500,0.637500,0.100000,0.100000},{0.812500,0.637500,0.050000,0.050000},{0.812500,0.637500,0.100000,0.100000},{0.837500,0.637500,0.050000,0.050000},{0.837500,0.637500,0.100000,0.100000},{0.862500,0.637500,0.050000,0.050000},{0.862500,0.637500,0.100000,0.100000},{0.887500,0.637500,0.050000,0.050000},{0.887500,0.637500,0.100000,0.100000},{0.912500,0.637500,0.050000,0.050000},{0.912500,0.637500,0.100000,0.100000},{0.937500,0.637500,0.050000,0.050000},{0.937500,0.637500,0.100000,0.100000},{0.962500,0.637500,0.050000,0.050000},{0.962500,0.637500,0.100000,0.100000},{0.987500,0.637500,0.050000,0.050000},{0.987500,0.637500,0.100000,0.100000},{0.012500,0.662500,0.050000,0.050000},{0.012500,0.662500,0.100000,0.100000},{0.037500,0.662500,0.050000,0.050000},{0.037500,0.662500,0.100000,0.100000},{0.062500,0.662500,0.050000,0.050000},{0.062500,0.662500,0.100000,0.100000},{0.087500,0.662500,0.050000,0.050000},{0.087500,0.662500,0.100000,0.100000},{0.112500,0.662500,0.050000,0.050000},{0.112500,0.662500,0.100000,0.100000},{0.137500,0.662500,0.050000,0.050000},{0.137500,0.662500,0.100000,0.100000},{0.162500,0.662500,0.050000,0.050000},{0.162500,0.662500,0.100000,0.100000},{0.187500,0.662500,0.050000,0.050000},{0.187500,0.662500,0.100000,0.100000},{0.212500,0.662500,0.050000,0.050000},{0.212500,0.662500,0.100000,0.100000},{0.237500,0.662500,0.050000,0.050000},{0.237500,0.662500,0.100000,0.100000},{0.262500,0.662500,0.050000,0.050000},{0.262500,0.662500,0.100000,0.100000},{0.287500,0.662500,0.050000,0.050000},{0.287500,0.662500,0.100000,0.100000},{0.312500,0.662500,0.050000,0.050000},{0.312500,0.662500,0.100000,0.100000},{0.337500,0.662500,0.050000,0.050000},{0.337500,0.662500,0.100000,0.100000},{0.362500,0.662500,0.050000,0.050000},{0.362500,0.662500,0.100000,0.100000},{0.387500,0.662500,0.050000,0.050000},{0.387500,0.662500,0.100000,0.100000},{0.412500,0.662500,0.050000,0.050000},{0.412500,0.662500,0.100000,0.100000},{0.437500,0.662500,0.050000,0.050000},{0.437500,0.662500,0.100000,0.100000},{0.462500,0.662500,0.050000,0.050000},{0.462500,0.662500,0.100000,0.100000},{0.487500,0.662500,0.050000,0.050000},{0.487500,0.662500,0.100000,0.100000},{0.512500,0.662500,0.050000,0.050000},{0.512500,0.662500,0.100000,0.100000},{0.537500,0.662500,0.050000,0.050000},{0.537500,0.662500,0.100000,0.100000},{0.562500,0.662500,0.050000,0.050000},{0.562500,0.662500,0.100000,0.100000},{0.587500,0.662500,0.050000,0.050000},{0.587500,0.662500,0.100000,0.100000},{0.612500,0.662500,0.050000,0.050000},{0.612500,0.662500,0.100000,0.100000},{0.637500,0.662500,0.050000,0.050000},{0.637500,0.662500,0.100000,0.100000},{0.662500,0.662500,0.050000,0.050000},{0.662500,0.662500,0.100000,0.100000},{0.687500,0.662500,0.050000,0.050000},{0.687500,0.662500,0.100000,0.100000},{0.712500,0.662500,0.050000,0.050000},{0.712500,0.662500,0.100000,0.100000},{0.737500,0.662500,0.050000,0.050000},{0.737500,0.662500,0.100000,0.100000},{0.762500,0.662500,0.050000,0.050000},{0.762500,0.662500,0.100000,0.100000},{0.787500,0.662500,0.050000,0.050000},{0.787500,0.662500,0.100000,0.100000},{0.812500,0.662500,0.050000,0.050000},{0.812500,0.662500,0.100000,0.100000},{0.837500,0.662500,0.050000,0.050000},{0.837500,0.662500,0.100000,0.100000},{0.862500,0.662500,0.050000,0.050000},{0.862500,0.662500,0.100000,0.100000},{0.887500,0.662500,0.050000,0.050000},{0.887500,0.662500,0.100000,0.100000},{0.912500,0.662500,0.050000,0.050000},{0.912500,0.662500,0.100000,0.100000},{0.937500,0.662500,0.050000,0.050000},{0.937500,0.662500,0.100000,0.100000},{0.962500,0.662500,0.050000,0.050000},{0.962500,0.662500,0.100000,0.100000},{0.987500,0.662500,0.050000,0.050000},{0.987500,0.662500,0.100000,0.100000},{0.012500,0.687500,0.050000,0.050000},{0.012500,0.687500,0.100000,0.100000},{0.037500,0.687500,0.050000,0.050000},{0.037500,0.687500,0.100000,0.100000},{0.062500,0.687500,0.050000,0.050000},{0.062500,0.687500,0.100000,0.100000},{0.087500,0.687500,0.050000,0.050000},{0.087500,0.687500,0.100000,0.100000},{0.112500,0.687500,0.050000,0.050000},{0.112500,0.687500,0.100000,0.100000},{0.137500,0.687500,0.050000,0.050000},{0.137500,0.687500,0.100000,0.100000},{0.162500,0.687500,0.050000,0.050000},{0.162500,0.687500,0.100000,0.100000},{0.187500,0.687500,0.050000,0.050000},{0.187500,0.687500,0.100000,0.100000},{0.212500,0.687500,0.050000,0.050000},{0.212500,0.687500,0.100000,0.100000},{0.237500,0.687500,0.050000,0.050000},{0.237500,0.687500,0.100000,0.100000},{0.262500,0.687500,0.050000,0.050000},{0.262500,0.687500,0.100000,0.100000},{0.287500,0.687500,0.050000,0.050000},{0.287500,0.687500,0.100000,0.100000},{0.312500,0.687500,0.050000,0.050000},{0.312500,0.687500,0.100000,0.100000},{0.337500,0.687500,0.050000,0.050000},{0.337500,0.687500,0.100000,0.100000},{0.362500,0.687500,0.050000,0.050000},{0.362500,0.687500,0.100000,0.100000},{0.387500,0.687500,0.050000,0.050000},{0.387500,0.687500,0.100000,0.100000},{0.412500,0.687500,0.050000,0.050000},{0.412500,0.687500,0.100000,0.100000},{0.437500,0.687500,0.050000,0.050000},{0.437500,0.687500,0.100000,0.100000},{0.462500,0.687500,0.050000,0.050000},{0.462500,0.687500,0.100000,0.100000},{0.487500,0.687500,0.050000,0.050000},{0.487500,0.687500,0.100000,0.100000},{0.512500,0.687500,0.050000,0.050000},{0.512500,0.687500,0.100000,0.100000},{0.537500,0.687500,0.050000,0.050000},{0.537500,0.687500,0.100000,0.100000},{0.562500,0.687500,0.050000,0.050000},{0.562500,0.687500,0.100000,0.100000},{0.587500,0.687500,0.050000,0.050000},{0.587500,0.687500,0.100000,0.100000},{0.612500,0.687500,0.050000,0.050000},{0.612500,0.687500,0.100000,0.100000},{0.637500,0.687500,0.050000,0.050000},{0.637500,0.687500,0.100000,0.100000},{0.662500,0.687500,0.050000,0.050000},{0.662500,0.687500,0.100000,0.100000},{0.687500,0.687500,0.050000,0.050000},{0.687500,0.687500,0.100000,0.100000},{0.712500,0.687500,0.050000,0.050000},{0.712500,0.687500,0.100000,0.100000},{0.737500,0.687500,0.050000,0.050000},{0.737500,0.687500,0.100000,0.100000},{0.762500,0.687500,0.050000,0.050000},{0.762500,0.687500,0.100000,0.100000},{0.787500,0.687500,0.050000,0.050000},{0.787500,0.687500,0.100000,0.100000},{0.812500,0.687500,0.050000,0.050000},{0.812500,0.687500,0.100000,0.100000},{0.837500,0.687500,0.050000,0.050000},{0.837500,0.687500,0.100000,0.100000},{0.862500,0.687500,0.050000,0.050000},{0.862500,0.687500,0.100000,0.100000},{0.887500,0.687500,0.050000,0.050000},{0.887500,0.687500,0.100000,0.100000},{0.912500,0.687500,0.050000,0.050000},{0.912500,0.687500,0.100000,0.100000},{0.937500,0.687500,0.050000,0.050000},{0.937500,0.687500,0.100000,0.100000},{0.962500,0.687500,0.050000,0.050000},{0.962500,0.687500,0.100000,0.100000},{0.987500,0.687500,0.050000,0.050000},{0.987500,0.687500,0.100000,0.100000},{0.012500,0.712500,0.050000,0.050000},{0.012500,0.712500,0.100000,0.100000},{0.037500,0.712500,0.050000,0.050000},{0.037500,0.712500,0.100000,0.100000},{0.062500,0.712500,0.050000,0.050000},{0.062500,0.712500,0.100000,0.100000},{0.087500,0.712500,0.050000,0.050000},{0.087500,0.712500,0.100000,0.100000},{0.112500,0.712500,0.050000,0.050000},{0.112500,0.712500,0.100000,0.100000},{0.137500,0.712500,0.050000,0.050000},{0.137500,0.712500,0.100000,0.100000},{0.162500,0.712500,0.050000,0.050000},{0.162500,0.712500,0.100000,0.100000},{0.187500,0.712500,0.050000,0.050000},{0.187500,0.712500,0.100000,0.100000},{0.212500,0.712500,0.050000,0.050000},{0.212500,0.712500,0.100000,0.100000},{0.237500,0.712500,0.050000,0.050000},{0.237500,0.712500,0.100000,0.100000},{0.262500,0.712500,0.050000,0.050000},{0.262500,0.712500,0.100000,0.100000},{0.287500,0.712500,0.050000,0.050000},{0.287500,0.712500,0.100000,0.100000},{0.312500,0.712500,0.050000,0.050000},{0.312500,0.712500,0.100000,0.100000},{0.337500,0.712500,0.050000,0.050000},{0.337500,0.712500,0.100000,0.100000},{0.362500,0.712500,0.050000,0.050000},{0.362500,0.712500,0.100000,0.100000},{0.387500,0.712500,0.050000,0.050000},{0.387500,0.712500,0.100000,0.100000},{0.412500,0.712500,0.050000,0.050000},{0.412500,0.712500,0.100000,0.100000},{0.437500,0.712500,0.050000,0.050000},{0.437500,0.712500,0.100000,0.100000},{0.462500,0.712500,0.050000,0.050000},{0.462500,0.712500,0.100000,0.100000},{0.487500,0.712500,0.050000,0.050000},{0.487500,0.712500,0.100000,0.100000},{0.512500,0.712500,0.050000,0.050000},{0.512500,0.712500,0.100000,0.100000},{0.537500,0.712500,0.050000,0.050000},{0.537500,0.712500,0.100000,0.100000},{0.562500,0.712500,0.050000,0.050000},{0.562500,0.712500,0.100000,0.100000},{0.587500,0.712500,0.050000,0.050000},{0.587500,0.712500,0.100000,0.100000},{0.612500,0.712500,0.050000,0.050000},{0.612500,0.712500,0.100000,0.100000},{0.637500,0.712500,0.050000,0.050000},{0.637500,0.712500,0.100000,0.100000},{0.662500,0.712500,0.050000,0.050000},{0.662500,0.712500,0.100000,0.100000},{0.687500,0.712500,0.050000,0.050000},{0.687500,0.712500,0.100000,0.100000},{0.712500,0.712500,0.050000,0.050000},{0.712500,0.712500,0.100000,0.100000},{0.737500,0.712500,0.050000,0.050000},{0.737500,0.712500,0.100000,0.100000},{0.762500,0.712500,0.050000,0.050000},{0.762500,0.712500,0.100000,0.100000},{0.787500,0.712500,0.050000,0.050000},{0.787500,0.712500,0.100000,0.100000},{0.812500,0.712500,0.050000,0.050000},{0.812500,0.712500,0.100000,0.100000},{0.837500,0.712500,0.050000,0.050000},{0.837500,0.712500,0.100000,0.100000},{0.862500,0.712500,0.050000,0.050000},{0.862500,0.712500,0.100000,0.100000},{0.887500,0.712500,0.050000,0.050000},{0.887500,0.712500,0.100000,0.100000},{0.912500,0.712500,0.050000,0.050000},{0.912500,0.712500,0.100000,0.100000},{0.937500,0.712500,0.050000,0.050000},{0.937500,0.712500,0.100000,0.100000},{0.962500,0.712500,0.050000,0.050000},{0.962500,0.712500,0.100000,0.100000},{0.987500,0.712500,0.050000,0.050000},{0.987500,0.712500,0.100000,0.100000},{0.012500,0.737500,0.050000,0.050000},{0.012500,0.737500,0.100000,0.100000},{0.037500,0.737500,0.050000,0.050000},{0.037500,0.737500,0.100000,0.100000},{0.062500,0.737500,0.050000,0.050000},{0.062500,0.737500,0.100000,0.100000},{0.087500,0.737500,0.050000,0.050000},{0.087500,0.737500,0.100000,0.100000},{0.112500,0.737500,0.050000,0.050000},{0.112500,0.737500,0.100000,0.100000},{0.137500,0.737500,0.050000,0.050000},{0.137500,0.737500,0.100000,0.100000},{0.162500,0.737500,0.050000,0.050000},{0.162500,0.737500,0.100000,0.100000},{0.187500,0.737500,0.050000,0.050000},{0.187500,0.737500,0.100000,0.100000},{0.212500,0.737500,0.050000,0.050000},{0.212500,0.737500,0.100000,0.100000},{0.237500,0.737500,0.050000,0.050000},{0.237500,0.737500,0.100000,0.100000},{0.262500,0.737500,0.050000,0.050000},{0.262500,0.737500,0.100000,0.100000},{0.287500,0.737500,0.050000,0.050000},{0.287500,0.737500,0.100000,0.100000},{0.312500,0.737500,0.050000,0.050000},{0.312500,0.737500,0.100000,0.100000},{0.337500,0.737500,0.050000,0.050000},{0.337500,0.737500,0.100000,0.100000},{0.362500,0.737500,0.050000,0.050000},{0.362500,0.737500,0.100000,0.100000},{0.387500,0.737500,0.050000,0.050000},{0.387500,0.737500,0.100000,0.100000},{0.412500,0.737500,0.050000,0.050000},{0.412500,0.737500,0.100000,0.100000},{0.437500,0.737500,0.050000,0.050000},{0.437500,0.737500,0.100000,0.100000},{0.462500,0.737500,0.050000,0.050000},{0.462500,0.737500,0.100000,0.100000},{0.487500,0.737500,0.050000,0.050000},{0.487500,0.737500,0.100000,0.100000},{0.512500,0.737500,0.050000,0.050000},{0.512500,0.737500,0.100000,0.100000},{0.537500,0.737500,0.050000,0.050000},{0.537500,0.737500,0.100000,0.100000},{0.562500,0.737500,0.050000,0.050000},{0.562500,0.737500,0.100000,0.100000},{0.587500,0.737500,0.050000,0.050000},{0.587500,0.737500,0.100000,0.100000},{0.612500,0.737500,0.050000,0.050000},{0.612500,0.737500,0.100000,0.100000},{0.637500,0.737500,0.050000,0.050000},{0.637500,0.737500,0.100000,0.100000},{0.662500,0.737500,0.050000,0.050000},{0.662500,0.737500,0.100000,0.100000},{0.687500,0.737500,0.050000,0.050000},{0.687500,0.737500,0.100000,0.100000},{0.712500,0.737500,0.050000,0.050000},{0.712500,0.737500,0.100000,0.100000},{0.737500,0.737500,0.050000,0.050000},{0.737500,0.737500,0.100000,0.100000},{0.762500,0.737500,0.050000,0.050000},{0.762500,0.737500,0.100000,0.100000},{0.787500,0.737500,0.050000,0.050000},{0.787500,0.737500,0.100000,0.100000},{0.812500,0.737500,0.050000,0.050000},{0.812500,0.737500,0.100000,0.100000},{0.837500,0.737500,0.050000,0.050000},{0.837500,0.737500,0.100000,0.100000},{0.862500,0.737500,0.050000,0.050000},{0.862500,0.737500,0.100000,0.100000},{0.887500,0.737500,0.050000,0.050000},{0.887500,0.737500,0.100000,0.100000},{0.912500,0.737500,0.050000,0.050000},{0.912500,0.737500,0.100000,0.100000},{0.937500,0.737500,0.050000,0.050000},{0.937500,0.737500,0.100000,0.100000},{0.962500,0.737500,0.050000,0.050000},{0.962500,0.737500,0.100000,0.100000},{0.987500,0.737500,0.050000,0.050000},{0.987500,0.737500,0.100000,0.100000},{0.012500,0.762500,0.050000,0.050000},{0.012500,0.762500,0.100000,0.100000},{0.037500,0.762500,0.050000,0.050000},{0.037500,0.762500,0.100000,0.100000},{0.062500,0.762500,0.050000,0.050000},{0.062500,0.762500,0.100000,0.100000},{0.087500,0.762500,0.050000,0.050000},{0.087500,0.762500,0.100000,0.100000},{0.112500,0.762500,0.050000,0.050000},{0.112500,0.762500,0.100000,0.100000},{0.137500,0.762500,0.050000,0.050000},{0.137500,0.762500,0.100000,0.100000},{0.162500,0.762500,0.050000,0.050000},{0.162500,0.762500,0.100000,0.100000},{0.187500,0.762500,0.050000,0.050000},{0.187500,0.762500,0.100000,0.100000},{0.212500,0.762500,0.050000,0.050000},{0.212500,0.762500,0.100000,0.100000},{0.237500,0.762500,0.050000,0.050000},{0.237500,0.762500,0.100000,0.100000},{0.262500,0.762500,0.050000,0.050000},{0.262500,0.762500,0.100000,0.100000},{0.287500,0.762500,0.050000,0.050000},{0.287500,0.762500,0.100000,0.100000},{0.312500,0.762500,0.050000,0.050000},{0.312500,0.762500,0.100000,0.100000},{0.337500,0.762500,0.050000,0.050000},{0.337500,0.762500,0.100000,0.100000},{0.362500,0.762500,0.050000,0.050000},{0.362500,0.762500,0.100000,0.100000},{0.387500,0.762500,0.050000,0.050000},{0.387500,0.762500,0.100000,0.100000},{0.412500,0.762500,0.050000,0.050000},{0.412500,0.762500,0.100000,0.100000},{0.437500,0.762500,0.050000,0.050000},{0.437500,0.762500,0.100000,0.100000},{0.462500,0.762500,0.050000,0.050000},{0.462500,0.762500,0.100000,0.100000},{0.487500,0.762500,0.050000,0.050000},{0.487500,0.762500,0.100000,0.100000},{0.512500,0.762500,0.050000,0.050000},{0.512500,0.762500,0.100000,0.100000},{0.537500,0.762500,0.050000,0.050000},{0.537500,0.762500,0.100000,0.100000},{0.562500,0.762500,0.050000,0.050000},{0.562500,0.762500,0.100000,0.100000},{0.587500,0.762500,0.050000,0.050000},{0.587500,0.762500,0.100000,0.100000},{0.612500,0.762500,0.050000,0.050000},{0.612500,0.762500,0.100000,0.100000},{0.637500,0.762500,0.050000,0.050000},{0.637500,0.762500,0.100000,0.100000},{0.662500,0.762500,0.050000,0.050000},{0.662500,0.762500,0.100000,0.100000},{0.687500,0.762500,0.050000,0.050000},{0.687500,0.762500,0.100000,0.100000},{0.712500,0.762500,0.050000,0.050000},{0.712500,0.762500,0.100000,0.100000},{0.737500,0.762500,0.050000,0.050000},{0.737500,0.762500,0.100000,0.100000},{0.762500,0.762500,0.050000,0.050000},{0.762500,0.762500,0.100000,0.100000},{0.787500,0.762500,0.050000,0.050000},{0.787500,0.762500,0.100000,0.100000},{0.812500,0.762500,0.050000,0.050000},{0.812500,0.762500,0.100000,0.100000},{0.837500,0.762500,0.050000,0.050000},{0.837500,0.762500,0.100000,0.100000},{0.862500,0.762500,0.050000,0.050000},{0.862500,0.762500,0.100000,0.100000},{0.887500,0.762500,0.050000,0.050000},{0.887500,0.762500,0.100000,0.100000},{0.912500,0.762500,0.050000,0.050000},{0.912500,0.762500,0.100000,0.100000},{0.937500,0.762500,0.050000,0.050000},{0.937500,0.762500,0.100000,0.100000},{0.962500,0.762500,0.050000,0.050000},{0.962500,0.762500,0.100000,0.100000},{0.987500,0.762500,0.050000,0.050000},{0.987500,0.762500,0.100000,0.100000},{0.012500,0.787500,0.050000,0.050000},{0.012500,0.787500,0.100000,0.100000},{0.037500,0.787500,0.050000,0.050000},{0.037500,0.787500,0.100000,0.100000},{0.062500,0.787500,0.050000,0.050000},{0.062500,0.787500,0.100000,0.100000},{0.087500,0.787500,0.050000,0.050000},{0.087500,0.787500,0.100000,0.100000},{0.112500,0.787500,0.050000,0.050000},{0.112500,0.787500,0.100000,0.100000},{0.137500,0.787500,0.050000,0.050000},{0.137500,0.787500,0.100000,0.100000},{0.162500,0.787500,0.050000,0.050000},{0.162500,0.787500,0.100000,0.100000},{0.187500,0.787500,0.050000,0.050000},{0.187500,0.787500,0.100000,0.100000},{0.212500,0.787500,0.050000,0.050000},{0.212500,0.787500,0.100000,0.100000},{0.237500,0.787500,0.050000,0.050000},{0.237500,0.787500,0.100000,0.100000},{0.262500,0.787500,0.050000,0.050000},{0.262500,0.787500,0.100000,0.100000},{0.287500,0.787500,0.050000,0.050000},{0.287500,0.787500,0.100000,0.100000},{0.312500,0.787500,0.050000,0.050000},{0.312500,0.787500,0.100000,0.100000},{0.337500,0.787500,0.050000,0.050000},{0.337500,0.787500,0.100000,0.100000},{0.362500,0.787500,0.050000,0.050000},{0.362500,0.787500,0.100000,0.100000},{0.387500,0.787500,0.050000,0.050000},{0.387500,0.787500,0.100000,0.100000},{0.412500,0.787500,0.050000,0.050000},{0.412500,0.787500,0.100000,0.100000},{0.437500,0.787500,0.050000,0.050000},{0.437500,0.787500,0.100000,0.100000},{0.462500,0.787500,0.050000,0.050000},{0.462500,0.787500,0.100000,0.100000},{0.487500,0.787500,0.050000,0.050000},{0.487500,0.787500,0.100000,0.100000},{0.512500,0.787500,0.050000,0.050000},{0.512500,0.787500,0.100000,0.100000},{0.537500,0.787500,0.050000,0.050000},{0.537500,0.787500,0.100000,0.100000},{0.562500,0.787500,0.050000,0.050000},{0.562500,0.787500,0.100000,0.100000},{0.587500,0.787500,0.050000,0.050000},{0.587500,0.787500,0.100000,0.100000},{0.612500,0.787500,0.050000,0.050000},{0.612500,0.787500,0.100000,0.100000},{0.637500,0.787500,0.050000,0.050000},{0.637500,0.787500,0.100000,0.100000},{0.662500,0.787500,0.050000,0.050000},{0.662500,0.787500,0.100000,0.100000},{0.687500,0.787500,0.050000,0.050000},{0.687500,0.787500,0.100000,0.100000},{0.712500,0.787500,0.050000,0.050000},{0.712500,0.787500,0.100000,0.100000},{0.737500,0.787500,0.050000,0.050000},{0.737500,0.787500,0.100000,0.100000},{0.762500,0.787500,0.050000,0.050000},{0.762500,0.787500,0.100000,0.100000},{0.787500,0.787500,0.050000,0.050000},{0.787500,0.787500,0.100000,0.100000},{0.812500,0.787500,0.050000,0.050000},{0.812500,0.787500,0.100000,0.100000},{0.837500,0.787500,0.050000,0.050000},{0.837500,0.787500,0.100000,0.100000},{0.862500,0.787500,0.050000,0.050000},{0.862500,0.787500,0.100000,0.100000},{0.887500,0.787500,0.050000,0.050000},{0.887500,0.787500,0.100000,0.100000},{0.912500,0.787500,0.050000,0.050000},{0.912500,0.787500,0.100000,0.100000},{0.937500,0.787500,0.050000,0.050000},{0.937500,0.787500,0.100000,0.100000},{0.962500,0.787500,0.050000,0.050000},{0.962500,0.787500,0.100000,0.100000},{0.987500,0.787500,0.050000,0.050000},{0.987500,0.787500,0.100000,0.100000},{0.012500,0.812500,0.050000,0.050000},{0.012500,0.812500,0.100000,0.100000},{0.037500,0.812500,0.050000,0.050000},{0.037500,0.812500,0.100000,0.100000},{0.062500,0.812500,0.050000,0.050000},{0.062500,0.812500,0.100000,0.100000},{0.087500,0.812500,0.050000,0.050000},{0.087500,0.812500,0.100000,0.100000},{0.112500,0.812500,0.050000,0.050000},{0.112500,0.812500,0.100000,0.100000},{0.137500,0.812500,0.050000,0.050000},{0.137500,0.812500,0.100000,0.100000},{0.162500,0.812500,0.050000,0.050000},{0.162500,0.812500,0.100000,0.100000},{0.187500,0.812500,0.050000,0.050000},{0.187500,0.812500,0.100000,0.100000},{0.212500,0.812500,0.050000,0.050000},{0.212500,0.812500,0.100000,0.100000},{0.237500,0.812500,0.050000,0.050000},{0.237500,0.812500,0.100000,0.100000},{0.262500,0.812500,0.050000,0.050000},{0.262500,0.812500,0.100000,0.100000},{0.287500,0.812500,0.050000,0.050000},{0.287500,0.812500,0.100000,0.100000},{0.312500,0.812500,0.050000,0.050000},{0.312500,0.812500,0.100000,0.100000},{0.337500,0.812500,0.050000,0.050000},{0.337500,0.812500,0.100000,0.100000},{0.362500,0.812500,0.050000,0.050000},{0.362500,0.812500,0.100000,0.100000},{0.387500,0.812500,0.050000,0.050000},{0.387500,0.812500,0.100000,0.100000},{0.412500,0.812500,0.050000,0.050000},{0.412500,0.812500,0.100000,0.100000},{0.437500,0.812500,0.050000,0.050000},{0.437500,0.812500,0.100000,0.100000},{0.462500,0.812500,0.050000,0.050000},{0.462500,0.812500,0.100000,0.100000},{0.487500,0.812500,0.050000,0.050000},{0.487500,0.812500,0.100000,0.100000},{0.512500,0.812500,0.050000,0.050000},{0.512500,0.812500,0.100000,0.100000},{0.537500,0.812500,0.050000,0.050000},{0.537500,0.812500,0.100000,0.100000},{0.562500,0.812500,0.050000,0.050000},{0.562500,0.812500,0.100000,0.100000},{0.587500,0.812500,0.050000,0.050000},{0.587500,0.812500,0.100000,0.100000},{0.612500,0.812500,0.050000,0.050000},{0.612500,0.812500,0.100000,0.100000},{0.637500,0.812500,0.050000,0.050000},{0.637500,0.812500,0.100000,0.100000},{0.662500,0.812500,0.050000,0.050000},{0.662500,0.812500,0.100000,0.100000},{0.687500,0.812500,0.050000,0.050000},{0.687500,0.812500,0.100000,0.100000},{0.712500,0.812500,0.050000,0.050000},{0.712500,0.812500,0.100000,0.100000},{0.737500,0.812500,0.050000,0.050000},{0.737500,0.812500,0.100000,0.100000},{0.762500,0.812500,0.050000,0.050000},{0.762500,0.812500,0.100000,0.100000},{0.787500,0.812500,0.050000,0.050000},{0.787500,0.812500,0.100000,0.100000},{0.812500,0.812500,0.050000,0.050000},{0.812500,0.812500,0.100000,0.100000},{0.837500,0.812500,0.050000,0.050000},{0.837500,0.812500,0.100000,0.100000},{0.862500,0.812500,0.050000,0.050000},{0.862500,0.812500,0.100000,0.100000},{0.887500,0.812500,0.050000,0.050000},{0.887500,0.812500,0.100000,0.100000},{0.912500,0.812500,0.050000,0.050000},{0.912500,0.812500,0.100000,0.100000},{0.937500,0.812500,0.050000,0.050000},{0.937500,0.812500,0.100000,0.100000},{0.962500,0.812500,0.050000,0.050000},{0.962500,0.812500,0.100000,0.100000},{0.987500,0.812500,0.050000,0.050000},{0.987500,0.812500,0.100000,0.100000},{0.012500,0.837500,0.050000,0.050000},{0.012500,0.837500,0.100000,0.100000},{0.037500,0.837500,0.050000,0.050000},{0.037500,0.837500,0.100000,0.100000},{0.062500,0.837500,0.050000,0.050000},{0.062500,0.837500,0.100000,0.100000},{0.087500,0.837500,0.050000,0.050000},{0.087500,0.837500,0.100000,0.100000},{0.112500,0.837500,0.050000,0.050000},{0.112500,0.837500,0.100000,0.100000},{0.137500,0.837500,0.050000,0.050000},{0.137500,0.837500,0.100000,0.100000},{0.162500,0.837500,0.050000,0.050000},{0.162500,0.837500,0.100000,0.100000},{0.187500,0.837500,0.050000,0.050000},{0.187500,0.837500,0.100000,0.100000},{0.212500,0.837500,0.050000,0.050000},{0.212500,0.837500,0.100000,0.100000},{0.237500,0.837500,0.050000,0.050000},{0.237500,0.837500,0.100000,0.100000},{0.262500,0.837500,0.050000,0.050000},{0.262500,0.837500,0.100000,0.100000},{0.287500,0.837500,0.050000,0.050000},{0.287500,0.837500,0.100000,0.100000},{0.312500,0.837500,0.050000,0.050000},{0.312500,0.837500,0.100000,0.100000},{0.337500,0.837500,0.050000,0.050000},{0.337500,0.837500,0.100000,0.100000},{0.362500,0.837500,0.050000,0.050000},{0.362500,0.837500,0.100000,0.100000},{0.387500,0.837500,0.050000,0.050000},{0.387500,0.837500,0.100000,0.100000},{0.412500,0.837500,0.050000,0.050000},{0.412500,0.837500,0.100000,0.100000},{0.437500,0.837500,0.050000,0.050000},{0.437500,0.837500,0.100000,0.100000},{0.462500,0.837500,0.050000,0.050000},{0.462500,0.837500,0.100000,0.100000},{0.487500,0.837500,0.050000,0.050000},{0.487500,0.837500,0.100000,0.100000},{0.512500,0.837500,0.050000,0.050000},{0.512500,0.837500,0.100000,0.100000},{0.537500,0.837500,0.050000,0.050000},{0.537500,0.837500,0.100000,0.100000},{0.562500,0.837500,0.050000,0.050000},{0.562500,0.837500,0.100000,0.100000},{0.587500,0.837500,0.050000,0.050000},{0.587500,0.837500,0.100000,0.100000},{0.612500,0.837500,0.050000,0.050000},{0.612500,0.837500,0.100000,0.100000},{0.637500,0.837500,0.050000,0.050000},{0.637500,0.837500,0.100000,0.100000},{0.662500,0.837500,0.050000,0.050000},{0.662500,0.837500,0.100000,0.100000},{0.687500,0.837500,0.050000,0.050000},{0.687500,0.837500,0.100000,0.100000},{0.712500,0.837500,0.050000,0.050000},{0.712500,0.837500,0.100000,0.100000},{0.737500,0.837500,0.050000,0.050000},{0.737500,0.837500,0.100000,0.100000},{0.762500,0.837500,0.050000,0.050000},{0.762500,0.837500,0.100000,0.100000},{0.787500,0.837500,0.050000,0.050000},{0.787500,0.837500,0.100000,0.100000},{0.812500,0.837500,0.050000,0.050000},{0.812500,0.837500,0.100000,0.100000},{0.837500,0.837500,0.050000,0.050000},{0.837500,0.837500,0.100000,0.100000},{0.862500,0.837500,0.050000,0.050000},{0.862500,0.837500,0.100000,0.100000},{0.887500,0.837500,0.050000,0.050000},{0.887500,0.837500,0.100000,0.100000},{0.912500,0.837500,0.050000,0.050000},{0.912500,0.837500,0.100000,0.100000},{0.937500,0.837500,0.050000,0.050000},{0.937500,0.837500,0.100000,0.100000},{0.962500,0.837500,0.050000,0.050000},{0.962500,0.837500,0.100000,0.100000},{0.987500,0.837500,0.050000,0.050000},{0.987500,0.837500,0.100000,0.100000},{0.012500,0.862500,0.050000,0.050000},{0.012500,0.862500,0.100000,0.100000},{0.037500,0.862500,0.050000,0.050000},{0.037500,0.862500,0.100000,0.100000},{0.062500,0.862500,0.050000,0.050000},{0.062500,0.862500,0.100000,0.100000},{0.087500,0.862500,0.050000,0.050000},{0.087500,0.862500,0.100000,0.100000},{0.112500,0.862500,0.050000,0.050000},{0.112500,0.862500,0.100000,0.100000},{0.137500,0.862500,0.050000,0.050000},{0.137500,0.862500,0.100000,0.100000},{0.162500,0.862500,0.050000,0.050000},{0.162500,0.862500,0.100000,0.100000},{0.187500,0.862500,0.050000,0.050000},{0.187500,0.862500,0.100000,0.100000},{0.212500,0.862500,0.050000,0.050000},{0.212500,0.862500,0.100000,0.100000},{0.237500,0.862500,0.050000,0.050000},{0.237500,0.862500,0.100000,0.100000},{0.262500,0.862500,0.050000,0.050000},{0.262500,0.862500,0.100000,0.100000},{0.287500,0.862500,0.050000,0.050000},{0.287500,0.862500,0.100000,0.100000},{0.312500,0.862500,0.050000,0.050000},{0.312500,0.862500,0.100000,0.100000},{0.337500,0.862500,0.050000,0.050000},{0.337500,0.862500,0.100000,0.100000},{0.362500,0.862500,0.050000,0.050000},{0.362500,0.862500,0.100000,0.100000},{0.387500,0.862500,0.050000,0.050000},{0.387500,0.862500,0.100000,0.100000},{0.412500,0.862500,0.050000,0.050000},{0.412500,0.862500,0.100000,0.100000},{0.437500,0.862500,0.050000,0.050000},{0.437500,0.862500,0.100000,0.100000},{0.462500,0.862500,0.050000,0.050000},{0.462500,0.862500,0.100000,0.100000},{0.487500,0.862500,0.050000,0.050000},{0.487500,0.862500,0.100000,0.100000},{0.512500,0.862500,0.050000,0.050000},{0.512500,0.862500,0.100000,0.100000},{0.537500,0.862500,0.050000,0.050000},{0.537500,0.862500,0.100000,0.100000},{0.562500,0.862500,0.050000,0.050000},{0.562500,0.862500,0.100000,0.100000},{0.587500,0.862500,0.050000,0.050000},{0.587500,0.862500,0.100000,0.100000},{0.612500,0.862500,0.050000,0.050000},{0.612500,0.862500,0.100000,0.100000},{0.637500,0.862500,0.050000,0.050000},{0.637500,0.862500,0.100000,0.100000},{0.662500,0.862500,0.050000,0.050000},{0.662500,0.862500,0.100000,0.100000},{0.687500,0.862500,0.050000,0.050000},{0.687500,0.862500,0.100000,0.100000},{0.712500,0.862500,0.050000,0.050000},{0.712500,0.862500,0.100000,0.100000},{0.737500,0.862500,0.050000,0.050000},{0.737500,0.862500,0.100000,0.100000},{0.762500,0.862500,0.050000,0.050000},{0.762500,0.862500,0.100000,0.100000},{0.787500,0.862500,0.050000,0.050000},{0.787500,0.862500,0.100000,0.100000},{0.812500,0.862500,0.050000,0.050000},{0.812500,0.862500,0.100000,0.100000},{0.837500,0.862500,0.050000,0.050000},{0.837500,0.862500,0.100000,0.100000},{0.862500,0.862500,0.050000,0.050000},{0.862500,0.862500,0.100000,0.100000},{0.887500,0.862500,0.050000,0.050000},{0.887500,0.862500,0.100000,0.100000},{0.912500,0.862500,0.050000,0.050000},{0.912500,0.862500,0.100000,0.100000},{0.937500,0.862500,0.050000,0.050000},{0.937500,0.862500,0.100000,0.100000},{0.962500,0.862500,0.050000,0.050000},{0.962500,0.862500,0.100000,0.100000},{0.987500,0.862500,0.050000,0.050000},{0.987500,0.862500,0.100000,0.100000},{0.012500,0.887500,0.050000,0.050000},{0.012500,0.887500,0.100000,0.100000},{0.037500,0.887500,0.050000,0.050000},{0.037500,0.887500,0.100000,0.100000},{0.062500,0.887500,0.050000,0.050000},{0.062500,0.887500,0.100000,0.100000},{0.087500,0.887500,0.050000,0.050000},{0.087500,0.887500,0.100000,0.100000},{0.112500,0.887500,0.050000,0.050000},{0.112500,0.887500,0.100000,0.100000},{0.137500,0.887500,0.050000,0.050000},{0.137500,0.887500,0.100000,0.100000},{0.162500,0.887500,0.050000,0.050000},{0.162500,0.887500,0.100000,0.100000},{0.187500,0.887500,0.050000,0.050000},{0.187500,0.887500,0.100000,0.100000},{0.212500,0.887500,0.050000,0.050000},{0.212500,0.887500,0.100000,0.100000},{0.237500,0.887500,0.050000,0.050000},{0.237500,0.887500,0.100000,0.100000},{0.262500,0.887500,0.050000,0.050000},{0.262500,0.887500,0.100000,0.100000},{0.287500,0.887500,0.050000,0.050000},{0.287500,0.887500,0.100000,0.100000},{0.312500,0.887500,0.050000,0.050000},{0.312500,0.887500,0.100000,0.100000},{0.337500,0.887500,0.050000,0.050000},{0.337500,0.887500,0.100000,0.100000},{0.362500,0.887500,0.050000,0.050000},{0.362500,0.887500,0.100000,0.100000},{0.387500,0.887500,0.050000,0.050000},{0.387500,0.887500,0.100000,0.100000},{0.412500,0.887500,0.050000,0.050000},{0.412500,0.887500,0.100000,0.100000},{0.437500,0.887500,0.050000,0.050000},{0.437500,0.887500,0.100000,0.100000},{0.462500,0.887500,0.050000,0.050000},{0.462500,0.887500,0.100000,0.100000},{0.487500,0.887500,0.050000,0.050000},{0.487500,0.887500,0.100000,0.100000},{0.512500,0.887500,0.050000,0.050000},{0.512500,0.887500,0.100000,0.100000},{0.537500,0.887500,0.050000,0.050000},{0.537500,0.887500,0.100000,0.100000},{0.562500,0.887500,0.050000,0.050000},{0.562500,0.887500,0.100000,0.100000},{0.587500,0.887500,0.050000,0.050000},{0.587500,0.887500,0.100000,0.100000},{0.612500,0.887500,0.050000,0.050000},{0.612500,0.887500,0.100000,0.100000},{0.637500,0.887500,0.050000,0.050000},{0.637500,0.887500,0.100000,0.100000},{0.662500,0.887500,0.050000,0.050000},{0.662500,0.887500,0.100000,0.100000},{0.687500,0.887500,0.050000,0.050000},{0.687500,0.887500,0.100000,0.100000},{0.712500,0.887500,0.050000,0.050000},{0.712500,0.887500,0.100000,0.100000},{0.737500,0.887500,0.050000,0.050000},{0.737500,0.887500,0.100000,0.100000},{0.762500,0.887500,0.050000,0.050000},{0.762500,0.887500,0.100000,0.100000},{0.787500,0.887500,0.050000,0.050000},{0.787500,0.887500,0.100000,0.100000},{0.812500,0.887500,0.050000,0.050000},{0.812500,0.887500,0.100000,0.100000},{0.837500,0.887500,0.050000,0.050000},{0.837500,0.887500,0.100000,0.100000},{0.862500,0.887500,0.050000,0.050000},{0.862500,0.887500,0.100000,0.100000},{0.887500,0.887500,0.050000,0.050000},{0.887500,0.887500,0.100000,0.100000},{0.912500,0.887500,0.050000,0.050000},{0.912500,0.887500,0.100000,0.100000},{0.937500,0.887500,0.050000,0.050000},{0.937500,0.887500,0.100000,0.100000},{0.962500,0.887500,0.050000,0.050000},{0.962500,0.887500,0.100000,0.100000},{0.987500,0.887500,0.050000,0.050000},{0.987500,0.887500,0.100000,0.100000},{0.012500,0.912500,0.050000,0.050000},{0.012500,0.912500,0.100000,0.100000},{0.037500,0.912500,0.050000,0.050000},{0.037500,0.912500,0.100000,0.100000},{0.062500,0.912500,0.050000,0.050000},{0.062500,0.912500,0.100000,0.100000},{0.087500,0.912500,0.050000,0.050000},{0.087500,0.912500,0.100000,0.100000},{0.112500,0.912500,0.050000,0.050000},{0.112500,0.912500,0.100000,0.100000},{0.137500,0.912500,0.050000,0.050000},{0.137500,0.912500,0.100000,0.100000},{0.162500,0.912500,0.050000,0.050000},{0.162500,0.912500,0.100000,0.100000},{0.187500,0.912500,0.050000,0.050000},{0.187500,0.912500,0.100000,0.100000},{0.212500,0.912500,0.050000,0.050000},{0.212500,0.912500,0.100000,0.100000},{0.237500,0.912500,0.050000,0.050000},{0.237500,0.912500,0.100000,0.100000},{0.262500,0.912500,0.050000,0.050000},{0.262500,0.912500,0.100000,0.100000},{0.287500,0.912500,0.050000,0.050000},{0.287500,0.912500,0.100000,0.100000},{0.312500,0.912500,0.050000,0.050000},{0.312500,0.912500,0.100000,0.100000},{0.337500,0.912500,0.050000,0.050000},{0.337500,0.912500,0.100000,0.100000},{0.362500,0.912500,0.050000,0.050000},{0.362500,0.912500,0.100000,0.100000},{0.387500,0.912500,0.050000,0.050000},{0.387500,0.912500,0.100000,0.100000},{0.412500,0.912500,0.050000,0.050000},{0.412500,0.912500,0.100000,0.100000},{0.437500,0.912500,0.050000,0.050000},{0.437500,0.912500,0.100000,0.100000},{0.462500,0.912500,0.050000,0.050000},{0.462500,0.912500,0.100000,0.100000},{0.487500,0.912500,0.050000,0.050000},{0.487500,0.912500,0.100000,0.100000},{0.512500,0.912500,0.050000,0.050000},{0.512500,0.912500,0.100000,0.100000},{0.537500,0.912500,0.050000,0.050000},{0.537500,0.912500,0.100000,0.100000},{0.562500,0.912500,0.050000,0.050000},{0.562500,0.912500,0.100000,0.100000},{0.587500,0.912500,0.050000,0.050000},{0.587500,0.912500,0.100000,0.100000},{0.612500,0.912500,0.050000,0.050000},{0.612500,0.912500,0.100000,0.100000},{0.637500,0.912500,0.050000,0.050000},{0.637500,0.912500,0.100000,0.100000},{0.662500,0.912500,0.050000,0.050000},{0.662500,0.912500,0.100000,0.100000},{0.687500,0.912500,0.050000,0.050000},{0.687500,0.912500,0.100000,0.100000},{0.712500,0.912500,0.050000,0.050000},{0.712500,0.912500,0.100000,0.100000},{0.737500,0.912500,0.050000,0.050000},{0.737500,0.912500,0.100000,0.100000},{0.762500,0.912500,0.050000,0.050000},{0.762500,0.912500,0.100000,0.100000},{0.787500,0.912500,0.050000,0.050000},{0.787500,0.912500,0.100000,0.100000},{0.812500,0.912500,0.050000,0.050000},{0.812500,0.912500,0.100000,0.100000},{0.837500,0.912500,0.050000,0.050000},{0.837500,0.912500,0.100000,0.100000},{0.862500,0.912500,0.050000,0.050000},{0.862500,0.912500,0.100000,0.100000},{0.887500,0.912500,0.050000,0.050000},{0.887500,0.912500,0.100000,0.100000},{0.912500,0.912500,0.050000,0.050000},{0.912500,0.912500,0.100000,0.100000},{0.937500,0.912500,0.050000,0.050000},{0.937500,0.912500,0.100000,0.100000},{0.962500,0.912500,0.050000,0.050000},{0.962500,0.912500,0.100000,0.100000},{0.987500,0.912500,0.050000,0.050000},{0.987500,0.912500,0.100000,0.100000},{0.012500,0.937500,0.050000,0.050000},{0.012500,0.937500,0.100000,0.100000},{0.037500,0.937500,0.050000,0.050000},{0.037500,0.937500,0.100000,0.100000},{0.062500,0.937500,0.050000,0.050000},{0.062500,0.937500,0.100000,0.100000},{0.087500,0.937500,0.050000,0.050000},{0.087500,0.937500,0.100000,0.100000},{0.112500,0.937500,0.050000,0.050000},{0.112500,0.937500,0.100000,0.100000},{0.137500,0.937500,0.050000,0.050000},{0.137500,0.937500,0.100000,0.100000},{0.162500,0.937500,0.050000,0.050000},{0.162500,0.937500,0.100000,0.100000},{0.187500,0.937500,0.050000,0.050000},{0.187500,0.937500,0.100000,0.100000},{0.212500,0.937500,0.050000,0.050000},{0.212500,0.937500,0.100000,0.100000},{0.237500,0.937500,0.050000,0.050000},{0.237500,0.937500,0.100000,0.100000},{0.262500,0.937500,0.050000,0.050000},{0.262500,0.937500,0.100000,0.100000},{0.287500,0.937500,0.050000,0.050000},{0.287500,0.937500,0.100000,0.100000},{0.312500,0.937500,0.050000,0.050000},{0.312500,0.937500,0.100000,0.100000},{0.337500,0.937500,0.050000,0.050000},{0.337500,0.937500,0.100000,0.100000},{0.362500,0.937500,0.050000,0.050000},{0.362500,0.937500,0.100000,0.100000},{0.387500,0.937500,0.050000,0.050000},{0.387500,0.937500,0.100000,0.100000},{0.412500,0.937500,0.050000,0.050000},{0.412500,0.937500,0.100000,0.100000},{0.437500,0.937500,0.050000,0.050000},{0.437500,0.937500,0.100000,0.100000},{0.462500,0.937500,0.050000,0.050000},{0.462500,0.937500,0.100000,0.100000},{0.487500,0.937500,0.050000,0.050000},{0.487500,0.937500,0.100000,0.100000},{0.512500,0.937500,0.050000,0.050000},{0.512500,0.937500,0.100000,0.100000},{0.537500,0.937500,0.050000,0.050000},{0.537500,0.937500,0.100000,0.100000},{0.562500,0.937500,0.050000,0.050000},{0.562500,0.937500,0.100000,0.100000},{0.587500,0.937500,0.050000,0.050000},{0.587500,0.937500,0.100000,0.100000},{0.612500,0.937500,0.050000,0.050000},{0.612500,0.937500,0.100000,0.100000},{0.637500,0.937500,0.050000,0.050000},{0.637500,0.937500,0.100000,0.100000},{0.662500,0.937500,0.050000,0.050000},{0.662500,0.937500,0.100000,0.100000},{0.687500,0.937500,0.050000,0.050000},{0.687500,0.937500,0.100000,0.100000},{0.712500,0.937500,0.050000,0.050000},{0.712500,0.937500,0.100000,0.100000},{0.737500,0.937500,0.050000,0.050000},{0.737500,0.937500,0.100000,0.100000},{0.762500,0.937500,0.050000,0.050000},{0.762500,0.937500,0.100000,0.100000},{0.787500,0.937500,0.050000,0.050000},{0.787500,0.937500,0.100000,0.100000},{0.812500,0.937500,0.050000,0.050000},{0.812500,0.937500,0.100000,0.100000},{0.837500,0.937500,0.050000,0.050000},{0.837500,0.937500,0.100000,0.100000},{0.862500,0.937500,0.050000,0.050000},{0.862500,0.937500,0.100000,0.100000},{0.887500,0.937500,0.050000,0.050000},{0.887500,0.937500,0.100000,0.100000},{0.912500,0.937500,0.050000,0.050000},{0.912500,0.937500,0.100000,0.100000},{0.937500,0.937500,0.050000,0.050000},{0.937500,0.937500,0.100000,0.100000},{0.962500,0.937500,0.050000,0.050000},{0.962500,0.937500,0.100000,0.100000},{0.987500,0.937500,0.050000,0.050000},{0.987500,0.937500,0.100000,0.100000},{0.012500,0.962500,0.050000,0.050000},{0.012500,0.962500,0.100000,0.100000},{0.037500,0.962500,0.050000,0.050000},{0.037500,0.962500,0.100000,0.100000},{0.062500,0.962500,0.050000,0.050000},{0.062500,0.962500,0.100000,0.100000},{0.087500,0.962500,0.050000,0.050000},{0.087500,0.962500,0.100000,0.100000},{0.112500,0.962500,0.050000,0.050000},{0.112500,0.962500,0.100000,0.100000},{0.137500,0.962500,0.050000,0.050000},{0.137500,0.962500,0.100000,0.100000},{0.162500,0.962500,0.050000,0.050000},{0.162500,0.962500,0.100000,0.100000},{0.187500,0.962500,0.050000,0.050000},{0.187500,0.962500,0.100000,0.100000},{0.212500,0.962500,0.050000,0.050000},{0.212500,0.962500,0.100000,0.100000},{0.237500,0.962500,0.050000,0.050000},{0.237500,0.962500,0.100000,0.100000},{0.262500,0.962500,0.050000,0.050000},{0.262500,0.962500,0.100000,0.100000},{0.287500,0.962500,0.050000,0.050000},{0.287500,0.962500,0.100000,0.100000},{0.312500,0.962500,0.050000,0.050000},{0.312500,0.962500,0.100000,0.100000},{0.337500,0.962500,0.050000,0.050000},{0.337500,0.962500,0.100000,0.100000},{0.362500,0.962500,0.050000,0.050000},{0.362500,0.962500,0.100000,0.100000},{0.387500,0.962500,0.050000,0.050000},{0.387500,0.962500,0.100000,0.100000},{0.412500,0.962500,0.050000,0.050000},{0.412500,0.962500,0.100000,0.100000},{0.437500,0.962500,0.050000,0.050000},{0.437500,0.962500,0.100000,0.100000},{0.462500,0.962500,0.050000,0.050000},{0.462500,0.962500,0.100000,0.100000},{0.487500,0.962500,0.050000,0.050000},{0.487500,0.962500,0.100000,0.100000},{0.512500,0.962500,0.050000,0.050000},{0.512500,0.962500,0.100000,0.100000},{0.537500,0.962500,0.050000,0.050000},{0.537500,0.962500,0.100000,0.100000},{0.562500,0.962500,0.050000,0.050000},{0.562500,0.962500,0.100000,0.100000},{0.587500,0.962500,0.050000,0.050000},{0.587500,0.962500,0.100000,0.100000},{0.612500,0.962500,0.050000,0.050000},{0.612500,0.962500,0.100000,0.100000},{0.637500,0.962500,0.050000,0.050000},{0.637500,0.962500,0.100000,0.100000},{0.662500,0.962500,0.050000,0.050000},{0.662500,0.962500,0.100000,0.100000},{0.687500,0.962500,0.050000,0.050000},{0.687500,0.962500,0.100000,0.100000},{0.712500,0.962500,0.050000,0.050000},{0.712500,0.962500,0.100000,0.100000},{0.737500,0.962500,0.050000,0.050000},{0.737500,0.962500,0.100000,0.100000},{0.762500,0.962500,0.050000,0.050000},{0.762500,0.962500,0.100000,0.100000},{0.787500,0.962500,0.050000,0.050000},{0.787500,0.962500,0.100000,0.100000},{0.812500,0.962500,0.050000,0.050000},{0.812500,0.962500,0.100000,0.100000},{0.837500,0.962500,0.050000,0.050000},{0.837500,0.962500,0.100000,0.100000},{0.862500,0.962500,0.050000,0.050000},{0.862500,0.962500,0.100000,0.100000},{0.887500,0.962500,0.050000,0.050000},{0.887500,0.962500,0.100000,0.100000},{0.912500,0.962500,0.050000,0.050000},{0.912500,0.962500,0.100000,0.100000},{0.937500,0.962500,0.050000,0.050000},{0.937500,0.962500,0.100000,0.100000},{0.962500,0.962500,0.050000,0.050000},{0.962500,0.962500,0.100000,0.100000},{0.987500,0.962500,0.050000,0.050000},{0.987500,0.962500,0.100000,0.100000},{0.012500,0.987500,0.050000,0.050000},{0.012500,0.987500,0.100000,0.100000},{0.037500,0.987500,0.050000,0.050000},{0.037500,0.987500,0.100000,0.100000},{0.062500,0.987500,0.050000,0.050000},{0.062500,0.987500,0.100000,0.100000},{0.087500,0.987500,0.050000,0.050000},{0.087500,0.987500,0.100000,0.100000},{0.112500,0.987500,0.050000,0.050000},{0.112500,0.987500,0.100000,0.100000},{0.137500,0.987500,0.050000,0.050000},{0.137500,0.987500,0.100000,0.100000},{0.162500,0.987500,0.050000,0.050000},{0.162500,0.987500,0.100000,0.100000},{0.187500,0.987500,0.050000,0.050000},{0.187500,0.987500,0.100000,0.100000},{0.212500,0.987500,0.050000,0.050000},{0.212500,0.987500,0.100000,0.100000},{0.237500,0.987500,0.050000,0.050000},{0.237500,0.987500,0.100000,0.100000},{0.262500,0.987500,0.050000,0.050000},{0.262500,0.987500,0.100000,0.100000},{0.287500,0.987500,0.050000,0.050000},{0.287500,0.987500,0.100000,0.100000},{0.312500,0.987500,0.050000,0.050000},{0.312500,0.987500,0.100000,0.100000},{0.337500,0.987500,0.050000,0.050000},{0.337500,0.987500,0.100000,0.100000},{0.362500,0.987500,0.050000,0.050000},{0.362500,0.987500,0.100000,0.100000},{0.387500,0.987500,0.050000,0.050000},{0.387500,0.987500,0.100000,0.100000},{0.412500,0.987500,0.050000,0.050000},{0.412500,0.987500,0.100000,0.100000},{0.437500,0.987500,0.050000,0.050000},{0.437500,0.987500,0.100000,0.100000},{0.462500,0.987500,0.050000,0.050000},{0.462500,0.987500,0.100000,0.100000},{0.487500,0.987500,0.050000,0.050000},{0.487500,0.987500,0.100000,0.100000},{0.512500,0.987500,0.050000,0.050000},{0.512500,0.987500,0.100000,0.100000},{0.537500,0.987500,0.050000,0.050000},{0.537500,0.987500,0.100000,0.100000},{0.562500,0.987500,0.050000,0.050000},{0.562500,0.987500,0.100000,0.100000},{0.587500,0.987500,0.050000,0.050000},{0.587500,0.987500,0.100000,0.100000},{0.612500,0.987500,0.050000,0.050000},{0.612500,0.987500,0.100000,0.100000},{0.637500,0.987500,0.050000,0.050000},{0.637500,0.987500,0.100000,0.100000},{0.662500,0.987500,0.050000,0.050000},{0.662500,0.987500,0.100000,0.100000},{0.687500,0.987500,0.050000,0.050000},{0.687500,0.987500,0.100000,0.100000},{0.712500,0.987500,0.050000,0.050000},{0.712500,0.987500,0.100000,0.100000},{0.737500,0.987500,0.050000,0.050000},{0.737500,0.987500,0.100000,0.100000},{0.762500,0.987500,0.050000,0.050000},{0.762500,0.987500,0.100000,0.100000},{0.787500,0.987500,0.050000,0.050000},{0.787500,0.987500,0.100000,0.100000},{0.812500,0.987500,0.050000,0.050000},{0.812500,0.987500,0.100000,0.100000},{0.837500,0.987500,0.050000,0.050000},{0.837500,0.987500,0.100000,0.100000},{0.862500,0.987500,0.050000,0.050000},{0.862500,0.987500,0.100000,0.100000},{0.887500,0.987500,0.050000,0.050000},{0.887500,0.987500,0.100000,0.100000},{0.912500,0.987500,0.050000,0.050000},{0.912500,0.987500,0.100000,0.100000},{0.937500,0.987500,0.050000,0.050000},{0.937500,0.987500,0.100000,0.100000},{0.962500,0.987500,0.050000,0.050000},{0.962500,0.987500,0.100000,0.100000},{0.987500,0.987500,0.050000,0.050000},{0.987500,0.987500,0.100000,0.100000},{0.025000,0.025000,0.200000,0.200000},{0.025000,0.025000,0.400000,0.400000},{0.075000,0.025000,0.200000,0.200000},{0.075000,0.025000,0.400000,0.400000},{0.125000,0.025000,0.200000,0.200000},{0.125000,0.025000,0.400000,0.400000},{0.175000,0.025000,0.200000,0.200000},{0.175000,0.025000,0.400000,0.400000},{0.225000,0.025000,0.200000,0.200000},{0.225000,0.025000,0.400000,0.400000},{0.275000,0.025000,0.200000,0.200000},{0.275000,0.025000,0.400000,0.400000},{0.325000,0.025000,0.200000,0.200000},{0.325000,0.025000,0.400000,0.400000},{0.375000,0.025000,0.200000,0.200000},{0.375000,0.025000,0.400000,0.400000},{0.425000,0.025000,0.200000,0.200000},{0.425000,0.025000,0.400000,0.400000},{0.475000,0.025000,0.200000,0.200000},{0.475000,0.025000,0.400000,0.400000},{0.525000,0.025000,0.200000,0.200000},{0.525000,0.025000,0.400000,0.400000},{0.575000,0.025000,0.200000,0.200000},{0.575000,0.025000,0.400000,0.400000},{0.625000,0.025000,0.200000,0.200000},{0.625000,0.025000,0.400000,0.400000},{0.675000,0.025000,0.200000,0.200000},{0.675000,0.025000,0.400000,0.400000},{0.725000,0.025000,0.200000,0.200000},{0.725000,0.025000,0.400000,0.400000},{0.775000,0.025000,0.200000,0.200000},{0.775000,0.025000,0.400000,0.400000},{0.825000,0.025000,0.200000,0.200000},{0.825000,0.025000,0.400000,0.400000},{0.875000,0.025000,0.200000,0.200000},{0.875000,0.025000,0.400000,0.400000},{0.925000,0.025000,0.200000,0.200000},{0.925000,0.025000,0.400000,0.400000},{0.975000,0.025000,0.200000,0.200000},{0.975000,0.025000,0.400000,0.400000},{0.025000,0.075000,0.200000,0.200000},{0.025000,0.075000,0.400000,0.400000},{0.075000,0.075000,0.200000,0.200000},{0.075000,0.075000,0.400000,0.400000},{0.125000,0.075000,0.200000,0.200000},{0.125000,0.075000,0.400000,0.400000},{0.175000,0.075000,0.200000,0.200000},{0.175000,0.075000,0.400000,0.400000},{0.225000,0.075000,0.200000,0.200000},{0.225000,0.075000,0.400000,0.400000},{0.275000,0.075000,0.200000,0.200000},{0.275000,0.075000,0.400000,0.400000},{0.325000,0.075000,0.200000,0.200000},{0.325000,0.075000,0.400000,0.400000},{0.375000,0.075000,0.200000,0.200000},{0.375000,0.075000,0.400000,0.400000},{0.425000,0.075000,0.200000,0.200000},{0.425000,0.075000,0.400000,0.400000},{0.475000,0.075000,0.200000,0.200000},{0.475000,0.075000,0.400000,0.400000},{0.525000,0.075000,0.200000,0.200000},{0.525000,0.075000,0.400000,0.400000},{0.575000,0.075000,0.200000,0.200000},{0.575000,0.075000,0.400000,0.400000},{0.625000,0.075000,0.200000,0.200000},{0.625000,0.075000,0.400000,0.400000},{0.675000,0.075000,0.200000,0.200000},{0.675000,0.075000,0.400000,0.400000},{0.725000,0.075000,0.200000,0.200000},{0.725000,0.075000,0.400000,0.400000},{0.775000,0.075000,0.200000,0.200000},{0.775000,0.075000,0.400000,0.400000},{0.825000,0.075000,0.200000,0.200000},{0.825000,0.075000,0.400000,0.400000},{0.875000,0.075000,0.200000,0.200000},{0.875000,0.075000,0.400000,0.400000},{0.925000,0.075000,0.200000,0.200000},{0.925000,0.075000,0.400000,0.400000},{0.975000,0.075000,0.200000,0.200000},{0.975000,0.075000,0.400000,0.400000},{0.025000,0.125000,0.200000,0.200000},{0.025000,0.125000,0.400000,0.400000},{0.075000,0.125000,0.200000,0.200000},{0.075000,0.125000,0.400000,0.400000},{0.125000,0.125000,0.200000,0.200000},{0.125000,0.125000,0.400000,0.400000},{0.175000,0.125000,0.200000,0.200000},{0.175000,0.125000,0.400000,0.400000},{0.225000,0.125000,0.200000,0.200000},{0.225000,0.125000,0.400000,0.400000},{0.275000,0.125000,0.200000,0.200000},{0.275000,0.125000,0.400000,0.400000},{0.325000,0.125000,0.200000,0.200000},{0.325000,0.125000,0.400000,0.400000},{0.375000,0.125000,0.200000,0.200000},{0.375000,0.125000,0.400000,0.400000},{0.425000,0.125000,0.200000,0.200000},{0.425000,0.125000,0.400000,0.400000},{0.475000,0.125000,0.200000,0.200000},{0.475000,0.125000,0.400000,0.400000},{0.525000,0.125000,0.200000,0.200000},{0.525000,0.125000,0.400000,0.400000},{0.575000,0.125000,0.200000,0.200000},{0.575000,0.125000,0.400000,0.400000},{0.625000,0.125000,0.200000,0.200000},{0.625000,0.125000,0.400000,0.400000},{0.675000,0.125000,0.200000,0.200000},{0.675000,0.125000,0.400000,0.400000},{0.725000,0.125000,0.200000,0.200000},{0.725000,0.125000,0.400000,0.400000},{0.775000,0.125000,0.200000,0.200000},{0.775000,0.125000,0.400000,0.400000},{0.825000,0.125000,0.200000,0.200000},{0.825000,0.125000,0.400000,0.400000},{0.875000,0.125000,0.200000,0.200000},{0.875000,0.125000,0.400000,0.400000},{0.925000,0.125000,0.200000,0.200000},{0.925000,0.125000,0.400000,0.400000},{0.975000,0.125000,0.200000,0.200000},{0.975000,0.125000,0.400000,0.400000},{0.025000,0.175000,0.200000,0.200000},{0.025000,0.175000,0.400000,0.400000},{0.075000,0.175000,0.200000,0.200000},{0.075000,0.175000,0.400000,0.400000},{0.125000,0.175000,0.200000,0.200000},{0.125000,0.175000,0.400000,0.400000},{0.175000,0.175000,0.200000,0.200000},{0.175000,0.175000,0.400000,0.400000},{0.225000,0.175000,0.200000,0.200000},{0.225000,0.175000,0.400000,0.400000},{0.275000,0.175000,0.200000,0.200000},{0.275000,0.175000,0.400000,0.400000},{0.325000,0.175000,0.200000,0.200000},{0.325000,0.175000,0.400000,0.400000},{0.375000,0.175000,0.200000,0.200000},{0.375000,0.175000,0.400000,0.400000},{0.425000,0.175000,0.200000,0.200000},{0.425000,0.175000,0.400000,0.400000},{0.475000,0.175000,0.200000,0.200000},{0.475000,0.175000,0.400000,0.400000},{0.525000,0.175000,0.200000,0.200000},{0.525000,0.175000,0.400000,0.400000},{0.575000,0.175000,0.200000,0.200000},{0.575000,0.175000,0.400000,0.400000},{0.625000,0.175000,0.200000,0.200000},{0.625000,0.175000,0.400000,0.400000},{0.675000,0.175000,0.200000,0.200000},{0.675000,0.175000,0.400000,0.400000},{0.725000,0.175000,0.200000,0.200000},{0.725000,0.175000,0.400000,0.400000},{0.775000,0.175000,0.200000,0.200000},{0.775000,0.175000,0.400000,0.400000},{0.825000,0.175000,0.200000,0.200000},{0.825000,0.175000,0.400000,0.400000},{0.875000,0.175000,0.200000,0.200000},{0.875000,0.175000,0.400000,0.400000},{0.925000,0.175000,0.200000,0.200000},{0.925000,0.175000,0.400000,0.400000},{0.975000,0.175000,0.200000,0.200000},{0.975000,0.175000,0.400000,0.400000},{0.025000,0.225000,0.200000,0.200000},{0.025000,0.225000,0.400000,0.400000},{0.075000,0.225000,0.200000,0.200000},{0.075000,0.225000,0.400000,0.400000},{0.125000,0.225000,0.200000,0.200000},{0.125000,0.225000,0.400000,0.400000},{0.175000,0.225000,0.200000,0.200000},{0.175000,0.225000,0.400000,0.400000},{0.225000,0.225000,0.200000,0.200000},{0.225000,0.225000,0.400000,0.400000},{0.275000,0.225000,0.200000,0.200000},{0.275000,0.225000,0.400000,0.400000},{0.325000,0.225000,0.200000,0.200000},{0.325000,0.225000,0.400000,0.400000},{0.375000,0.225000,0.200000,0.200000},{0.375000,0.225000,0.400000,0.400000},{0.425000,0.225000,0.200000,0.200000},{0.425000,0.225000,0.400000,0.400000},{0.475000,0.225000,0.200000,0.200000},{0.475000,0.225000,0.400000,0.400000},{0.525000,0.225000,0.200000,0.200000},{0.525000,0.225000,0.400000,0.400000},{0.575000,0.225000,0.200000,0.200000},{0.575000,0.225000,0.400000,0.400000},{0.625000,0.225000,0.200000,0.200000},{0.625000,0.225000,0.400000,0.400000},{0.675000,0.225000,0.200000,0.200000},{0.675000,0.225000,0.400000,0.400000},{0.725000,0.225000,0.200000,0.200000},{0.725000,0.225000,0.400000,0.400000},{0.775000,0.225000,0.200000,0.200000},{0.775000,0.225000,0.400000,0.400000},{0.825000,0.225000,0.200000,0.200000},{0.825000,0.225000,0.400000,0.400000},{0.875000,0.225000,0.200000,0.200000},{0.875000,0.225000,0.400000,0.400000},{0.925000,0.225000,0.200000,0.200000},{0.925000,0.225000,0.400000,0.400000},{0.975000,0.225000,0.200000,0.200000},{0.975000,0.225000,0.400000,0.400000},{0.025000,0.275000,0.200000,0.200000},{0.025000,0.275000,0.400000,0.400000},{0.075000,0.275000,0.200000,0.200000},{0.075000,0.275000,0.400000,0.400000},{0.125000,0.275000,0.200000,0.200000},{0.125000,0.275000,0.400000,0.400000},{0.175000,0.275000,0.200000,0.200000},{0.175000,0.275000,0.400000,0.400000},{0.225000,0.275000,0.200000,0.200000},{0.225000,0.275000,0.400000,0.400000},{0.275000,0.275000,0.200000,0.200000},{0.275000,0.275000,0.400000,0.400000},{0.325000,0.275000,0.200000,0.200000},{0.325000,0.275000,0.400000,0.400000},{0.375000,0.275000,0.200000,0.200000},{0.375000,0.275000,0.400000,0.400000},{0.425000,0.275000,0.200000,0.200000},{0.425000,0.275000,0.400000,0.400000},{0.475000,0.275000,0.200000,0.200000},{0.475000,0.275000,0.400000,0.400000},{0.525000,0.275000,0.200000,0.200000},{0.525000,0.275000,0.400000,0.400000},{0.575000,0.275000,0.200000,0.200000},{0.575000,0.275000,0.400000,0.400000},{0.625000,0.275000,0.200000,0.200000},{0.625000,0.275000,0.400000,0.400000},{0.675000,0.275000,0.200000,0.200000},{0.675000,0.275000,0.400000,0.400000},{0.725000,0.275000,0.200000,0.200000},{0.725000,0.275000,0.400000,0.400000},{0.775000,0.275000,0.200000,0.200000},{0.775000,0.275000,0.400000,0.400000},{0.825000,0.275000,0.200000,0.200000},{0.825000,0.275000,0.400000,0.400000},{0.875000,0.275000,0.200000,0.200000},{0.875000,0.275000,0.400000,0.400000},{0.925000,0.275000,0.200000,0.200000},{0.925000,0.275000,0.400000,0.400000},{0.975000,0.275000,0.200000,0.200000},{0.975000,0.275000,0.400000,0.400000},{0.025000,0.325000,0.200000,0.200000},{0.025000,0.325000,0.400000,0.400000},{0.075000,0.325000,0.200000,0.200000},{0.075000,0.325000,0.400000,0.400000},{0.125000,0.325000,0.200000,0.200000},{0.125000,0.325000,0.400000,0.400000},{0.175000,0.325000,0.200000,0.200000},{0.175000,0.325000,0.400000,0.400000},{0.225000,0.325000,0.200000,0.200000},{0.225000,0.325000,0.400000,0.400000},{0.275000,0.325000,0.200000,0.200000},{0.275000,0.325000,0.400000,0.400000},{0.325000,0.325000,0.200000,0.200000},{0.325000,0.325000,0.400000,0.400000},{0.375000,0.325000,0.200000,0.200000},{0.375000,0.325000,0.400000,0.400000},{0.425000,0.325000,0.200000,0.200000},{0.425000,0.325000,0.400000,0.400000},{0.475000,0.325000,0.200000,0.200000},{0.475000,0.325000,0.400000,0.400000},{0.525000,0.325000,0.200000,0.200000},{0.525000,0.325000,0.400000,0.400000},{0.575000,0.325000,0.200000,0.200000},{0.575000,0.325000,0.400000,0.400000},{0.625000,0.325000,0.200000,0.200000},{0.625000,0.325000,0.400000,0.400000},{0.675000,0.325000,0.200000,0.200000},{0.675000,0.325000,0.400000,0.400000},{0.725000,0.325000,0.200000,0.200000},{0.725000,0.325000,0.400000,0.400000},{0.775000,0.325000,0.200000,0.200000},{0.775000,0.325000,0.400000,0.400000},{0.825000,0.325000,0.200000,0.200000},{0.825000,0.325000,0.400000,0.400000},{0.875000,0.325000,0.200000,0.200000},{0.875000,0.325000,0.400000,0.400000},{0.925000,0.325000,0.200000,0.200000},{0.925000,0.325000,0.400000,0.400000},{0.975000,0.325000,0.200000,0.200000},{0.975000,0.325000,0.400000,0.400000},{0.025000,0.375000,0.200000,0.200000},{0.025000,0.375000,0.400000,0.400000},{0.075000,0.375000,0.200000,0.200000},{0.075000,0.375000,0.400000,0.400000},{0.125000,0.375000,0.200000,0.200000},{0.125000,0.375000,0.400000,0.400000},{0.175000,0.375000,0.200000,0.200000},{0.175000,0.375000,0.400000,0.400000},{0.225000,0.375000,0.200000,0.200000},{0.225000,0.375000,0.400000,0.400000},{0.275000,0.375000,0.200000,0.200000},{0.275000,0.375000,0.400000,0.400000},{0.325000,0.375000,0.200000,0.200000},{0.325000,0.375000,0.400000,0.400000},{0.375000,0.375000,0.200000,0.200000},{0.375000,0.375000,0.400000,0.400000},{0.425000,0.375000,0.200000,0.200000},{0.425000,0.375000,0.400000,0.400000},{0.475000,0.375000,0.200000,0.200000},{0.475000,0.375000,0.400000,0.400000},{0.525000,0.375000,0.200000,0.200000},{0.525000,0.375000,0.400000,0.400000},{0.575000,0.375000,0.200000,0.200000},{0.575000,0.375000,0.400000,0.400000},{0.625000,0.375000,0.200000,0.200000},{0.625000,0.375000,0.400000,0.400000},{0.675000,0.375000,0.200000,0.200000},{0.675000,0.375000,0.400000,0.400000},{0.725000,0.375000,0.200000,0.200000},{0.725000,0.375000,0.400000,0.400000},{0.775000,0.375000,0.200000,0.200000},{0.775000,0.375000,0.400000,0.400000},{0.825000,0.375000,0.200000,0.200000},{0.825000,0.375000,0.400000,0.400000},{0.875000,0.375000,0.200000,0.200000},{0.875000,0.375000,0.400000,0.400000},{0.925000,0.375000,0.200000,0.200000},{0.925000,0.375000,0.400000,0.400000},{0.975000,0.375000,0.200000,0.200000},{0.975000,0.375000,0.400000,0.400000},{0.025000,0.425000,0.200000,0.200000},{0.025000,0.425000,0.400000,0.400000},{0.075000,0.425000,0.200000,0.200000},{0.075000,0.425000,0.400000,0.400000},{0.125000,0.425000,0.200000,0.200000},{0.125000,0.425000,0.400000,0.400000},{0.175000,0.425000,0.200000,0.200000},{0.175000,0.425000,0.400000,0.400000},{0.225000,0.425000,0.200000,0.200000},{0.225000,0.425000,0.400000,0.400000},{0.275000,0.425000,0.200000,0.200000},{0.275000,0.425000,0.400000,0.400000},{0.325000,0.425000,0.200000,0.200000},{0.325000,0.425000,0.400000,0.400000},{0.375000,0.425000,0.200000,0.200000},{0.375000,0.425000,0.400000,0.400000},{0.425000,0.425000,0.200000,0.200000},{0.425000,0.425000,0.400000,0.400000},{0.475000,0.425000,0.200000,0.200000},{0.475000,0.425000,0.400000,0.400000},{0.525000,0.425000,0.200000,0.200000},{0.525000,0.425000,0.400000,0.400000},{0.575000,0.425000,0.200000,0.200000},{0.575000,0.425000,0.400000,0.400000},{0.625000,0.425000,0.200000,0.200000},{0.625000,0.425000,0.400000,0.400000},{0.675000,0.425000,0.200000,0.200000},{0.675000,0.425000,0.400000,0.400000},{0.725000,0.425000,0.200000,0.200000},{0.725000,0.425000,0.400000,0.400000},{0.775000,0.425000,0.200000,0.200000},{0.775000,0.425000,0.400000,0.400000},{0.825000,0.425000,0.200000,0.200000},{0.825000,0.425000,0.400000,0.400000},{0.875000,0.425000,0.200000,0.200000},{0.875000,0.425000,0.400000,0.400000},{0.925000,0.425000,0.200000,0.200000},{0.925000,0.425000,0.400000,0.400000},{0.975000,0.425000,0.200000,0.200000},{0.975000,0.425000,0.400000,0.400000},{0.025000,0.475000,0.200000,0.200000},{0.025000,0.475000,0.400000,0.400000},{0.075000,0.475000,0.200000,0.200000},{0.075000,0.475000,0.400000,0.400000},{0.125000,0.475000,0.200000,0.200000},{0.125000,0.475000,0.400000,0.400000},{0.175000,0.475000,0.200000,0.200000},{0.175000,0.475000,0.400000,0.400000},{0.225000,0.475000,0.200000,0.200000},{0.225000,0.475000,0.400000,0.400000},{0.275000,0.475000,0.200000,0.200000},{0.275000,0.475000,0.400000,0.400000},{0.325000,0.475000,0.200000,0.200000},{0.325000,0.475000,0.400000,0.400000},{0.375000,0.475000,0.200000,0.200000},{0.375000,0.475000,0.400000,0.400000},{0.425000,0.475000,0.200000,0.200000},{0.425000,0.475000,0.400000,0.400000},{0.475000,0.475000,0.200000,0.200000},{0.475000,0.475000,0.400000,0.400000},{0.525000,0.475000,0.200000,0.200000},{0.525000,0.475000,0.400000,0.400000},{0.575000,0.475000,0.200000,0.200000},{0.575000,0.475000,0.400000,0.400000},{0.625000,0.475000,0.200000,0.200000},{0.625000,0.475000,0.400000,0.400000},{0.675000,0.475000,0.200000,0.200000},{0.675000,0.475000,0.400000,0.400000},{0.725000,0.475000,0.200000,0.200000},{0.725000,0.475000,0.400000,0.400000},{0.775000,0.475000,0.200000,0.200000},{0.775000,0.475000,0.400000,0.400000},{0.825000,0.475000,0.200000,0.200000},{0.825000,0.475000,0.400000,0.400000},{0.875000,0.475000,0.200000,0.200000},{0.875000,0.475000,0.400000,0.400000},{0.925000,0.475000,0.200000,0.200000},{0.925000,0.475000,0.400000,0.400000},{0.975000,0.475000,0.200000,0.200000},{0.975000,0.475000,0.400000,0.400000},{0.025000,0.525000,0.200000,0.200000},{0.025000,0.525000,0.400000,0.400000},{0.075000,0.525000,0.200000,0.200000},{0.075000,0.525000,0.400000,0.400000},{0.125000,0.525000,0.200000,0.200000},{0.125000,0.525000,0.400000,0.400000},{0.175000,0.525000,0.200000,0.200000},{0.175000,0.525000,0.400000,0.400000},{0.225000,0.525000,0.200000,0.200000},{0.225000,0.525000,0.400000,0.400000},{0.275000,0.525000,0.200000,0.200000},{0.275000,0.525000,0.400000,0.400000},{0.325000,0.525000,0.200000,0.200000},{0.325000,0.525000,0.400000,0.400000},{0.375000,0.525000,0.200000,0.200000},{0.375000,0.525000,0.400000,0.400000},{0.425000,0.525000,0.200000,0.200000},{0.425000,0.525000,0.400000,0.400000},{0.475000,0.525000,0.200000,0.200000},{0.475000,0.525000,0.400000,0.400000},{0.525000,0.525000,0.200000,0.200000},{0.525000,0.525000,0.400000,0.400000},{0.575000,0.525000,0.200000,0.200000},{0.575000,0.525000,0.400000,0.400000},{0.625000,0.525000,0.200000,0.200000},{0.625000,0.525000,0.400000,0.400000},{0.675000,0.525000,0.200000,0.200000},{0.675000,0.525000,0.400000,0.400000},{0.725000,0.525000,0.200000,0.200000},{0.725000,0.525000,0.400000,0.400000},{0.775000,0.525000,0.200000,0.200000},{0.775000,0.525000,0.400000,0.400000},{0.825000,0.525000,0.200000,0.200000},{0.825000,0.525000,0.400000,0.400000},{0.875000,0.525000,0.200000,0.200000},{0.875000,0.525000,0.400000,0.400000},{0.925000,0.525000,0.200000,0.200000},{0.925000,0.525000,0.400000,0.400000},{0.975000,0.525000,0.200000,0.200000},{0.975000,0.525000,0.400000,0.400000},{0.025000,0.575000,0.200000,0.200000},{0.025000,0.575000,0.400000,0.400000},{0.075000,0.575000,0.200000,0.200000},{0.075000,0.575000,0.400000,0.400000},{0.125000,0.575000,0.200000,0.200000},{0.125000,0.575000,0.400000,0.400000},{0.175000,0.575000,0.200000,0.200000},{0.175000,0.575000,0.400000,0.400000},{0.225000,0.575000,0.200000,0.200000},{0.225000,0.575000,0.400000,0.400000},{0.275000,0.575000,0.200000,0.200000},{0.275000,0.575000,0.400000,0.400000},{0.325000,0.575000,0.200000,0.200000},{0.325000,0.575000,0.400000,0.400000},{0.375000,0.575000,0.200000,0.200000},{0.375000,0.575000,0.400000,0.400000},{0.425000,0.575000,0.200000,0.200000},{0.425000,0.575000,0.400000,0.400000},{0.475000,0.575000,0.200000,0.200000},{0.475000,0.575000,0.400000,0.400000},{0.525000,0.575000,0.200000,0.200000},{0.525000,0.575000,0.400000,0.400000},{0.575000,0.575000,0.200000,0.200000},{0.575000,0.575000,0.400000,0.400000},{0.625000,0.575000,0.200000,0.200000},{0.625000,0.575000,0.400000,0.400000},{0.675000,0.575000,0.200000,0.200000},{0.675000,0.575000,0.400000,0.400000},{0.725000,0.575000,0.200000,0.200000},{0.725000,0.575000,0.400000,0.400000},{0.775000,0.575000,0.200000,0.200000},{0.775000,0.575000,0.400000,0.400000},{0.825000,0.575000,0.200000,0.200000},{0.825000,0.575000,0.400000,0.400000},{0.875000,0.575000,0.200000,0.200000},{0.875000,0.575000,0.400000,0.400000},{0.925000,0.575000,0.200000,0.200000},{0.925000,0.575000,0.400000,0.400000},{0.975000,0.575000,0.200000,0.200000},{0.975000,0.575000,0.400000,0.400000},{0.025000,0.625000,0.200000,0.200000},{0.025000,0.625000,0.400000,0.400000},{0.075000,0.625000,0.200000,0.200000},{0.075000,0.625000,0.400000,0.400000},{0.125000,0.625000,0.200000,0.200000},{0.125000,0.625000,0.400000,0.400000},{0.175000,0.625000,0.200000,0.200000},{0.175000,0.625000,0.400000,0.400000},{0.225000,0.625000,0.200000,0.200000},{0.225000,0.625000,0.400000,0.400000},{0.275000,0.625000,0.200000,0.200000},{0.275000,0.625000,0.400000,0.400000},{0.325000,0.625000,0.200000,0.200000},{0.325000,0.625000,0.400000,0.400000},{0.375000,0.625000,0.200000,0.200000},{0.375000,0.625000,0.400000,0.400000},{0.425000,0.625000,0.200000,0.200000},{0.425000,0.625000,0.400000,0.400000},{0.475000,0.625000,0.200000,0.200000},{0.475000,0.625000,0.400000,0.400000},{0.525000,0.625000,0.200000,0.200000},{0.525000,0.625000,0.400000,0.400000},{0.575000,0.625000,0.200000,0.200000},{0.575000,0.625000,0.400000,0.400000},{0.625000,0.625000,0.200000,0.200000},{0.625000,0.625000,0.400000,0.400000},{0.675000,0.625000,0.200000,0.200000},{0.675000,0.625000,0.400000,0.400000},{0.725000,0.625000,0.200000,0.200000},{0.725000,0.625000,0.400000,0.400000},{0.775000,0.625000,0.200000,0.200000},{0.775000,0.625000,0.400000,0.400000},{0.825000,0.625000,0.200000,0.200000},{0.825000,0.625000,0.400000,0.400000},{0.875000,0.625000,0.200000,0.200000},{0.875000,0.625000,0.400000,0.400000},{0.925000,0.625000,0.200000,0.200000},{0.925000,0.625000,0.400000,0.400000},{0.975000,0.625000,0.200000,0.200000},{0.975000,0.625000,0.400000,0.400000},{0.025000,0.675000,0.200000,0.200000},{0.025000,0.675000,0.400000,0.400000},{0.075000,0.675000,0.200000,0.200000},{0.075000,0.675000,0.400000,0.400000},{0.125000,0.675000,0.200000,0.200000},{0.125000,0.675000,0.400000,0.400000},{0.175000,0.675000,0.200000,0.200000},{0.175000,0.675000,0.400000,0.400000},{0.225000,0.675000,0.200000,0.200000},{0.225000,0.675000,0.400000,0.400000},{0.275000,0.675000,0.200000,0.200000},{0.275000,0.675000,0.400000,0.400000},{0.325000,0.675000,0.200000,0.200000},{0.325000,0.675000,0.400000,0.400000},{0.375000,0.675000,0.200000,0.200000},{0.375000,0.675000,0.400000,0.400000},{0.425000,0.675000,0.200000,0.200000},{0.425000,0.675000,0.400000,0.400000},{0.475000,0.675000,0.200000,0.200000},{0.475000,0.675000,0.400000,0.400000},{0.525000,0.675000,0.200000,0.200000},{0.525000,0.675000,0.400000,0.400000},{0.575000,0.675000,0.200000,0.200000},{0.575000,0.675000,0.400000,0.400000},{0.625000,0.675000,0.200000,0.200000},{0.625000,0.675000,0.400000,0.400000},{0.675000,0.675000,0.200000,0.200000},{0.675000,0.675000,0.400000,0.400000},{0.725000,0.675000,0.200000,0.200000},{0.725000,0.675000,0.400000,0.400000},{0.775000,0.675000,0.200000,0.200000},{0.775000,0.675000,0.400000,0.400000},{0.825000,0.675000,0.200000,0.200000},{0.825000,0.675000,0.400000,0.400000},{0.875000,0.675000,0.200000,0.200000},{0.875000,0.675000,0.400000,0.400000},{0.925000,0.675000,0.200000,0.200000},{0.925000,0.675000,0.400000,0.400000},{0.975000,0.675000,0.200000,0.200000},{0.975000,0.675000,0.400000,0.400000},{0.025000,0.725000,0.200000,0.200000},{0.025000,0.725000,0.400000,0.400000},{0.075000,0.725000,0.200000,0.200000},{0.075000,0.725000,0.400000,0.400000},{0.125000,0.725000,0.200000,0.200000},{0.125000,0.725000,0.400000,0.400000},{0.175000,0.725000,0.200000,0.200000},{0.175000,0.725000,0.400000,0.400000},{0.225000,0.725000,0.200000,0.200000},{0.225000,0.725000,0.400000,0.400000},{0.275000,0.725000,0.200000,0.200000},{0.275000,0.725000,0.400000,0.400000},{0.325000,0.725000,0.200000,0.200000},{0.325000,0.725000,0.400000,0.400000},{0.375000,0.725000,0.200000,0.200000},{0.375000,0.725000,0.400000,0.400000},{0.425000,0.725000,0.200000,0.200000},{0.425000,0.725000,0.400000,0.400000},{0.475000,0.725000,0.200000,0.200000},{0.475000,0.725000,0.400000,0.400000},{0.525000,0.725000,0.200000,0.200000},{0.525000,0.725000,0.400000,0.400000},{0.575000,0.725000,0.200000,0.200000},{0.575000,0.725000,0.400000,0.400000},{0.625000,0.725000,0.200000,0.200000},{0.625000,0.725000,0.400000,0.400000},{0.675000,0.725000,0.200000,0.200000},{0.675000,0.725000,0.400000,0.400000},{0.725000,0.725000,0.200000,0.200000},{0.725000,0.725000,0.400000,0.400000},{0.775000,0.725000,0.200000,0.200000},{0.775000,0.725000,0.400000,0.400000},{0.825000,0.725000,0.200000,0.200000},{0.825000,0.725000,0.400000,0.400000},{0.875000,0.725000,0.200000,0.200000},{0.875000,0.725000,0.400000,0.400000},{0.925000,0.725000,0.200000,0.200000},{0.925000,0.725000,0.400000,0.400000},{0.975000,0.725000,0.200000,0.200000},{0.975000,0.725000,0.400000,0.400000},{0.025000,0.775000,0.200000,0.200000},{0.025000,0.775000,0.400000,0.400000},{0.075000,0.775000,0.200000,0.200000},{0.075000,0.775000,0.400000,0.400000},{0.125000,0.775000,0.200000,0.200000},{0.125000,0.775000,0.400000,0.400000},{0.175000,0.775000,0.200000,0.200000},{0.175000,0.775000,0.400000,0.400000},{0.225000,0.775000,0.200000,0.200000},{0.225000,0.775000,0.400000,0.400000},{0.275000,0.775000,0.200000,0.200000},{0.275000,0.775000,0.400000,0.400000},{0.325000,0.775000,0.200000,0.200000},{0.325000,0.775000,0.400000,0.400000},{0.375000,0.775000,0.200000,0.200000},{0.375000,0.775000,0.400000,0.400000},{0.425000,0.775000,0.200000,0.200000},{0.425000,0.775000,0.400000,0.400000},{0.475000,0.775000,0.200000,0.200000},{0.475000,0.775000,0.400000,0.400000},{0.525000,0.775000,0.200000,0.200000},{0.525000,0.775000,0.400000,0.400000},{0.575000,0.775000,0.200000,0.200000},{0.575000,0.775000,0.400000,0.400000},{0.625000,0.775000,0.200000,0.200000},{0.625000,0.775000,0.400000,0.400000},{0.675000,0.775000,0.200000,0.200000},{0.675000,0.775000,0.400000,0.400000},{0.725000,0.775000,0.200000,0.200000},{0.725000,0.775000,0.400000,0.400000},{0.775000,0.775000,0.200000,0.200000},{0.775000,0.775000,0.400000,0.400000},{0.825000,0.775000,0.200000,0.200000},{0.825000,0.775000,0.400000,0.400000},{0.875000,0.775000,0.200000,0.200000},{0.875000,0.775000,0.400000,0.400000},{0.925000,0.775000,0.200000,0.200000},{0.925000,0.775000,0.400000,0.400000},{0.975000,0.775000,0.200000,0.200000},{0.975000,0.775000,0.400000,0.400000},{0.025000,0.825000,0.200000,0.200000},{0.025000,0.825000,0.400000,0.400000},{0.075000,0.825000,0.200000,0.200000},{0.075000,0.825000,0.400000,0.400000},{0.125000,0.825000,0.200000,0.200000},{0.125000,0.825000,0.400000,0.400000},{0.175000,0.825000,0.200000,0.200000},{0.175000,0.825000,0.400000,0.400000},{0.225000,0.825000,0.200000,0.200000},{0.225000,0.825000,0.400000,0.400000},{0.275000,0.825000,0.200000,0.200000},{0.275000,0.825000,0.400000,0.400000},{0.325000,0.825000,0.200000,0.200000},{0.325000,0.825000,0.400000,0.400000},{0.375000,0.825000,0.200000,0.200000},{0.375000,0.825000,0.400000,0.400000},{0.425000,0.825000,0.200000,0.200000},{0.425000,0.825000,0.400000,0.400000},{0.475000,0.825000,0.200000,0.200000},{0.475000,0.825000,0.400000,0.400000},{0.525000,0.825000,0.200000,0.200000},{0.525000,0.825000,0.400000,0.400000},{0.575000,0.825000,0.200000,0.200000},{0.575000,0.825000,0.400000,0.400000},{0.625000,0.825000,0.200000,0.200000},{0.625000,0.825000,0.400000,0.400000},{0.675000,0.825000,0.200000,0.200000},{0.675000,0.825000,0.400000,0.400000},{0.725000,0.825000,0.200000,0.200000},{0.725000,0.825000,0.400000,0.400000},{0.775000,0.825000,0.200000,0.200000},{0.775000,0.825000,0.400000,0.400000},{0.825000,0.825000,0.200000,0.200000},{0.825000,0.825000,0.400000,0.400000},{0.875000,0.825000,0.200000,0.200000},{0.875000,0.825000,0.400000,0.400000},{0.925000,0.825000,0.200000,0.200000},{0.925000,0.825000,0.400000,0.400000},{0.975000,0.825000,0.200000,0.200000},{0.975000,0.825000,0.400000,0.400000},{0.025000,0.875000,0.200000,0.200000},{0.025000,0.875000,0.400000,0.400000},{0.075000,0.875000,0.200000,0.200000},{0.075000,0.875000,0.400000,0.400000},{0.125000,0.875000,0.200000,0.200000},{0.125000,0.875000,0.400000,0.400000},{0.175000,0.875000,0.200000,0.200000},{0.175000,0.875000,0.400000,0.400000},{0.225000,0.875000,0.200000,0.200000},{0.225000,0.875000,0.400000,0.400000},{0.275000,0.875000,0.200000,0.200000},{0.275000,0.875000,0.400000,0.400000},{0.325000,0.875000,0.200000,0.200000},{0.325000,0.875000,0.400000,0.400000},{0.375000,0.875000,0.200000,0.200000},{0.375000,0.875000,0.400000,0.400000},{0.425000,0.875000,0.200000,0.200000},{0.425000,0.875000,0.400000,0.400000},{0.475000,0.875000,0.200000,0.200000},{0.475000,0.875000,0.400000,0.400000},{0.525000,0.875000,0.200000,0.200000},{0.525000,0.875000,0.400000,0.400000},{0.575000,0.875000,0.200000,0.200000},{0.575000,0.875000,0.400000,0.400000},{0.625000,0.875000,0.200000,0.200000},{0.625000,0.875000,0.400000,0.400000},{0.675000,0.875000,0.200000,0.200000},{0.675000,0.875000,0.400000,0.400000},{0.725000,0.875000,0.200000,0.200000},{0.725000,0.875000,0.400000,0.400000},{0.775000,0.875000,0.200000,0.200000},{0.775000,0.875000,0.400000,0.400000},{0.825000,0.875000,0.200000,0.200000},{0.825000,0.875000,0.400000,0.400000},{0.875000,0.875000,0.200000,0.200000},{0.875000,0.875000,0.400000,0.400000},{0.925000,0.875000,0.200000,0.200000},{0.925000,0.875000,0.400000,0.400000},{0.975000,0.875000,0.200000,0.200000},{0.975000,0.875000,0.400000,0.400000},{0.025000,0.925000,0.200000,0.200000},{0.025000,0.925000,0.400000,0.400000},{0.075000,0.925000,0.200000,0.200000},{0.075000,0.925000,0.400000,0.400000},{0.125000,0.925000,0.200000,0.200000},{0.125000,0.925000,0.400000,0.400000},{0.175000,0.925000,0.200000,0.200000},{0.175000,0.925000,0.400000,0.400000},{0.225000,0.925000,0.200000,0.200000},{0.225000,0.925000,0.400000,0.400000},{0.275000,0.925000,0.200000,0.200000},{0.275000,0.925000,0.400000,0.400000},{0.325000,0.925000,0.200000,0.200000},{0.325000,0.925000,0.400000,0.400000},{0.375000,0.925000,0.200000,0.200000},{0.375000,0.925000,0.400000,0.400000},{0.425000,0.925000,0.200000,0.200000},{0.425000,0.925000,0.400000,0.400000},{0.475000,0.925000,0.200000,0.200000},{0.475000,0.925000,0.400000,0.400000},{0.525000,0.925000,0.200000,0.200000},{0.525000,0.925000,0.400000,0.400000},{0.575000,0.925000,0.200000,0.200000},{0.575000,0.925000,0.400000,0.400000},{0.625000,0.925000,0.200000,0.200000},{0.625000,0.925000,0.400000,0.400000},{0.675000,0.925000,0.200000,0.200000},{0.675000,0.925000,0.400000,0.400000},{0.725000,0.925000,0.200000,0.200000},{0.725000,0.925000,0.400000,0.400000},{0.775000,0.925000,0.200000,0.200000},{0.775000,0.925000,0.400000,0.400000},{0.825000,0.925000,0.200000,0.200000},{0.825000,0.925000,0.400000,0.400000},{0.875000,0.925000,0.200000,0.200000},{0.875000,0.925000,0.400000,0.400000},{0.925000,0.925000,0.200000,0.200000},{0.925000,0.925000,0.400000,0.400000},{0.975000,0.925000,0.200000,0.200000},{0.975000,0.925000,0.400000,0.400000},{0.025000,0.975000,0.200000,0.200000},{0.025000,0.975000,0.400000,0.400000},{0.075000,0.975000,0.200000,0.200000},{0.075000,0.975000,0.400000,0.400000},{0.125000,0.975000,0.200000,0.200000},{0.125000,0.975000,0.400000,0.400000},{0.175000,0.975000,0.200000,0.200000},{0.175000,0.975000,0.400000,0.400000},{0.225000,0.975000,0.200000,0.200000},{0.225000,0.975000,0.400000,0.400000},{0.275000,0.975000,0.200000,0.200000},{0.275000,0.975000,0.400000,0.400000},{0.325000,0.975000,0.200000,0.200000},{0.325000,0.975000,0.400000,0.400000},{0.375000,0.975000,0.200000,0.200000},{0.375000,0.975000,0.400000,0.400000},{0.425000,0.975000,0.200000,0.200000},{0.425000,0.975000,0.400000,0.400000},{0.475000,0.975000,0.200000,0.200000},{0.475000,0.975000,0.400000,0.400000},{0.525000,0.975000,0.200000,0.200000},{0.525000,0.975000,0.400000,0.400000},{0.575000,0.975000,0.200000,0.200000},{0.575000,0.975000,0.400000,0.400000},{0.625000,0.975000,0.200000,0.200000},{0.625000,0.975000,0.400000,0.400000},{0.675000,0.975000,0.200000,0.200000},{0.675000,0.975000,0.400000,0.400000},{0.725000,0.975000,0.200000,0.200000},{0.725000,0.975000,0.400000,0.400000},{0.775000,0.975000,0.200000,0.200000},{0.775000,0.975000,0.400000,0.400000},{0.825000,0.975000,0.200000,0.200000},{0.825000,0.975000,0.400000,0.400000},{0.875000,0.975000,0.200000,0.200000},{0.875000,0.975000,0.400000,0.400000},{0.925000,0.975000,0.200000,0.200000},{0.925000,0.975000,0.400000,0.400000},{0.975000,0.975000,0.200000,0.200000},{0.975000,0.975000,0.400000,0.400000},{0.050000,0.050000,0.800000,0.800000},{0.050000,0.050000,1.600000,1.600000},{0.150000,0.050000,0.800000,0.800000},{0.150000,0.050000,1.600000,1.600000},{0.250000,0.050000,0.800000,0.800000},{0.250000,0.050000,1.600000,1.600000},{0.350000,0.050000,0.800000,0.800000},{0.350000,0.050000,1.600000,1.600000},{0.450000,0.050000,0.800000,0.800000},{0.450000,0.050000,1.600000,1.600000},{0.550000,0.050000,0.800000,0.800000},{0.550000,0.050000,1.600000,1.600000},{0.650000,0.050000,0.800000,0.800000},{0.650000,0.050000,1.600000,1.600000},{0.750000,0.050000,0.800000,0.800000},{0.750000,0.050000,1.600000,1.600000},{0.850000,0.050000,0.800000,0.800000},{0.850000,0.050000,1.600000,1.600000},{0.950000,0.050000,0.800000,0.800000},{0.950000,0.050000,1.600000,1.600000},{0.050000,0.150000,0.800000,0.800000},{0.050000,0.150000,1.600000,1.600000},{0.150000,0.150000,0.800000,0.800000},{0.150000,0.150000,1.600000,1.600000},{0.250000,0.150000,0.800000,0.800000},{0.250000,0.150000,1.600000,1.600000},{0.350000,0.150000,0.800000,0.800000},{0.350000,0.150000,1.600000,1.600000},{0.450000,0.150000,0.800000,0.800000},{0.450000,0.150000,1.600000,1.600000},{0.550000,0.150000,0.800000,0.800000},{0.550000,0.150000,1.600000,1.600000},{0.650000,0.150000,0.800000,0.800000},{0.650000,0.150000,1.600000,1.600000},{0.750000,0.150000,0.800000,0.800000},{0.750000,0.150000,1.600000,1.600000},{0.850000,0.150000,0.800000,0.800000},{0.850000,0.150000,1.600000,1.600000},{0.950000,0.150000,0.800000,0.800000},{0.950000,0.150000,1.600000,1.600000},{0.050000,0.250000,0.800000,0.800000},{0.050000,0.250000,1.600000,1.600000},{0.150000,0.250000,0.800000,0.800000},{0.150000,0.250000,1.600000,1.600000},{0.250000,0.250000,0.800000,0.800000},{0.250000,0.250000,1.600000,1.600000},{0.350000,0.250000,0.800000,0.800000},{0.350000,0.250000,1.600000,1.600000},{0.450000,0.250000,0.800000,0.800000},{0.450000,0.250000,1.600000,1.600000},{0.550000,0.250000,0.800000,0.800000},{0.550000,0.250000,1.600000,1.600000},{0.650000,0.250000,0.800000,0.800000},{0.650000,0.250000,1.600000,1.600000},{0.750000,0.250000,0.800000,0.800000},{0.750000,0.250000,1.600000,1.600000},{0.850000,0.250000,0.800000,0.800000},{0.850000,0.250000,1.600000,1.600000},{0.950000,0.250000,0.800000,0.800000},{0.950000,0.250000,1.600000,1.600000},{0.050000,0.350000,0.800000,0.800000},{0.050000,0.350000,1.600000,1.600000},{0.150000,0.350000,0.800000,0.800000},{0.150000,0.350000,1.600000,1.600000},{0.250000,0.350000,0.800000,0.800000},{0.250000,0.350000,1.600000,1.600000},{0.350000,0.350000,0.800000,0.800000},{0.350000,0.350000,1.600000,1.600000},{0.450000,0.350000,0.800000,0.800000},{0.450000,0.350000,1.600000,1.600000},{0.550000,0.350000,0.800000,0.800000},{0.550000,0.350000,1.600000,1.600000},{0.650000,0.350000,0.800000,0.800000},{0.650000,0.350000,1.600000,1.600000},{0.750000,0.350000,0.800000,0.800000},{0.750000,0.350000,1.600000,1.600000},{0.850000,0.350000,0.800000,0.800000},{0.850000,0.350000,1.600000,1.600000},{0.950000,0.350000,0.800000,0.800000},{0.950000,0.350000,1.600000,1.600000},{0.050000,0.450000,0.800000,0.800000},{0.050000,0.450000,1.600000,1.600000},{0.150000,0.450000,0.800000,0.800000},{0.150000,0.450000,1.600000,1.600000},{0.250000,0.450000,0.800000,0.800000},{0.250000,0.450000,1.600000,1.600000},{0.350000,0.450000,0.800000,0.800000},{0.350000,0.450000,1.600000,1.600000},{0.450000,0.450000,0.800000,0.800000},{0.450000,0.450000,1.600000,1.600000},{0.550000,0.450000,0.800000,0.800000},{0.550000,0.450000,1.600000,1.600000},{0.650000,0.450000,0.800000,0.800000},{0.650000,0.450000,1.600000,1.600000},{0.750000,0.450000,0.800000,0.800000},{0.750000,0.450000,1.600000,1.600000},{0.850000,0.450000,0.800000,0.800000},{0.850000,0.450000,1.600000,1.600000},{0.950000,0.450000,0.800000,0.800000},{0.950000,0.450000,1.600000,1.600000},{0.050000,0.550000,0.800000,0.800000},{0.050000,0.550000,1.600000,1.600000},{0.150000,0.550000,0.800000,0.800000},{0.150000,0.550000,1.600000,1.600000},{0.250000,0.550000,0.800000,0.800000},{0.250000,0.550000,1.600000,1.600000},{0.350000,0.550000,0.800000,0.800000},{0.350000,0.550000,1.600000,1.600000},{0.450000,0.550000,0.800000,0.800000},{0.450000,0.550000,1.600000,1.600000},{0.550000,0.550000,0.800000,0.800000},{0.550000,0.550000,1.600000,1.600000},{0.650000,0.550000,0.800000,0.800000},{0.650000,0.550000,1.600000,1.600000},{0.750000,0.550000,0.800000,0.800000},{0.750000,0.550000,1.600000,1.600000},{0.850000,0.550000,0.800000,0.800000},{0.850000,0.550000,1.600000,1.600000},{0.950000,0.550000,0.800000,0.800000},{0.950000,0.550000,1.600000,1.600000},{0.050000,0.650000,0.800000,0.800000},{0.050000,0.650000,1.600000,1.600000},{0.150000,0.650000,0.800000,0.800000},{0.150000,0.650000,1.600000,1.600000},{0.250000,0.650000,0.800000,0.800000},{0.250000,0.650000,1.600000,1.600000},{0.350000,0.650000,0.800000,0.800000},{0.350000,0.650000,1.600000,1.600000},{0.450000,0.650000,0.800000,0.800000},{0.450000,0.650000,1.600000,1.600000},{0.550000,0.650000,0.800000,0.800000},{0.550000,0.650000,1.600000,1.600000},{0.650000,0.650000,0.800000,0.800000},{0.650000,0.650000,1.600000,1.600000},{0.750000,0.650000,0.800000,0.800000},{0.750000,0.650000,1.600000,1.600000},{0.850000,0.650000,0.800000,0.800000},{0.850000,0.650000,1.600000,1.600000},{0.950000,0.650000,0.800000,0.800000},{0.950000,0.650000,1.600000,1.600000},{0.050000,0.750000,0.800000,0.800000},{0.050000,0.750000,1.600000,1.600000},{0.150000,0.750000,0.800000,0.800000},{0.150000,0.750000,1.600000,1.600000},{0.250000,0.750000,0.800000,0.800000},{0.250000,0.750000,1.600000,1.600000},{0.350000,0.750000,0.800000,0.800000},{0.350000,0.750000,1.600000,1.600000},{0.450000,0.750000,0.800000,0.800000},{0.450000,0.750000,1.600000,1.600000},{0.550000,0.750000,0.800000,0.800000},{0.550000,0.750000,1.600000,1.600000},{0.650000,0.750000,0.800000,0.800000},{0.650000,0.750000,1.600000,1.600000},{0.750000,0.750000,0.800000,0.800000},{0.750000,0.750000,1.600000,1.600000},{0.850000,0.750000,0.800000,0.800000},{0.850000,0.750000,1.600000,1.600000},{0.950000,0.750000,0.800000,0.800000},{0.950000,0.750000,1.600000,1.600000},{0.050000,0.850000,0.800000,0.800000},{0.050000,0.850000,1.600000,1.600000},{0.150000,0.850000,0.800000,0.800000},{0.150000,0.850000,1.600000,1.600000},{0.250000,0.850000,0.800000,0.800000},{0.250000,0.850000,1.600000,1.600000},{0.350000,0.850000,0.800000,0.800000},{0.350000,0.850000,1.600000,1.600000},{0.450000,0.850000,0.800000,0.800000},{0.450000,0.850000,1.600000,1.600000},{0.550000,0.850000,0.800000,0.800000},{0.550000,0.850000,1.600000,1.600000},{0.650000,0.850000,0.800000,0.800000},{0.650000,0.850000,1.600000,1.600000},{0.750000,0.850000,0.800000,0.800000},{0.750000,0.850000,1.600000,1.600000},{0.850000,0.850000,0.800000,0.800000},{0.850000,0.850000,1.600000,1.600000},{0.950000,0.850000,0.800000,0.800000},{0.950000,0.850000,1.600000,1.600000},{0.050000,0.950000,0.800000,0.800000},{0.050000,0.950000,1.600000,1.600000},{0.150000,0.950000,0.800000,0.800000},{0.150000,0.950000,1.600000,1.600000},{0.250000,0.950000,0.800000,0.800000},{0.250000,0.950000,1.600000,1.600000},{0.350000,0.950000,0.800000,0.800000},{0.350000,0.950000,1.600000,1.600000},{0.450000,0.950000,0.800000,0.800000},{0.450000,0.950000,1.600000,1.600000},{0.550000,0.950000,0.800000,0.800000},{0.550000,0.950000,1.600000,1.600000},{0.650000,0.950000,0.800000,0.800000},{0.650000,0.950000,1.600000,1.600000},{0.750000,0.950000,0.800000,0.800000},{0.750000,0.950000,1.600000,1.600000},{0.850000,0.950000,0.800000,0.800000},{0.850000,0.950000,1.600000,1.600000},{0.950000,0.950000,0.800000,0.800000},{0.950000,0.950000,1.600000,1.600000}}; \ No newline at end of file diff --git a/src/reference/ai_poc/face_alignment/anchors_640.cc b/src/reference/ai_poc/face_alignment/anchors_640.cc new file mode 100644 index 000000000..9a8d3fb0f --- /dev/null +++ b/src/reference/ai_poc/face_alignment/anchors_640.cc @@ -0,0 +1,25 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +float kAnchors640[16800][4] = {{0.006250,0.006250,0.025000,0.025000},{0.006250,0.006250,0.050000,0.050000},{0.018750,0.006250,0.025000,0.025000},{0.018750,0.006250,0.050000,0.050000},{0.031250,0.006250,0.025000,0.025000},{0.031250,0.006250,0.050000,0.050000},{0.043750,0.006250,0.025000,0.025000},{0.043750,0.006250,0.050000,0.050000},{0.056250,0.006250,0.025000,0.025000},{0.056250,0.006250,0.050000,0.050000},{0.068750,0.006250,0.025000,0.025000},{0.068750,0.006250,0.050000,0.050000},{0.081250,0.006250,0.025000,0.025000},{0.081250,0.006250,0.050000,0.050000},{0.093750,0.006250,0.025000,0.025000},{0.093750,0.006250,0.050000,0.050000},{0.106250,0.006250,0.025000,0.025000},{0.106250,0.006250,0.050000,0.050000},{0.118750,0.006250,0.025000,0.025000},{0.118750,0.006250,0.050000,0.050000},{0.131250,0.006250,0.025000,0.025000},{0.131250,0.006250,0.050000,0.050000},{0.143750,0.006250,0.025000,0.025000},{0.143750,0.006250,0.050000,0.050000},{0.156250,0.006250,0.025000,0.025000},{0.156250,0.006250,0.050000,0.050000},{0.168750,0.006250,0.025000,0.025000},{0.168750,0.006250,0.050000,0.050000},{0.181250,0.006250,0.025000,0.025000},{0.181250,0.006250,0.050000,0.050000},{0.193750,0.006250,0.025000,0.025000},{0.193750,0.006250,0.050000,0.050000},{0.206250,0.006250,0.025000,0.025000},{0.206250,0.006250,0.050000,0.050000},{0.218750,0.006250,0.025000,0.025000},{0.218750,0.006250,0.050000,0.050000},{0.231250,0.006250,0.025000,0.025000},{0.231250,0.006250,0.050000,0.050000},{0.243750,0.006250,0.025000,0.025000},{0.243750,0.006250,0.050000,0.050000},{0.256250,0.006250,0.025000,0.025000},{0.256250,0.006250,0.050000,0.050000},{0.268750,0.006250,0.025000,0.025000},{0.268750,0.006250,0.050000,0.050000},{0.281250,0.006250,0.025000,0.025000},{0.281250,0.006250,0.050000,0.050000},{0.293750,0.006250,0.025000,0.025000},{0.293750,0.006250,0.050000,0.050000},{0.306250,0.006250,0.025000,0.025000},{0.306250,0.006250,0.050000,0.050000},{0.318750,0.006250,0.025000,0.025000},{0.318750,0.006250,0.050000,0.050000},{0.331250,0.006250,0.025000,0.025000},{0.331250,0.006250,0.050000,0.050000},{0.343750,0.006250,0.025000,0.025000},{0.343750,0.006250,0.050000,0.050000},{0.356250,0.006250,0.025000,0.025000},{0.356250,0.006250,0.050000,0.050000},{0.368750,0.006250,0.025000,0.025000},{0.368750,0.006250,0.050000,0.050000},{0.381250,0.006250,0.025000,0.025000},{0.381250,0.006250,0.050000,0.050000},{0.393750,0.006250,0.025000,0.025000},{0.393750,0.006250,0.050000,0.050000},{0.406250,0.006250,0.025000,0.025000},{0.406250,0.006250,0.050000,0.050000},{0.418750,0.006250,0.025000,0.025000},{0.418750,0.006250,0.050000,0.050000},{0.431250,0.006250,0.025000,0.025000},{0.431250,0.006250,0.050000,0.050000},{0.443750,0.006250,0.025000,0.025000},{0.443750,0.006250,0.050000,0.050000},{0.456250,0.006250,0.025000,0.025000},{0.456250,0.006250,0.050000,0.050000},{0.468750,0.006250,0.025000,0.025000},{0.468750,0.006250,0.050000,0.050000},{0.481250,0.006250,0.025000,0.025000},{0.481250,0.006250,0.050000,0.050000},{0.493750,0.006250,0.025000,0.025000},{0.493750,0.006250,0.050000,0.050000},{0.506250,0.006250,0.025000,0.025000},{0.506250,0.006250,0.050000,0.050000},{0.518750,0.006250,0.025000,0.025000},{0.518750,0.006250,0.050000,0.050000},{0.531250,0.006250,0.025000,0.025000},{0.531250,0.006250,0.050000,0.050000},{0.543750,0.006250,0.025000,0.025000},{0.543750,0.006250,0.050000,0.050000},{0.556250,0.006250,0.025000,0.025000},{0.556250,0.006250,0.050000,0.050000},{0.568750,0.006250,0.025000,0.025000},{0.568750,0.006250,0.050000,0.050000},{0.581250,0.006250,0.025000,0.025000},{0.581250,0.006250,0.050000,0.050000},{0.593750,0.006250,0.025000,0.025000},{0.593750,0.006250,0.050000,0.050000},{0.606250,0.006250,0.025000,0.025000},{0.606250,0.006250,0.050000,0.050000},{0.618750,0.006250,0.025000,0.025000},{0.618750,0.006250,0.050000,0.050000},{0.631250,0.006250,0.025000,0.025000},{0.631250,0.006250,0.050000,0.050000},{0.643750,0.006250,0.025000,0.025000},{0.643750,0.006250,0.050000,0.050000},{0.656250,0.006250,0.025000,0.025000},{0.656250,0.006250,0.050000,0.050000},{0.668750,0.006250,0.025000,0.025000},{0.668750,0.006250,0.050000,0.050000},{0.681250,0.006250,0.025000,0.025000},{0.681250,0.006250,0.050000,0.050000},{0.693750,0.006250,0.025000,0.025000},{0.693750,0.006250,0.050000,0.050000},{0.706250,0.006250,0.025000,0.025000},{0.706250,0.006250,0.050000,0.050000},{0.718750,0.006250,0.025000,0.025000},{0.718750,0.006250,0.050000,0.050000},{0.731250,0.006250,0.025000,0.025000},{0.731250,0.006250,0.050000,0.050000},{0.743750,0.006250,0.025000,0.025000},{0.743750,0.006250,0.050000,0.050000},{0.756250,0.006250,0.025000,0.025000},{0.756250,0.006250,0.050000,0.050000},{0.768750,0.006250,0.025000,0.025000},{0.768750,0.006250,0.050000,0.050000},{0.781250,0.006250,0.025000,0.025000},{0.781250,0.006250,0.050000,0.050000},{0.793750,0.006250,0.025000,0.025000},{0.793750,0.006250,0.050000,0.050000},{0.806250,0.006250,0.025000,0.025000},{0.806250,0.006250,0.050000,0.050000},{0.818750,0.006250,0.025000,0.025000},{0.818750,0.006250,0.050000,0.050000},{0.831250,0.006250,0.025000,0.025000},{0.831250,0.006250,0.050000,0.050000},{0.843750,0.006250,0.025000,0.025000},{0.843750,0.006250,0.050000,0.050000},{0.856250,0.006250,0.025000,0.025000},{0.856250,0.006250,0.050000,0.050000},{0.868750,0.006250,0.025000,0.025000},{0.868750,0.006250,0.050000,0.050000},{0.881250,0.006250,0.025000,0.025000},{0.881250,0.006250,0.050000,0.050000},{0.893750,0.006250,0.025000,0.025000},{0.893750,0.006250,0.050000,0.050000},{0.906250,0.006250,0.025000,0.025000},{0.906250,0.006250,0.050000,0.050000},{0.918750,0.006250,0.025000,0.025000},{0.918750,0.006250,0.050000,0.050000},{0.931250,0.006250,0.025000,0.025000},{0.931250,0.006250,0.050000,0.050000},{0.943750,0.006250,0.025000,0.025000},{0.943750,0.006250,0.050000,0.050000},{0.956250,0.006250,0.025000,0.025000},{0.956250,0.006250,0.050000,0.050000},{0.968750,0.006250,0.025000,0.025000},{0.968750,0.006250,0.050000,0.050000},{0.981250,0.006250,0.025000,0.025000},{0.981250,0.006250,0.050000,0.050000},{0.993750,0.006250,0.025000,0.025000},{0.993750,0.006250,0.050000,0.050000},{0.006250,0.018750,0.025000,0.025000},{0.006250,0.018750,0.050000,0.050000},{0.018750,0.018750,0.025000,0.025000},{0.018750,0.018750,0.050000,0.050000},{0.031250,0.018750,0.025000,0.025000},{0.031250,0.018750,0.050000,0.050000},{0.043750,0.018750,0.025000,0.025000},{0.043750,0.018750,0.050000,0.050000},{0.056250,0.018750,0.025000,0.025000},{0.056250,0.018750,0.050000,0.050000},{0.068750,0.018750,0.025000,0.025000},{0.068750,0.018750,0.050000,0.050000},{0.081250,0.018750,0.025000,0.025000},{0.081250,0.018750,0.050000,0.050000},{0.093750,0.018750,0.025000,0.025000},{0.093750,0.018750,0.050000,0.050000},{0.106250,0.018750,0.025000,0.025000},{0.106250,0.018750,0.050000,0.050000},{0.118750,0.018750,0.025000,0.025000},{0.118750,0.018750,0.050000,0.050000},{0.131250,0.018750,0.025000,0.025000},{0.131250,0.018750,0.050000,0.050000},{0.143750,0.018750,0.025000,0.025000},{0.143750,0.018750,0.050000,0.050000},{0.156250,0.018750,0.025000,0.025000},{0.156250,0.018750,0.050000,0.050000},{0.168750,0.018750,0.025000,0.025000},{0.168750,0.018750,0.050000,0.050000},{0.181250,0.018750,0.025000,0.025000},{0.181250,0.018750,0.050000,0.050000},{0.193750,0.018750,0.025000,0.025000},{0.193750,0.018750,0.050000,0.050000},{0.206250,0.018750,0.025000,0.025000},{0.206250,0.018750,0.050000,0.050000},{0.218750,0.018750,0.025000,0.025000},{0.218750,0.018750,0.050000,0.050000},{0.231250,0.018750,0.025000,0.025000},{0.231250,0.018750,0.050000,0.050000},{0.243750,0.018750,0.025000,0.025000},{0.243750,0.018750,0.050000,0.050000},{0.256250,0.018750,0.025000,0.025000},{0.256250,0.018750,0.050000,0.050000},{0.268750,0.018750,0.025000,0.025000},{0.268750,0.018750,0.050000,0.050000},{0.281250,0.018750,0.025000,0.025000},{0.281250,0.018750,0.050000,0.050000},{0.293750,0.018750,0.025000,0.025000},{0.293750,0.018750,0.050000,0.050000},{0.306250,0.018750,0.025000,0.025000},{0.306250,0.018750,0.050000,0.050000},{0.318750,0.018750,0.025000,0.025000},{0.318750,0.018750,0.050000,0.050000},{0.331250,0.018750,0.025000,0.025000},{0.331250,0.018750,0.050000,0.050000},{0.343750,0.018750,0.025000,0.025000},{0.343750,0.018750,0.050000,0.050000},{0.356250,0.018750,0.025000,0.025000},{0.356250,0.018750,0.050000,0.050000},{0.368750,0.018750,0.025000,0.025000},{0.368750,0.018750,0.050000,0.050000},{0.381250,0.018750,0.025000,0.025000},{0.381250,0.018750,0.050000,0.050000},{0.393750,0.018750,0.025000,0.025000},{0.393750,0.018750,0.050000,0.050000},{0.406250,0.018750,0.025000,0.025000},{0.406250,0.018750,0.050000,0.050000},{0.418750,0.018750,0.025000,0.025000},{0.418750,0.018750,0.050000,0.050000},{0.431250,0.018750,0.025000,0.025000},{0.431250,0.018750,0.050000,0.050000},{0.443750,0.018750,0.025000,0.025000},{0.443750,0.018750,0.050000,0.050000},{0.456250,0.018750,0.025000,0.025000},{0.456250,0.018750,0.050000,0.050000},{0.468750,0.018750,0.025000,0.025000},{0.468750,0.018750,0.050000,0.050000},{0.481250,0.018750,0.025000,0.025000},{0.481250,0.018750,0.050000,0.050000},{0.493750,0.018750,0.025000,0.025000},{0.493750,0.018750,0.050000,0.050000},{0.506250,0.018750,0.025000,0.025000},{0.506250,0.018750,0.050000,0.050000},{0.518750,0.018750,0.025000,0.025000},{0.518750,0.018750,0.050000,0.050000},{0.531250,0.018750,0.025000,0.025000},{0.531250,0.018750,0.050000,0.050000},{0.543750,0.018750,0.025000,0.025000},{0.543750,0.018750,0.050000,0.050000},{0.556250,0.018750,0.025000,0.025000},{0.556250,0.018750,0.050000,0.050000},{0.568750,0.018750,0.025000,0.025000},{0.568750,0.018750,0.050000,0.050000},{0.581250,0.018750,0.025000,0.025000},{0.581250,0.018750,0.050000,0.050000},{0.593750,0.018750,0.025000,0.025000},{0.593750,0.018750,0.050000,0.050000},{0.606250,0.018750,0.025000,0.025000},{0.606250,0.018750,0.050000,0.050000},{0.618750,0.018750,0.025000,0.025000},{0.618750,0.018750,0.050000,0.050000},{0.631250,0.018750,0.025000,0.025000},{0.631250,0.018750,0.050000,0.050000},{0.643750,0.018750,0.025000,0.025000},{0.643750,0.018750,0.050000,0.050000},{0.656250,0.018750,0.025000,0.025000},{0.656250,0.018750,0.050000,0.050000},{0.668750,0.018750,0.025000,0.025000},{0.668750,0.018750,0.050000,0.050000},{0.681250,0.018750,0.025000,0.025000},{0.681250,0.018750,0.050000,0.050000},{0.693750,0.018750,0.025000,0.025000},{0.693750,0.018750,0.050000,0.050000},{0.706250,0.018750,0.025000,0.025000},{0.706250,0.018750,0.050000,0.050000},{0.718750,0.018750,0.025000,0.025000},{0.718750,0.018750,0.050000,0.050000},{0.731250,0.018750,0.025000,0.025000},{0.731250,0.018750,0.050000,0.050000},{0.743750,0.018750,0.025000,0.025000},{0.743750,0.018750,0.050000,0.050000},{0.756250,0.018750,0.025000,0.025000},{0.756250,0.018750,0.050000,0.050000},{0.768750,0.018750,0.025000,0.025000},{0.768750,0.018750,0.050000,0.050000},{0.781250,0.018750,0.025000,0.025000},{0.781250,0.018750,0.050000,0.050000},{0.793750,0.018750,0.025000,0.025000},{0.793750,0.018750,0.050000,0.050000},{0.806250,0.018750,0.025000,0.025000},{0.806250,0.018750,0.050000,0.050000},{0.818750,0.018750,0.025000,0.025000},{0.818750,0.018750,0.050000,0.050000},{0.831250,0.018750,0.025000,0.025000},{0.831250,0.018750,0.050000,0.050000},{0.843750,0.018750,0.025000,0.025000},{0.843750,0.018750,0.050000,0.050000},{0.856250,0.018750,0.025000,0.025000},{0.856250,0.018750,0.050000,0.050000},{0.868750,0.018750,0.025000,0.025000},{0.868750,0.018750,0.050000,0.050000},{0.881250,0.018750,0.025000,0.025000},{0.881250,0.018750,0.050000,0.050000},{0.893750,0.018750,0.025000,0.025000},{0.893750,0.018750,0.050000,0.050000},{0.906250,0.018750,0.025000,0.025000},{0.906250,0.018750,0.050000,0.050000},{0.918750,0.018750,0.025000,0.025000},{0.918750,0.018750,0.050000,0.050000},{0.931250,0.018750,0.025000,0.025000},{0.931250,0.018750,0.050000,0.050000},{0.943750,0.018750,0.025000,0.025000},{0.943750,0.018750,0.050000,0.050000},{0.956250,0.018750,0.025000,0.025000},{0.956250,0.018750,0.050000,0.050000},{0.968750,0.018750,0.025000,0.025000},{0.968750,0.018750,0.050000,0.050000},{0.981250,0.018750,0.025000,0.025000},{0.981250,0.018750,0.050000,0.050000},{0.993750,0.018750,0.025000,0.025000},{0.993750,0.018750,0.050000,0.050000},{0.006250,0.031250,0.025000,0.025000},{0.006250,0.031250,0.050000,0.050000},{0.018750,0.031250,0.025000,0.025000},{0.018750,0.031250,0.050000,0.050000},{0.031250,0.031250,0.025000,0.025000},{0.031250,0.031250,0.050000,0.050000},{0.043750,0.031250,0.025000,0.025000},{0.043750,0.031250,0.050000,0.050000},{0.056250,0.031250,0.025000,0.025000},{0.056250,0.031250,0.050000,0.050000},{0.068750,0.031250,0.025000,0.025000},{0.068750,0.031250,0.050000,0.050000},{0.081250,0.031250,0.025000,0.025000},{0.081250,0.031250,0.050000,0.050000},{0.093750,0.031250,0.025000,0.025000},{0.093750,0.031250,0.050000,0.050000},{0.106250,0.031250,0.025000,0.025000},{0.106250,0.031250,0.050000,0.050000},{0.118750,0.031250,0.025000,0.025000},{0.118750,0.031250,0.050000,0.050000},{0.131250,0.031250,0.025000,0.025000},{0.131250,0.031250,0.050000,0.050000},{0.143750,0.031250,0.025000,0.025000},{0.143750,0.031250,0.050000,0.050000},{0.156250,0.031250,0.025000,0.025000},{0.156250,0.031250,0.050000,0.050000},{0.168750,0.031250,0.025000,0.025000},{0.168750,0.031250,0.050000,0.050000},{0.181250,0.031250,0.025000,0.025000},{0.181250,0.031250,0.050000,0.050000},{0.193750,0.031250,0.025000,0.025000},{0.193750,0.031250,0.050000,0.050000},{0.206250,0.031250,0.025000,0.025000},{0.206250,0.031250,0.050000,0.050000},{0.218750,0.031250,0.025000,0.025000},{0.218750,0.031250,0.050000,0.050000},{0.231250,0.031250,0.025000,0.025000},{0.231250,0.031250,0.050000,0.050000},{0.243750,0.031250,0.025000,0.025000},{0.243750,0.031250,0.050000,0.050000},{0.256250,0.031250,0.025000,0.025000},{0.256250,0.031250,0.050000,0.050000},{0.268750,0.031250,0.025000,0.025000},{0.268750,0.031250,0.050000,0.050000},{0.281250,0.031250,0.025000,0.025000},{0.281250,0.031250,0.050000,0.050000},{0.293750,0.031250,0.025000,0.025000},{0.293750,0.031250,0.050000,0.050000},{0.306250,0.031250,0.025000,0.025000},{0.306250,0.031250,0.050000,0.050000},{0.318750,0.031250,0.025000,0.025000},{0.318750,0.031250,0.050000,0.050000},{0.331250,0.031250,0.025000,0.025000},{0.331250,0.031250,0.050000,0.050000},{0.343750,0.031250,0.025000,0.025000},{0.343750,0.031250,0.050000,0.050000},{0.356250,0.031250,0.025000,0.025000},{0.356250,0.031250,0.050000,0.050000},{0.368750,0.031250,0.025000,0.025000},{0.368750,0.031250,0.050000,0.050000},{0.381250,0.031250,0.025000,0.025000},{0.381250,0.031250,0.050000,0.050000},{0.393750,0.031250,0.025000,0.025000},{0.393750,0.031250,0.050000,0.050000},{0.406250,0.031250,0.025000,0.025000},{0.406250,0.031250,0.050000,0.050000},{0.418750,0.031250,0.025000,0.025000},{0.418750,0.031250,0.050000,0.050000},{0.431250,0.031250,0.025000,0.025000},{0.431250,0.031250,0.050000,0.050000},{0.443750,0.031250,0.025000,0.025000},{0.443750,0.031250,0.050000,0.050000},{0.456250,0.031250,0.025000,0.025000},{0.456250,0.031250,0.050000,0.050000},{0.468750,0.031250,0.025000,0.025000},{0.468750,0.031250,0.050000,0.050000},{0.481250,0.031250,0.025000,0.025000},{0.481250,0.031250,0.050000,0.050000},{0.493750,0.031250,0.025000,0.025000},{0.493750,0.031250,0.050000,0.050000},{0.506250,0.031250,0.025000,0.025000},{0.506250,0.031250,0.050000,0.050000},{0.518750,0.031250,0.025000,0.025000},{0.518750,0.031250,0.050000,0.050000},{0.531250,0.031250,0.025000,0.025000},{0.531250,0.031250,0.050000,0.050000},{0.543750,0.031250,0.025000,0.025000},{0.543750,0.031250,0.050000,0.050000},{0.556250,0.031250,0.025000,0.025000},{0.556250,0.031250,0.050000,0.050000},{0.568750,0.031250,0.025000,0.025000},{0.568750,0.031250,0.050000,0.050000},{0.581250,0.031250,0.025000,0.025000},{0.581250,0.031250,0.050000,0.050000},{0.593750,0.031250,0.025000,0.025000},{0.593750,0.031250,0.050000,0.050000},{0.606250,0.031250,0.025000,0.025000},{0.606250,0.031250,0.050000,0.050000},{0.618750,0.031250,0.025000,0.025000},{0.618750,0.031250,0.050000,0.050000},{0.631250,0.031250,0.025000,0.025000},{0.631250,0.031250,0.050000,0.050000},{0.643750,0.031250,0.025000,0.025000},{0.643750,0.031250,0.050000,0.050000},{0.656250,0.031250,0.025000,0.025000},{0.656250,0.031250,0.050000,0.050000},{0.668750,0.031250,0.025000,0.025000},{0.668750,0.031250,0.050000,0.050000},{0.681250,0.031250,0.025000,0.025000},{0.681250,0.031250,0.050000,0.050000},{0.693750,0.031250,0.025000,0.025000},{0.693750,0.031250,0.050000,0.050000},{0.706250,0.031250,0.025000,0.025000},{0.706250,0.031250,0.050000,0.050000},{0.718750,0.031250,0.025000,0.025000},{0.718750,0.031250,0.050000,0.050000},{0.731250,0.031250,0.025000,0.025000},{0.731250,0.031250,0.050000,0.050000},{0.743750,0.031250,0.025000,0.025000},{0.743750,0.031250,0.050000,0.050000},{0.756250,0.031250,0.025000,0.025000},{0.756250,0.031250,0.050000,0.050000},{0.768750,0.031250,0.025000,0.025000},{0.768750,0.031250,0.050000,0.050000},{0.781250,0.031250,0.025000,0.025000},{0.781250,0.031250,0.050000,0.050000},{0.793750,0.031250,0.025000,0.025000},{0.793750,0.031250,0.050000,0.050000},{0.806250,0.031250,0.025000,0.025000},{0.806250,0.031250,0.050000,0.050000},{0.818750,0.031250,0.025000,0.025000},{0.818750,0.031250,0.050000,0.050000},{0.831250,0.031250,0.025000,0.025000},{0.831250,0.031250,0.050000,0.050000},{0.843750,0.031250,0.025000,0.025000},{0.843750,0.031250,0.050000,0.050000},{0.856250,0.031250,0.025000,0.025000},{0.856250,0.031250,0.050000,0.050000},{0.868750,0.031250,0.025000,0.025000},{0.868750,0.031250,0.050000,0.050000},{0.881250,0.031250,0.025000,0.025000},{0.881250,0.031250,0.050000,0.050000},{0.893750,0.031250,0.025000,0.025000},{0.893750,0.031250,0.050000,0.050000},{0.906250,0.031250,0.025000,0.025000},{0.906250,0.031250,0.050000,0.050000},{0.918750,0.031250,0.025000,0.025000},{0.918750,0.031250,0.050000,0.050000},{0.931250,0.031250,0.025000,0.025000},{0.931250,0.031250,0.050000,0.050000},{0.943750,0.031250,0.025000,0.025000},{0.943750,0.031250,0.050000,0.050000},{0.956250,0.031250,0.025000,0.025000},{0.956250,0.031250,0.050000,0.050000},{0.968750,0.031250,0.025000,0.025000},{0.968750,0.031250,0.050000,0.050000},{0.981250,0.031250,0.025000,0.025000},{0.981250,0.031250,0.050000,0.050000},{0.993750,0.031250,0.025000,0.025000},{0.993750,0.031250,0.050000,0.050000},{0.006250,0.043750,0.025000,0.025000},{0.006250,0.043750,0.050000,0.050000},{0.018750,0.043750,0.025000,0.025000},{0.018750,0.043750,0.050000,0.050000},{0.031250,0.043750,0.025000,0.025000},{0.031250,0.043750,0.050000,0.050000},{0.043750,0.043750,0.025000,0.025000},{0.043750,0.043750,0.050000,0.050000},{0.056250,0.043750,0.025000,0.025000},{0.056250,0.043750,0.050000,0.050000},{0.068750,0.043750,0.025000,0.025000},{0.068750,0.043750,0.050000,0.050000},{0.081250,0.043750,0.025000,0.025000},{0.081250,0.043750,0.050000,0.050000},{0.093750,0.043750,0.025000,0.025000},{0.093750,0.043750,0.050000,0.050000},{0.106250,0.043750,0.025000,0.025000},{0.106250,0.043750,0.050000,0.050000},{0.118750,0.043750,0.025000,0.025000},{0.118750,0.043750,0.050000,0.050000},{0.131250,0.043750,0.025000,0.025000},{0.131250,0.043750,0.050000,0.050000},{0.143750,0.043750,0.025000,0.025000},{0.143750,0.043750,0.050000,0.050000},{0.156250,0.043750,0.025000,0.025000},{0.156250,0.043750,0.050000,0.050000},{0.168750,0.043750,0.025000,0.025000},{0.168750,0.043750,0.050000,0.050000},{0.181250,0.043750,0.025000,0.025000},{0.181250,0.043750,0.050000,0.050000},{0.193750,0.043750,0.025000,0.025000},{0.193750,0.043750,0.050000,0.050000},{0.206250,0.043750,0.025000,0.025000},{0.206250,0.043750,0.050000,0.050000},{0.218750,0.043750,0.025000,0.025000},{0.218750,0.043750,0.050000,0.050000},{0.231250,0.043750,0.025000,0.025000},{0.231250,0.043750,0.050000,0.050000},{0.243750,0.043750,0.025000,0.025000},{0.243750,0.043750,0.050000,0.050000},{0.256250,0.043750,0.025000,0.025000},{0.256250,0.043750,0.050000,0.050000},{0.268750,0.043750,0.025000,0.025000},{0.268750,0.043750,0.050000,0.050000},{0.281250,0.043750,0.025000,0.025000},{0.281250,0.043750,0.050000,0.050000},{0.293750,0.043750,0.025000,0.025000},{0.293750,0.043750,0.050000,0.050000},{0.306250,0.043750,0.025000,0.025000},{0.306250,0.043750,0.050000,0.050000},{0.318750,0.043750,0.025000,0.025000},{0.318750,0.043750,0.050000,0.050000},{0.331250,0.043750,0.025000,0.025000},{0.331250,0.043750,0.050000,0.050000},{0.343750,0.043750,0.025000,0.025000},{0.343750,0.043750,0.050000,0.050000},{0.356250,0.043750,0.025000,0.025000},{0.356250,0.043750,0.050000,0.050000},{0.368750,0.043750,0.025000,0.025000},{0.368750,0.043750,0.050000,0.050000},{0.381250,0.043750,0.025000,0.025000},{0.381250,0.043750,0.050000,0.050000},{0.393750,0.043750,0.025000,0.025000},{0.393750,0.043750,0.050000,0.050000},{0.406250,0.043750,0.025000,0.025000},{0.406250,0.043750,0.050000,0.050000},{0.418750,0.043750,0.025000,0.025000},{0.418750,0.043750,0.050000,0.050000},{0.431250,0.043750,0.025000,0.025000},{0.431250,0.043750,0.050000,0.050000},{0.443750,0.043750,0.025000,0.025000},{0.443750,0.043750,0.050000,0.050000},{0.456250,0.043750,0.025000,0.025000},{0.456250,0.043750,0.050000,0.050000},{0.468750,0.043750,0.025000,0.025000},{0.468750,0.043750,0.050000,0.050000},{0.481250,0.043750,0.025000,0.025000},{0.481250,0.043750,0.050000,0.050000},{0.493750,0.043750,0.025000,0.025000},{0.493750,0.043750,0.050000,0.050000},{0.506250,0.043750,0.025000,0.025000},{0.506250,0.043750,0.050000,0.050000},{0.518750,0.043750,0.025000,0.025000},{0.518750,0.043750,0.050000,0.050000},{0.531250,0.043750,0.025000,0.025000},{0.531250,0.043750,0.050000,0.050000},{0.543750,0.043750,0.025000,0.025000},{0.543750,0.043750,0.050000,0.050000},{0.556250,0.043750,0.025000,0.025000},{0.556250,0.043750,0.050000,0.050000},{0.568750,0.043750,0.025000,0.025000},{0.568750,0.043750,0.050000,0.050000},{0.581250,0.043750,0.025000,0.025000},{0.581250,0.043750,0.050000,0.050000},{0.593750,0.043750,0.025000,0.025000},{0.593750,0.043750,0.050000,0.050000},{0.606250,0.043750,0.025000,0.025000},{0.606250,0.043750,0.050000,0.050000},{0.618750,0.043750,0.025000,0.025000},{0.618750,0.043750,0.050000,0.050000},{0.631250,0.043750,0.025000,0.025000},{0.631250,0.043750,0.050000,0.050000},{0.643750,0.043750,0.025000,0.025000},{0.643750,0.043750,0.050000,0.050000},{0.656250,0.043750,0.025000,0.025000},{0.656250,0.043750,0.050000,0.050000},{0.668750,0.043750,0.025000,0.025000},{0.668750,0.043750,0.050000,0.050000},{0.681250,0.043750,0.025000,0.025000},{0.681250,0.043750,0.050000,0.050000},{0.693750,0.043750,0.025000,0.025000},{0.693750,0.043750,0.050000,0.050000},{0.706250,0.043750,0.025000,0.025000},{0.706250,0.043750,0.050000,0.050000},{0.718750,0.043750,0.025000,0.025000},{0.718750,0.043750,0.050000,0.050000},{0.731250,0.043750,0.025000,0.025000},{0.731250,0.043750,0.050000,0.050000},{0.743750,0.043750,0.025000,0.025000},{0.743750,0.043750,0.050000,0.050000},{0.756250,0.043750,0.025000,0.025000},{0.756250,0.043750,0.050000,0.050000},{0.768750,0.043750,0.025000,0.025000},{0.768750,0.043750,0.050000,0.050000},{0.781250,0.043750,0.025000,0.025000},{0.781250,0.043750,0.050000,0.050000},{0.793750,0.043750,0.025000,0.025000},{0.793750,0.043750,0.050000,0.050000},{0.806250,0.043750,0.025000,0.025000},{0.806250,0.043750,0.050000,0.050000},{0.818750,0.043750,0.025000,0.025000},{0.818750,0.043750,0.050000,0.050000},{0.831250,0.043750,0.025000,0.025000},{0.831250,0.043750,0.050000,0.050000},{0.843750,0.043750,0.025000,0.025000},{0.843750,0.043750,0.050000,0.050000},{0.856250,0.043750,0.025000,0.025000},{0.856250,0.043750,0.050000,0.050000},{0.868750,0.043750,0.025000,0.025000},{0.868750,0.043750,0.050000,0.050000},{0.881250,0.043750,0.025000,0.025000},{0.881250,0.043750,0.050000,0.050000},{0.893750,0.043750,0.025000,0.025000},{0.893750,0.043750,0.050000,0.050000},{0.906250,0.043750,0.025000,0.025000},{0.906250,0.043750,0.050000,0.050000},{0.918750,0.043750,0.025000,0.025000},{0.918750,0.043750,0.050000,0.050000},{0.931250,0.043750,0.025000,0.025000},{0.931250,0.043750,0.050000,0.050000},{0.943750,0.043750,0.025000,0.025000},{0.943750,0.043750,0.050000,0.050000},{0.956250,0.043750,0.025000,0.025000},{0.956250,0.043750,0.050000,0.050000},{0.968750,0.043750,0.025000,0.025000},{0.968750,0.043750,0.050000,0.050000},{0.981250,0.043750,0.025000,0.025000},{0.981250,0.043750,0.050000,0.050000},{0.993750,0.043750,0.025000,0.025000},{0.993750,0.043750,0.050000,0.050000},{0.006250,0.056250,0.025000,0.025000},{0.006250,0.056250,0.050000,0.050000},{0.018750,0.056250,0.025000,0.025000},{0.018750,0.056250,0.050000,0.050000},{0.031250,0.056250,0.025000,0.025000},{0.031250,0.056250,0.050000,0.050000},{0.043750,0.056250,0.025000,0.025000},{0.043750,0.056250,0.050000,0.050000},{0.056250,0.056250,0.025000,0.025000},{0.056250,0.056250,0.050000,0.050000},{0.068750,0.056250,0.025000,0.025000},{0.068750,0.056250,0.050000,0.050000},{0.081250,0.056250,0.025000,0.025000},{0.081250,0.056250,0.050000,0.050000},{0.093750,0.056250,0.025000,0.025000},{0.093750,0.056250,0.050000,0.050000},{0.106250,0.056250,0.025000,0.025000},{0.106250,0.056250,0.050000,0.050000},{0.118750,0.056250,0.025000,0.025000},{0.118750,0.056250,0.050000,0.050000},{0.131250,0.056250,0.025000,0.025000},{0.131250,0.056250,0.050000,0.050000},{0.143750,0.056250,0.025000,0.025000},{0.143750,0.056250,0.050000,0.050000},{0.156250,0.056250,0.025000,0.025000},{0.156250,0.056250,0.050000,0.050000},{0.168750,0.056250,0.025000,0.025000},{0.168750,0.056250,0.050000,0.050000},{0.181250,0.056250,0.025000,0.025000},{0.181250,0.056250,0.050000,0.050000},{0.193750,0.056250,0.025000,0.025000},{0.193750,0.056250,0.050000,0.050000},{0.206250,0.056250,0.025000,0.025000},{0.206250,0.056250,0.050000,0.050000},{0.218750,0.056250,0.025000,0.025000},{0.218750,0.056250,0.050000,0.050000},{0.231250,0.056250,0.025000,0.025000},{0.231250,0.056250,0.050000,0.050000},{0.243750,0.056250,0.025000,0.025000},{0.243750,0.056250,0.050000,0.050000},{0.256250,0.056250,0.025000,0.025000},{0.256250,0.056250,0.050000,0.050000},{0.268750,0.056250,0.025000,0.025000},{0.268750,0.056250,0.050000,0.050000},{0.281250,0.056250,0.025000,0.025000},{0.281250,0.056250,0.050000,0.050000},{0.293750,0.056250,0.025000,0.025000},{0.293750,0.056250,0.050000,0.050000},{0.306250,0.056250,0.025000,0.025000},{0.306250,0.056250,0.050000,0.050000},{0.318750,0.056250,0.025000,0.025000},{0.318750,0.056250,0.050000,0.050000},{0.331250,0.056250,0.025000,0.025000},{0.331250,0.056250,0.050000,0.050000},{0.343750,0.056250,0.025000,0.025000},{0.343750,0.056250,0.050000,0.050000},{0.356250,0.056250,0.025000,0.025000},{0.356250,0.056250,0.050000,0.050000},{0.368750,0.056250,0.025000,0.025000},{0.368750,0.056250,0.050000,0.050000},{0.381250,0.056250,0.025000,0.025000},{0.381250,0.056250,0.050000,0.050000},{0.393750,0.056250,0.025000,0.025000},{0.393750,0.056250,0.050000,0.050000},{0.406250,0.056250,0.025000,0.025000},{0.406250,0.056250,0.050000,0.050000},{0.418750,0.056250,0.025000,0.025000},{0.418750,0.056250,0.050000,0.050000},{0.431250,0.056250,0.025000,0.025000},{0.431250,0.056250,0.050000,0.050000},{0.443750,0.056250,0.025000,0.025000},{0.443750,0.056250,0.050000,0.050000},{0.456250,0.056250,0.025000,0.025000},{0.456250,0.056250,0.050000,0.050000},{0.468750,0.056250,0.025000,0.025000},{0.468750,0.056250,0.050000,0.050000},{0.481250,0.056250,0.025000,0.025000},{0.481250,0.056250,0.050000,0.050000},{0.493750,0.056250,0.025000,0.025000},{0.493750,0.056250,0.050000,0.050000},{0.506250,0.056250,0.025000,0.025000},{0.506250,0.056250,0.050000,0.050000},{0.518750,0.056250,0.025000,0.025000},{0.518750,0.056250,0.050000,0.050000},{0.531250,0.056250,0.025000,0.025000},{0.531250,0.056250,0.050000,0.050000},{0.543750,0.056250,0.025000,0.025000},{0.543750,0.056250,0.050000,0.050000},{0.556250,0.056250,0.025000,0.025000},{0.556250,0.056250,0.050000,0.050000},{0.568750,0.056250,0.025000,0.025000},{0.568750,0.056250,0.050000,0.050000},{0.581250,0.056250,0.025000,0.025000},{0.581250,0.056250,0.050000,0.050000},{0.593750,0.056250,0.025000,0.025000},{0.593750,0.056250,0.050000,0.050000},{0.606250,0.056250,0.025000,0.025000},{0.606250,0.056250,0.050000,0.050000},{0.618750,0.056250,0.025000,0.025000},{0.618750,0.056250,0.050000,0.050000},{0.631250,0.056250,0.025000,0.025000},{0.631250,0.056250,0.050000,0.050000},{0.643750,0.056250,0.025000,0.025000},{0.643750,0.056250,0.050000,0.050000},{0.656250,0.056250,0.025000,0.025000},{0.656250,0.056250,0.050000,0.050000},{0.668750,0.056250,0.025000,0.025000},{0.668750,0.056250,0.050000,0.050000},{0.681250,0.056250,0.025000,0.025000},{0.681250,0.056250,0.050000,0.050000},{0.693750,0.056250,0.025000,0.025000},{0.693750,0.056250,0.050000,0.050000},{0.706250,0.056250,0.025000,0.025000},{0.706250,0.056250,0.050000,0.050000},{0.718750,0.056250,0.025000,0.025000},{0.718750,0.056250,0.050000,0.050000},{0.731250,0.056250,0.025000,0.025000},{0.731250,0.056250,0.050000,0.050000},{0.743750,0.056250,0.025000,0.025000},{0.743750,0.056250,0.050000,0.050000},{0.756250,0.056250,0.025000,0.025000},{0.756250,0.056250,0.050000,0.050000},{0.768750,0.056250,0.025000,0.025000},{0.768750,0.056250,0.050000,0.050000},{0.781250,0.056250,0.025000,0.025000},{0.781250,0.056250,0.050000,0.050000},{0.793750,0.056250,0.025000,0.025000},{0.793750,0.056250,0.050000,0.050000},{0.806250,0.056250,0.025000,0.025000},{0.806250,0.056250,0.050000,0.050000},{0.818750,0.056250,0.025000,0.025000},{0.818750,0.056250,0.050000,0.050000},{0.831250,0.056250,0.025000,0.025000},{0.831250,0.056250,0.050000,0.050000},{0.843750,0.056250,0.025000,0.025000},{0.843750,0.056250,0.050000,0.050000},{0.856250,0.056250,0.025000,0.025000},{0.856250,0.056250,0.050000,0.050000},{0.868750,0.056250,0.025000,0.025000},{0.868750,0.056250,0.050000,0.050000},{0.881250,0.056250,0.025000,0.025000},{0.881250,0.056250,0.050000,0.050000},{0.893750,0.056250,0.025000,0.025000},{0.893750,0.056250,0.050000,0.050000},{0.906250,0.056250,0.025000,0.025000},{0.906250,0.056250,0.050000,0.050000},{0.918750,0.056250,0.025000,0.025000},{0.918750,0.056250,0.050000,0.050000},{0.931250,0.056250,0.025000,0.025000},{0.931250,0.056250,0.050000,0.050000},{0.943750,0.056250,0.025000,0.025000},{0.943750,0.056250,0.050000,0.050000},{0.956250,0.056250,0.025000,0.025000},{0.956250,0.056250,0.050000,0.050000},{0.968750,0.056250,0.025000,0.025000},{0.968750,0.056250,0.050000,0.050000},{0.981250,0.056250,0.025000,0.025000},{0.981250,0.056250,0.050000,0.050000},{0.993750,0.056250,0.025000,0.025000},{0.993750,0.056250,0.050000,0.050000},{0.006250,0.068750,0.025000,0.025000},{0.006250,0.068750,0.050000,0.050000},{0.018750,0.068750,0.025000,0.025000},{0.018750,0.068750,0.050000,0.050000},{0.031250,0.068750,0.025000,0.025000},{0.031250,0.068750,0.050000,0.050000},{0.043750,0.068750,0.025000,0.025000},{0.043750,0.068750,0.050000,0.050000},{0.056250,0.068750,0.025000,0.025000},{0.056250,0.068750,0.050000,0.050000},{0.068750,0.068750,0.025000,0.025000},{0.068750,0.068750,0.050000,0.050000},{0.081250,0.068750,0.025000,0.025000},{0.081250,0.068750,0.050000,0.050000},{0.093750,0.068750,0.025000,0.025000},{0.093750,0.068750,0.050000,0.050000},{0.106250,0.068750,0.025000,0.025000},{0.106250,0.068750,0.050000,0.050000},{0.118750,0.068750,0.025000,0.025000},{0.118750,0.068750,0.050000,0.050000},{0.131250,0.068750,0.025000,0.025000},{0.131250,0.068750,0.050000,0.050000},{0.143750,0.068750,0.025000,0.025000},{0.143750,0.068750,0.050000,0.050000},{0.156250,0.068750,0.025000,0.025000},{0.156250,0.068750,0.050000,0.050000},{0.168750,0.068750,0.025000,0.025000},{0.168750,0.068750,0.050000,0.050000},{0.181250,0.068750,0.025000,0.025000},{0.181250,0.068750,0.050000,0.050000},{0.193750,0.068750,0.025000,0.025000},{0.193750,0.068750,0.050000,0.050000},{0.206250,0.068750,0.025000,0.025000},{0.206250,0.068750,0.050000,0.050000},{0.218750,0.068750,0.025000,0.025000},{0.218750,0.068750,0.050000,0.050000},{0.231250,0.068750,0.025000,0.025000},{0.231250,0.068750,0.050000,0.050000},{0.243750,0.068750,0.025000,0.025000},{0.243750,0.068750,0.050000,0.050000},{0.256250,0.068750,0.025000,0.025000},{0.256250,0.068750,0.050000,0.050000},{0.268750,0.068750,0.025000,0.025000},{0.268750,0.068750,0.050000,0.050000},{0.281250,0.068750,0.025000,0.025000},{0.281250,0.068750,0.050000,0.050000},{0.293750,0.068750,0.025000,0.025000},{0.293750,0.068750,0.050000,0.050000},{0.306250,0.068750,0.025000,0.025000},{0.306250,0.068750,0.050000,0.050000},{0.318750,0.068750,0.025000,0.025000},{0.318750,0.068750,0.050000,0.050000},{0.331250,0.068750,0.025000,0.025000},{0.331250,0.068750,0.050000,0.050000},{0.343750,0.068750,0.025000,0.025000},{0.343750,0.068750,0.050000,0.050000},{0.356250,0.068750,0.025000,0.025000},{0.356250,0.068750,0.050000,0.050000},{0.368750,0.068750,0.025000,0.025000},{0.368750,0.068750,0.050000,0.050000},{0.381250,0.068750,0.025000,0.025000},{0.381250,0.068750,0.050000,0.050000},{0.393750,0.068750,0.025000,0.025000},{0.393750,0.068750,0.050000,0.050000},{0.406250,0.068750,0.025000,0.025000},{0.406250,0.068750,0.050000,0.050000},{0.418750,0.068750,0.025000,0.025000},{0.418750,0.068750,0.050000,0.050000},{0.431250,0.068750,0.025000,0.025000},{0.431250,0.068750,0.050000,0.050000},{0.443750,0.068750,0.025000,0.025000},{0.443750,0.068750,0.050000,0.050000},{0.456250,0.068750,0.025000,0.025000},{0.456250,0.068750,0.050000,0.050000},{0.468750,0.068750,0.025000,0.025000},{0.468750,0.068750,0.050000,0.050000},{0.481250,0.068750,0.025000,0.025000},{0.481250,0.068750,0.050000,0.050000},{0.493750,0.068750,0.025000,0.025000},{0.493750,0.068750,0.050000,0.050000},{0.506250,0.068750,0.025000,0.025000},{0.506250,0.068750,0.050000,0.050000},{0.518750,0.068750,0.025000,0.025000},{0.518750,0.068750,0.050000,0.050000},{0.531250,0.068750,0.025000,0.025000},{0.531250,0.068750,0.050000,0.050000},{0.543750,0.068750,0.025000,0.025000},{0.543750,0.068750,0.050000,0.050000},{0.556250,0.068750,0.025000,0.025000},{0.556250,0.068750,0.050000,0.050000},{0.568750,0.068750,0.025000,0.025000},{0.568750,0.068750,0.050000,0.050000},{0.581250,0.068750,0.025000,0.025000},{0.581250,0.068750,0.050000,0.050000},{0.593750,0.068750,0.025000,0.025000},{0.593750,0.068750,0.050000,0.050000},{0.606250,0.068750,0.025000,0.025000},{0.606250,0.068750,0.050000,0.050000},{0.618750,0.068750,0.025000,0.025000},{0.618750,0.068750,0.050000,0.050000},{0.631250,0.068750,0.025000,0.025000},{0.631250,0.068750,0.050000,0.050000},{0.643750,0.068750,0.025000,0.025000},{0.643750,0.068750,0.050000,0.050000},{0.656250,0.068750,0.025000,0.025000},{0.656250,0.068750,0.050000,0.050000},{0.668750,0.068750,0.025000,0.025000},{0.668750,0.068750,0.050000,0.050000},{0.681250,0.068750,0.025000,0.025000},{0.681250,0.068750,0.050000,0.050000},{0.693750,0.068750,0.025000,0.025000},{0.693750,0.068750,0.050000,0.050000},{0.706250,0.068750,0.025000,0.025000},{0.706250,0.068750,0.050000,0.050000},{0.718750,0.068750,0.025000,0.025000},{0.718750,0.068750,0.050000,0.050000},{0.731250,0.068750,0.025000,0.025000},{0.731250,0.068750,0.050000,0.050000},{0.743750,0.068750,0.025000,0.025000},{0.743750,0.068750,0.050000,0.050000},{0.756250,0.068750,0.025000,0.025000},{0.756250,0.068750,0.050000,0.050000},{0.768750,0.068750,0.025000,0.025000},{0.768750,0.068750,0.050000,0.050000},{0.781250,0.068750,0.025000,0.025000},{0.781250,0.068750,0.050000,0.050000},{0.793750,0.068750,0.025000,0.025000},{0.793750,0.068750,0.050000,0.050000},{0.806250,0.068750,0.025000,0.025000},{0.806250,0.068750,0.050000,0.050000},{0.818750,0.068750,0.025000,0.025000},{0.818750,0.068750,0.050000,0.050000},{0.831250,0.068750,0.025000,0.025000},{0.831250,0.068750,0.050000,0.050000},{0.843750,0.068750,0.025000,0.025000},{0.843750,0.068750,0.050000,0.050000},{0.856250,0.068750,0.025000,0.025000},{0.856250,0.068750,0.050000,0.050000},{0.868750,0.068750,0.025000,0.025000},{0.868750,0.068750,0.050000,0.050000},{0.881250,0.068750,0.025000,0.025000},{0.881250,0.068750,0.050000,0.050000},{0.893750,0.068750,0.025000,0.025000},{0.893750,0.068750,0.050000,0.050000},{0.906250,0.068750,0.025000,0.025000},{0.906250,0.068750,0.050000,0.050000},{0.918750,0.068750,0.025000,0.025000},{0.918750,0.068750,0.050000,0.050000},{0.931250,0.068750,0.025000,0.025000},{0.931250,0.068750,0.050000,0.050000},{0.943750,0.068750,0.025000,0.025000},{0.943750,0.068750,0.050000,0.050000},{0.956250,0.068750,0.025000,0.025000},{0.956250,0.068750,0.050000,0.050000},{0.968750,0.068750,0.025000,0.025000},{0.968750,0.068750,0.050000,0.050000},{0.981250,0.068750,0.025000,0.025000},{0.981250,0.068750,0.050000,0.050000},{0.993750,0.068750,0.025000,0.025000},{0.993750,0.068750,0.050000,0.050000},{0.006250,0.081250,0.025000,0.025000},{0.006250,0.081250,0.050000,0.050000},{0.018750,0.081250,0.025000,0.025000},{0.018750,0.081250,0.050000,0.050000},{0.031250,0.081250,0.025000,0.025000},{0.031250,0.081250,0.050000,0.050000},{0.043750,0.081250,0.025000,0.025000},{0.043750,0.081250,0.050000,0.050000},{0.056250,0.081250,0.025000,0.025000},{0.056250,0.081250,0.050000,0.050000},{0.068750,0.081250,0.025000,0.025000},{0.068750,0.081250,0.050000,0.050000},{0.081250,0.081250,0.025000,0.025000},{0.081250,0.081250,0.050000,0.050000},{0.093750,0.081250,0.025000,0.025000},{0.093750,0.081250,0.050000,0.050000},{0.106250,0.081250,0.025000,0.025000},{0.106250,0.081250,0.050000,0.050000},{0.118750,0.081250,0.025000,0.025000},{0.118750,0.081250,0.050000,0.050000},{0.131250,0.081250,0.025000,0.025000},{0.131250,0.081250,0.050000,0.050000},{0.143750,0.081250,0.025000,0.025000},{0.143750,0.081250,0.050000,0.050000},{0.156250,0.081250,0.025000,0.025000},{0.156250,0.081250,0.050000,0.050000},{0.168750,0.081250,0.025000,0.025000},{0.168750,0.081250,0.050000,0.050000},{0.181250,0.081250,0.025000,0.025000},{0.181250,0.081250,0.050000,0.050000},{0.193750,0.081250,0.025000,0.025000},{0.193750,0.081250,0.050000,0.050000},{0.206250,0.081250,0.025000,0.025000},{0.206250,0.081250,0.050000,0.050000},{0.218750,0.081250,0.025000,0.025000},{0.218750,0.081250,0.050000,0.050000},{0.231250,0.081250,0.025000,0.025000},{0.231250,0.081250,0.050000,0.050000},{0.243750,0.081250,0.025000,0.025000},{0.243750,0.081250,0.050000,0.050000},{0.256250,0.081250,0.025000,0.025000},{0.256250,0.081250,0.050000,0.050000},{0.268750,0.081250,0.025000,0.025000},{0.268750,0.081250,0.050000,0.050000},{0.281250,0.081250,0.025000,0.025000},{0.281250,0.081250,0.050000,0.050000},{0.293750,0.081250,0.025000,0.025000},{0.293750,0.081250,0.050000,0.050000},{0.306250,0.081250,0.025000,0.025000},{0.306250,0.081250,0.050000,0.050000},{0.318750,0.081250,0.025000,0.025000},{0.318750,0.081250,0.050000,0.050000},{0.331250,0.081250,0.025000,0.025000},{0.331250,0.081250,0.050000,0.050000},{0.343750,0.081250,0.025000,0.025000},{0.343750,0.081250,0.050000,0.050000},{0.356250,0.081250,0.025000,0.025000},{0.356250,0.081250,0.050000,0.050000},{0.368750,0.081250,0.025000,0.025000},{0.368750,0.081250,0.050000,0.050000},{0.381250,0.081250,0.025000,0.025000},{0.381250,0.081250,0.050000,0.050000},{0.393750,0.081250,0.025000,0.025000},{0.393750,0.081250,0.050000,0.050000},{0.406250,0.081250,0.025000,0.025000},{0.406250,0.081250,0.050000,0.050000},{0.418750,0.081250,0.025000,0.025000},{0.418750,0.081250,0.050000,0.050000},{0.431250,0.081250,0.025000,0.025000},{0.431250,0.081250,0.050000,0.050000},{0.443750,0.081250,0.025000,0.025000},{0.443750,0.081250,0.050000,0.050000},{0.456250,0.081250,0.025000,0.025000},{0.456250,0.081250,0.050000,0.050000},{0.468750,0.081250,0.025000,0.025000},{0.468750,0.081250,0.050000,0.050000},{0.481250,0.081250,0.025000,0.025000},{0.481250,0.081250,0.050000,0.050000},{0.493750,0.081250,0.025000,0.025000},{0.493750,0.081250,0.050000,0.050000},{0.506250,0.081250,0.025000,0.025000},{0.506250,0.081250,0.050000,0.050000},{0.518750,0.081250,0.025000,0.025000},{0.518750,0.081250,0.050000,0.050000},{0.531250,0.081250,0.025000,0.025000},{0.531250,0.081250,0.050000,0.050000},{0.543750,0.081250,0.025000,0.025000},{0.543750,0.081250,0.050000,0.050000},{0.556250,0.081250,0.025000,0.025000},{0.556250,0.081250,0.050000,0.050000},{0.568750,0.081250,0.025000,0.025000},{0.568750,0.081250,0.050000,0.050000},{0.581250,0.081250,0.025000,0.025000},{0.581250,0.081250,0.050000,0.050000},{0.593750,0.081250,0.025000,0.025000},{0.593750,0.081250,0.050000,0.050000},{0.606250,0.081250,0.025000,0.025000},{0.606250,0.081250,0.050000,0.050000},{0.618750,0.081250,0.025000,0.025000},{0.618750,0.081250,0.050000,0.050000},{0.631250,0.081250,0.025000,0.025000},{0.631250,0.081250,0.050000,0.050000},{0.643750,0.081250,0.025000,0.025000},{0.643750,0.081250,0.050000,0.050000},{0.656250,0.081250,0.025000,0.025000},{0.656250,0.081250,0.050000,0.050000},{0.668750,0.081250,0.025000,0.025000},{0.668750,0.081250,0.050000,0.050000},{0.681250,0.081250,0.025000,0.025000},{0.681250,0.081250,0.050000,0.050000},{0.693750,0.081250,0.025000,0.025000},{0.693750,0.081250,0.050000,0.050000},{0.706250,0.081250,0.025000,0.025000},{0.706250,0.081250,0.050000,0.050000},{0.718750,0.081250,0.025000,0.025000},{0.718750,0.081250,0.050000,0.050000},{0.731250,0.081250,0.025000,0.025000},{0.731250,0.081250,0.050000,0.050000},{0.743750,0.081250,0.025000,0.025000},{0.743750,0.081250,0.050000,0.050000},{0.756250,0.081250,0.025000,0.025000},{0.756250,0.081250,0.050000,0.050000},{0.768750,0.081250,0.025000,0.025000},{0.768750,0.081250,0.050000,0.050000},{0.781250,0.081250,0.025000,0.025000},{0.781250,0.081250,0.050000,0.050000},{0.793750,0.081250,0.025000,0.025000},{0.793750,0.081250,0.050000,0.050000},{0.806250,0.081250,0.025000,0.025000},{0.806250,0.081250,0.050000,0.050000},{0.818750,0.081250,0.025000,0.025000},{0.818750,0.081250,0.050000,0.050000},{0.831250,0.081250,0.025000,0.025000},{0.831250,0.081250,0.050000,0.050000},{0.843750,0.081250,0.025000,0.025000},{0.843750,0.081250,0.050000,0.050000},{0.856250,0.081250,0.025000,0.025000},{0.856250,0.081250,0.050000,0.050000},{0.868750,0.081250,0.025000,0.025000},{0.868750,0.081250,0.050000,0.050000},{0.881250,0.081250,0.025000,0.025000},{0.881250,0.081250,0.050000,0.050000},{0.893750,0.081250,0.025000,0.025000},{0.893750,0.081250,0.050000,0.050000},{0.906250,0.081250,0.025000,0.025000},{0.906250,0.081250,0.050000,0.050000},{0.918750,0.081250,0.025000,0.025000},{0.918750,0.081250,0.050000,0.050000},{0.931250,0.081250,0.025000,0.025000},{0.931250,0.081250,0.050000,0.050000},{0.943750,0.081250,0.025000,0.025000},{0.943750,0.081250,0.050000,0.050000},{0.956250,0.081250,0.025000,0.025000},{0.956250,0.081250,0.050000,0.050000},{0.968750,0.081250,0.025000,0.025000},{0.968750,0.081250,0.050000,0.050000},{0.981250,0.081250,0.025000,0.025000},{0.981250,0.081250,0.050000,0.050000},{0.993750,0.081250,0.025000,0.025000},{0.993750,0.081250,0.050000,0.050000},{0.006250,0.093750,0.025000,0.025000},{0.006250,0.093750,0.050000,0.050000},{0.018750,0.093750,0.025000,0.025000},{0.018750,0.093750,0.050000,0.050000},{0.031250,0.093750,0.025000,0.025000},{0.031250,0.093750,0.050000,0.050000},{0.043750,0.093750,0.025000,0.025000},{0.043750,0.093750,0.050000,0.050000},{0.056250,0.093750,0.025000,0.025000},{0.056250,0.093750,0.050000,0.050000},{0.068750,0.093750,0.025000,0.025000},{0.068750,0.093750,0.050000,0.050000},{0.081250,0.093750,0.025000,0.025000},{0.081250,0.093750,0.050000,0.050000},{0.093750,0.093750,0.025000,0.025000},{0.093750,0.093750,0.050000,0.050000},{0.106250,0.093750,0.025000,0.025000},{0.106250,0.093750,0.050000,0.050000},{0.118750,0.093750,0.025000,0.025000},{0.118750,0.093750,0.050000,0.050000},{0.131250,0.093750,0.025000,0.025000},{0.131250,0.093750,0.050000,0.050000},{0.143750,0.093750,0.025000,0.025000},{0.143750,0.093750,0.050000,0.050000},{0.156250,0.093750,0.025000,0.025000},{0.156250,0.093750,0.050000,0.050000},{0.168750,0.093750,0.025000,0.025000},{0.168750,0.093750,0.050000,0.050000},{0.181250,0.093750,0.025000,0.025000},{0.181250,0.093750,0.050000,0.050000},{0.193750,0.093750,0.025000,0.025000},{0.193750,0.093750,0.050000,0.050000},{0.206250,0.093750,0.025000,0.025000},{0.206250,0.093750,0.050000,0.050000},{0.218750,0.093750,0.025000,0.025000},{0.218750,0.093750,0.050000,0.050000},{0.231250,0.093750,0.025000,0.025000},{0.231250,0.093750,0.050000,0.050000},{0.243750,0.093750,0.025000,0.025000},{0.243750,0.093750,0.050000,0.050000},{0.256250,0.093750,0.025000,0.025000},{0.256250,0.093750,0.050000,0.050000},{0.268750,0.093750,0.025000,0.025000},{0.268750,0.093750,0.050000,0.050000},{0.281250,0.093750,0.025000,0.025000},{0.281250,0.093750,0.050000,0.050000},{0.293750,0.093750,0.025000,0.025000},{0.293750,0.093750,0.050000,0.050000},{0.306250,0.093750,0.025000,0.025000},{0.306250,0.093750,0.050000,0.050000},{0.318750,0.093750,0.025000,0.025000},{0.318750,0.093750,0.050000,0.050000},{0.331250,0.093750,0.025000,0.025000},{0.331250,0.093750,0.050000,0.050000},{0.343750,0.093750,0.025000,0.025000},{0.343750,0.093750,0.050000,0.050000},{0.356250,0.093750,0.025000,0.025000},{0.356250,0.093750,0.050000,0.050000},{0.368750,0.093750,0.025000,0.025000},{0.368750,0.093750,0.050000,0.050000},{0.381250,0.093750,0.025000,0.025000},{0.381250,0.093750,0.050000,0.050000},{0.393750,0.093750,0.025000,0.025000},{0.393750,0.093750,0.050000,0.050000},{0.406250,0.093750,0.025000,0.025000},{0.406250,0.093750,0.050000,0.050000},{0.418750,0.093750,0.025000,0.025000},{0.418750,0.093750,0.050000,0.050000},{0.431250,0.093750,0.025000,0.025000},{0.431250,0.093750,0.050000,0.050000},{0.443750,0.093750,0.025000,0.025000},{0.443750,0.093750,0.050000,0.050000},{0.456250,0.093750,0.025000,0.025000},{0.456250,0.093750,0.050000,0.050000},{0.468750,0.093750,0.025000,0.025000},{0.468750,0.093750,0.050000,0.050000},{0.481250,0.093750,0.025000,0.025000},{0.481250,0.093750,0.050000,0.050000},{0.493750,0.093750,0.025000,0.025000},{0.493750,0.093750,0.050000,0.050000},{0.506250,0.093750,0.025000,0.025000},{0.506250,0.093750,0.050000,0.050000},{0.518750,0.093750,0.025000,0.025000},{0.518750,0.093750,0.050000,0.050000},{0.531250,0.093750,0.025000,0.025000},{0.531250,0.093750,0.050000,0.050000},{0.543750,0.093750,0.025000,0.025000},{0.543750,0.093750,0.050000,0.050000},{0.556250,0.093750,0.025000,0.025000},{0.556250,0.093750,0.050000,0.050000},{0.568750,0.093750,0.025000,0.025000},{0.568750,0.093750,0.050000,0.050000},{0.581250,0.093750,0.025000,0.025000},{0.581250,0.093750,0.050000,0.050000},{0.593750,0.093750,0.025000,0.025000},{0.593750,0.093750,0.050000,0.050000},{0.606250,0.093750,0.025000,0.025000},{0.606250,0.093750,0.050000,0.050000},{0.618750,0.093750,0.025000,0.025000},{0.618750,0.093750,0.050000,0.050000},{0.631250,0.093750,0.025000,0.025000},{0.631250,0.093750,0.050000,0.050000},{0.643750,0.093750,0.025000,0.025000},{0.643750,0.093750,0.050000,0.050000},{0.656250,0.093750,0.025000,0.025000},{0.656250,0.093750,0.050000,0.050000},{0.668750,0.093750,0.025000,0.025000},{0.668750,0.093750,0.050000,0.050000},{0.681250,0.093750,0.025000,0.025000},{0.681250,0.093750,0.050000,0.050000},{0.693750,0.093750,0.025000,0.025000},{0.693750,0.093750,0.050000,0.050000},{0.706250,0.093750,0.025000,0.025000},{0.706250,0.093750,0.050000,0.050000},{0.718750,0.093750,0.025000,0.025000},{0.718750,0.093750,0.050000,0.050000},{0.731250,0.093750,0.025000,0.025000},{0.731250,0.093750,0.050000,0.050000},{0.743750,0.093750,0.025000,0.025000},{0.743750,0.093750,0.050000,0.050000},{0.756250,0.093750,0.025000,0.025000},{0.756250,0.093750,0.050000,0.050000},{0.768750,0.093750,0.025000,0.025000},{0.768750,0.093750,0.050000,0.050000},{0.781250,0.093750,0.025000,0.025000},{0.781250,0.093750,0.050000,0.050000},{0.793750,0.093750,0.025000,0.025000},{0.793750,0.093750,0.050000,0.050000},{0.806250,0.093750,0.025000,0.025000},{0.806250,0.093750,0.050000,0.050000},{0.818750,0.093750,0.025000,0.025000},{0.818750,0.093750,0.050000,0.050000},{0.831250,0.093750,0.025000,0.025000},{0.831250,0.093750,0.050000,0.050000},{0.843750,0.093750,0.025000,0.025000},{0.843750,0.093750,0.050000,0.050000},{0.856250,0.093750,0.025000,0.025000},{0.856250,0.093750,0.050000,0.050000},{0.868750,0.093750,0.025000,0.025000},{0.868750,0.093750,0.050000,0.050000},{0.881250,0.093750,0.025000,0.025000},{0.881250,0.093750,0.050000,0.050000},{0.893750,0.093750,0.025000,0.025000},{0.893750,0.093750,0.050000,0.050000},{0.906250,0.093750,0.025000,0.025000},{0.906250,0.093750,0.050000,0.050000},{0.918750,0.093750,0.025000,0.025000},{0.918750,0.093750,0.050000,0.050000},{0.931250,0.093750,0.025000,0.025000},{0.931250,0.093750,0.050000,0.050000},{0.943750,0.093750,0.025000,0.025000},{0.943750,0.093750,0.050000,0.050000},{0.956250,0.093750,0.025000,0.025000},{0.956250,0.093750,0.050000,0.050000},{0.968750,0.093750,0.025000,0.025000},{0.968750,0.093750,0.050000,0.050000},{0.981250,0.093750,0.025000,0.025000},{0.981250,0.093750,0.050000,0.050000},{0.993750,0.093750,0.025000,0.025000},{0.993750,0.093750,0.050000,0.050000},{0.006250,0.106250,0.025000,0.025000},{0.006250,0.106250,0.050000,0.050000},{0.018750,0.106250,0.025000,0.025000},{0.018750,0.106250,0.050000,0.050000},{0.031250,0.106250,0.025000,0.025000},{0.031250,0.106250,0.050000,0.050000},{0.043750,0.106250,0.025000,0.025000},{0.043750,0.106250,0.050000,0.050000},{0.056250,0.106250,0.025000,0.025000},{0.056250,0.106250,0.050000,0.050000},{0.068750,0.106250,0.025000,0.025000},{0.068750,0.106250,0.050000,0.050000},{0.081250,0.106250,0.025000,0.025000},{0.081250,0.106250,0.050000,0.050000},{0.093750,0.106250,0.025000,0.025000},{0.093750,0.106250,0.050000,0.050000},{0.106250,0.106250,0.025000,0.025000},{0.106250,0.106250,0.050000,0.050000},{0.118750,0.106250,0.025000,0.025000},{0.118750,0.106250,0.050000,0.050000},{0.131250,0.106250,0.025000,0.025000},{0.131250,0.106250,0.050000,0.050000},{0.143750,0.106250,0.025000,0.025000},{0.143750,0.106250,0.050000,0.050000},{0.156250,0.106250,0.025000,0.025000},{0.156250,0.106250,0.050000,0.050000},{0.168750,0.106250,0.025000,0.025000},{0.168750,0.106250,0.050000,0.050000},{0.181250,0.106250,0.025000,0.025000},{0.181250,0.106250,0.050000,0.050000},{0.193750,0.106250,0.025000,0.025000},{0.193750,0.106250,0.050000,0.050000},{0.206250,0.106250,0.025000,0.025000},{0.206250,0.106250,0.050000,0.050000},{0.218750,0.106250,0.025000,0.025000},{0.218750,0.106250,0.050000,0.050000},{0.231250,0.106250,0.025000,0.025000},{0.231250,0.106250,0.050000,0.050000},{0.243750,0.106250,0.025000,0.025000},{0.243750,0.106250,0.050000,0.050000},{0.256250,0.106250,0.025000,0.025000},{0.256250,0.106250,0.050000,0.050000},{0.268750,0.106250,0.025000,0.025000},{0.268750,0.106250,0.050000,0.050000},{0.281250,0.106250,0.025000,0.025000},{0.281250,0.106250,0.050000,0.050000},{0.293750,0.106250,0.025000,0.025000},{0.293750,0.106250,0.050000,0.050000},{0.306250,0.106250,0.025000,0.025000},{0.306250,0.106250,0.050000,0.050000},{0.318750,0.106250,0.025000,0.025000},{0.318750,0.106250,0.050000,0.050000},{0.331250,0.106250,0.025000,0.025000},{0.331250,0.106250,0.050000,0.050000},{0.343750,0.106250,0.025000,0.025000},{0.343750,0.106250,0.050000,0.050000},{0.356250,0.106250,0.025000,0.025000},{0.356250,0.106250,0.050000,0.050000},{0.368750,0.106250,0.025000,0.025000},{0.368750,0.106250,0.050000,0.050000},{0.381250,0.106250,0.025000,0.025000},{0.381250,0.106250,0.050000,0.050000},{0.393750,0.106250,0.025000,0.025000},{0.393750,0.106250,0.050000,0.050000},{0.406250,0.106250,0.025000,0.025000},{0.406250,0.106250,0.050000,0.050000},{0.418750,0.106250,0.025000,0.025000},{0.418750,0.106250,0.050000,0.050000},{0.431250,0.106250,0.025000,0.025000},{0.431250,0.106250,0.050000,0.050000},{0.443750,0.106250,0.025000,0.025000},{0.443750,0.106250,0.050000,0.050000},{0.456250,0.106250,0.025000,0.025000},{0.456250,0.106250,0.050000,0.050000},{0.468750,0.106250,0.025000,0.025000},{0.468750,0.106250,0.050000,0.050000},{0.481250,0.106250,0.025000,0.025000},{0.481250,0.106250,0.050000,0.050000},{0.493750,0.106250,0.025000,0.025000},{0.493750,0.106250,0.050000,0.050000},{0.506250,0.106250,0.025000,0.025000},{0.506250,0.106250,0.050000,0.050000},{0.518750,0.106250,0.025000,0.025000},{0.518750,0.106250,0.050000,0.050000},{0.531250,0.106250,0.025000,0.025000},{0.531250,0.106250,0.050000,0.050000},{0.543750,0.106250,0.025000,0.025000},{0.543750,0.106250,0.050000,0.050000},{0.556250,0.106250,0.025000,0.025000},{0.556250,0.106250,0.050000,0.050000},{0.568750,0.106250,0.025000,0.025000},{0.568750,0.106250,0.050000,0.050000},{0.581250,0.106250,0.025000,0.025000},{0.581250,0.106250,0.050000,0.050000},{0.593750,0.106250,0.025000,0.025000},{0.593750,0.106250,0.050000,0.050000},{0.606250,0.106250,0.025000,0.025000},{0.606250,0.106250,0.050000,0.050000},{0.618750,0.106250,0.025000,0.025000},{0.618750,0.106250,0.050000,0.050000},{0.631250,0.106250,0.025000,0.025000},{0.631250,0.106250,0.050000,0.050000},{0.643750,0.106250,0.025000,0.025000},{0.643750,0.106250,0.050000,0.050000},{0.656250,0.106250,0.025000,0.025000},{0.656250,0.106250,0.050000,0.050000},{0.668750,0.106250,0.025000,0.025000},{0.668750,0.106250,0.050000,0.050000},{0.681250,0.106250,0.025000,0.025000},{0.681250,0.106250,0.050000,0.050000},{0.693750,0.106250,0.025000,0.025000},{0.693750,0.106250,0.050000,0.050000},{0.706250,0.106250,0.025000,0.025000},{0.706250,0.106250,0.050000,0.050000},{0.718750,0.106250,0.025000,0.025000},{0.718750,0.106250,0.050000,0.050000},{0.731250,0.106250,0.025000,0.025000},{0.731250,0.106250,0.050000,0.050000},{0.743750,0.106250,0.025000,0.025000},{0.743750,0.106250,0.050000,0.050000},{0.756250,0.106250,0.025000,0.025000},{0.756250,0.106250,0.050000,0.050000},{0.768750,0.106250,0.025000,0.025000},{0.768750,0.106250,0.050000,0.050000},{0.781250,0.106250,0.025000,0.025000},{0.781250,0.106250,0.050000,0.050000},{0.793750,0.106250,0.025000,0.025000},{0.793750,0.106250,0.050000,0.050000},{0.806250,0.106250,0.025000,0.025000},{0.806250,0.106250,0.050000,0.050000},{0.818750,0.106250,0.025000,0.025000},{0.818750,0.106250,0.050000,0.050000},{0.831250,0.106250,0.025000,0.025000},{0.831250,0.106250,0.050000,0.050000},{0.843750,0.106250,0.025000,0.025000},{0.843750,0.106250,0.050000,0.050000},{0.856250,0.106250,0.025000,0.025000},{0.856250,0.106250,0.050000,0.050000},{0.868750,0.106250,0.025000,0.025000},{0.868750,0.106250,0.050000,0.050000},{0.881250,0.106250,0.025000,0.025000},{0.881250,0.106250,0.050000,0.050000},{0.893750,0.106250,0.025000,0.025000},{0.893750,0.106250,0.050000,0.050000},{0.906250,0.106250,0.025000,0.025000},{0.906250,0.106250,0.050000,0.050000},{0.918750,0.106250,0.025000,0.025000},{0.918750,0.106250,0.050000,0.050000},{0.931250,0.106250,0.025000,0.025000},{0.931250,0.106250,0.050000,0.050000},{0.943750,0.106250,0.025000,0.025000},{0.943750,0.106250,0.050000,0.050000},{0.956250,0.106250,0.025000,0.025000},{0.956250,0.106250,0.050000,0.050000},{0.968750,0.106250,0.025000,0.025000},{0.968750,0.106250,0.050000,0.050000},{0.981250,0.106250,0.025000,0.025000},{0.981250,0.106250,0.050000,0.050000},{0.993750,0.106250,0.025000,0.025000},{0.993750,0.106250,0.050000,0.050000},{0.006250,0.118750,0.025000,0.025000},{0.006250,0.118750,0.050000,0.050000},{0.018750,0.118750,0.025000,0.025000},{0.018750,0.118750,0.050000,0.050000},{0.031250,0.118750,0.025000,0.025000},{0.031250,0.118750,0.050000,0.050000},{0.043750,0.118750,0.025000,0.025000},{0.043750,0.118750,0.050000,0.050000},{0.056250,0.118750,0.025000,0.025000},{0.056250,0.118750,0.050000,0.050000},{0.068750,0.118750,0.025000,0.025000},{0.068750,0.118750,0.050000,0.050000},{0.081250,0.118750,0.025000,0.025000},{0.081250,0.118750,0.050000,0.050000},{0.093750,0.118750,0.025000,0.025000},{0.093750,0.118750,0.050000,0.050000},{0.106250,0.118750,0.025000,0.025000},{0.106250,0.118750,0.050000,0.050000},{0.118750,0.118750,0.025000,0.025000},{0.118750,0.118750,0.050000,0.050000},{0.131250,0.118750,0.025000,0.025000},{0.131250,0.118750,0.050000,0.050000},{0.143750,0.118750,0.025000,0.025000},{0.143750,0.118750,0.050000,0.050000},{0.156250,0.118750,0.025000,0.025000},{0.156250,0.118750,0.050000,0.050000},{0.168750,0.118750,0.025000,0.025000},{0.168750,0.118750,0.050000,0.050000},{0.181250,0.118750,0.025000,0.025000},{0.181250,0.118750,0.050000,0.050000},{0.193750,0.118750,0.025000,0.025000},{0.193750,0.118750,0.050000,0.050000},{0.206250,0.118750,0.025000,0.025000},{0.206250,0.118750,0.050000,0.050000},{0.218750,0.118750,0.025000,0.025000},{0.218750,0.118750,0.050000,0.050000},{0.231250,0.118750,0.025000,0.025000},{0.231250,0.118750,0.050000,0.050000},{0.243750,0.118750,0.025000,0.025000},{0.243750,0.118750,0.050000,0.050000},{0.256250,0.118750,0.025000,0.025000},{0.256250,0.118750,0.050000,0.050000},{0.268750,0.118750,0.025000,0.025000},{0.268750,0.118750,0.050000,0.050000},{0.281250,0.118750,0.025000,0.025000},{0.281250,0.118750,0.050000,0.050000},{0.293750,0.118750,0.025000,0.025000},{0.293750,0.118750,0.050000,0.050000},{0.306250,0.118750,0.025000,0.025000},{0.306250,0.118750,0.050000,0.050000},{0.318750,0.118750,0.025000,0.025000},{0.318750,0.118750,0.050000,0.050000},{0.331250,0.118750,0.025000,0.025000},{0.331250,0.118750,0.050000,0.050000},{0.343750,0.118750,0.025000,0.025000},{0.343750,0.118750,0.050000,0.050000},{0.356250,0.118750,0.025000,0.025000},{0.356250,0.118750,0.050000,0.050000},{0.368750,0.118750,0.025000,0.025000},{0.368750,0.118750,0.050000,0.050000},{0.381250,0.118750,0.025000,0.025000},{0.381250,0.118750,0.050000,0.050000},{0.393750,0.118750,0.025000,0.025000},{0.393750,0.118750,0.050000,0.050000},{0.406250,0.118750,0.025000,0.025000},{0.406250,0.118750,0.050000,0.050000},{0.418750,0.118750,0.025000,0.025000},{0.418750,0.118750,0.050000,0.050000},{0.431250,0.118750,0.025000,0.025000},{0.431250,0.118750,0.050000,0.050000},{0.443750,0.118750,0.025000,0.025000},{0.443750,0.118750,0.050000,0.050000},{0.456250,0.118750,0.025000,0.025000},{0.456250,0.118750,0.050000,0.050000},{0.468750,0.118750,0.025000,0.025000},{0.468750,0.118750,0.050000,0.050000},{0.481250,0.118750,0.025000,0.025000},{0.481250,0.118750,0.050000,0.050000},{0.493750,0.118750,0.025000,0.025000},{0.493750,0.118750,0.050000,0.050000},{0.506250,0.118750,0.025000,0.025000},{0.506250,0.118750,0.050000,0.050000},{0.518750,0.118750,0.025000,0.025000},{0.518750,0.118750,0.050000,0.050000},{0.531250,0.118750,0.025000,0.025000},{0.531250,0.118750,0.050000,0.050000},{0.543750,0.118750,0.025000,0.025000},{0.543750,0.118750,0.050000,0.050000},{0.556250,0.118750,0.025000,0.025000},{0.556250,0.118750,0.050000,0.050000},{0.568750,0.118750,0.025000,0.025000},{0.568750,0.118750,0.050000,0.050000},{0.581250,0.118750,0.025000,0.025000},{0.581250,0.118750,0.050000,0.050000},{0.593750,0.118750,0.025000,0.025000},{0.593750,0.118750,0.050000,0.050000},{0.606250,0.118750,0.025000,0.025000},{0.606250,0.118750,0.050000,0.050000},{0.618750,0.118750,0.025000,0.025000},{0.618750,0.118750,0.050000,0.050000},{0.631250,0.118750,0.025000,0.025000},{0.631250,0.118750,0.050000,0.050000},{0.643750,0.118750,0.025000,0.025000},{0.643750,0.118750,0.050000,0.050000},{0.656250,0.118750,0.025000,0.025000},{0.656250,0.118750,0.050000,0.050000},{0.668750,0.118750,0.025000,0.025000},{0.668750,0.118750,0.050000,0.050000},{0.681250,0.118750,0.025000,0.025000},{0.681250,0.118750,0.050000,0.050000},{0.693750,0.118750,0.025000,0.025000},{0.693750,0.118750,0.050000,0.050000},{0.706250,0.118750,0.025000,0.025000},{0.706250,0.118750,0.050000,0.050000},{0.718750,0.118750,0.025000,0.025000},{0.718750,0.118750,0.050000,0.050000},{0.731250,0.118750,0.025000,0.025000},{0.731250,0.118750,0.050000,0.050000},{0.743750,0.118750,0.025000,0.025000},{0.743750,0.118750,0.050000,0.050000},{0.756250,0.118750,0.025000,0.025000},{0.756250,0.118750,0.050000,0.050000},{0.768750,0.118750,0.025000,0.025000},{0.768750,0.118750,0.050000,0.050000},{0.781250,0.118750,0.025000,0.025000},{0.781250,0.118750,0.050000,0.050000},{0.793750,0.118750,0.025000,0.025000},{0.793750,0.118750,0.050000,0.050000},{0.806250,0.118750,0.025000,0.025000},{0.806250,0.118750,0.050000,0.050000},{0.818750,0.118750,0.025000,0.025000},{0.818750,0.118750,0.050000,0.050000},{0.831250,0.118750,0.025000,0.025000},{0.831250,0.118750,0.050000,0.050000},{0.843750,0.118750,0.025000,0.025000},{0.843750,0.118750,0.050000,0.050000},{0.856250,0.118750,0.025000,0.025000},{0.856250,0.118750,0.050000,0.050000},{0.868750,0.118750,0.025000,0.025000},{0.868750,0.118750,0.050000,0.050000},{0.881250,0.118750,0.025000,0.025000},{0.881250,0.118750,0.050000,0.050000},{0.893750,0.118750,0.025000,0.025000},{0.893750,0.118750,0.050000,0.050000},{0.906250,0.118750,0.025000,0.025000},{0.906250,0.118750,0.050000,0.050000},{0.918750,0.118750,0.025000,0.025000},{0.918750,0.118750,0.050000,0.050000},{0.931250,0.118750,0.025000,0.025000},{0.931250,0.118750,0.050000,0.050000},{0.943750,0.118750,0.025000,0.025000},{0.943750,0.118750,0.050000,0.050000},{0.956250,0.118750,0.025000,0.025000},{0.956250,0.118750,0.050000,0.050000},{0.968750,0.118750,0.025000,0.025000},{0.968750,0.118750,0.050000,0.050000},{0.981250,0.118750,0.025000,0.025000},{0.981250,0.118750,0.050000,0.050000},{0.993750,0.118750,0.025000,0.025000},{0.993750,0.118750,0.050000,0.050000},{0.006250,0.131250,0.025000,0.025000},{0.006250,0.131250,0.050000,0.050000},{0.018750,0.131250,0.025000,0.025000},{0.018750,0.131250,0.050000,0.050000},{0.031250,0.131250,0.025000,0.025000},{0.031250,0.131250,0.050000,0.050000},{0.043750,0.131250,0.025000,0.025000},{0.043750,0.131250,0.050000,0.050000},{0.056250,0.131250,0.025000,0.025000},{0.056250,0.131250,0.050000,0.050000},{0.068750,0.131250,0.025000,0.025000},{0.068750,0.131250,0.050000,0.050000},{0.081250,0.131250,0.025000,0.025000},{0.081250,0.131250,0.050000,0.050000},{0.093750,0.131250,0.025000,0.025000},{0.093750,0.131250,0.050000,0.050000},{0.106250,0.131250,0.025000,0.025000},{0.106250,0.131250,0.050000,0.050000},{0.118750,0.131250,0.025000,0.025000},{0.118750,0.131250,0.050000,0.050000},{0.131250,0.131250,0.025000,0.025000},{0.131250,0.131250,0.050000,0.050000},{0.143750,0.131250,0.025000,0.025000},{0.143750,0.131250,0.050000,0.050000},{0.156250,0.131250,0.025000,0.025000},{0.156250,0.131250,0.050000,0.050000},{0.168750,0.131250,0.025000,0.025000},{0.168750,0.131250,0.050000,0.050000},{0.181250,0.131250,0.025000,0.025000},{0.181250,0.131250,0.050000,0.050000},{0.193750,0.131250,0.025000,0.025000},{0.193750,0.131250,0.050000,0.050000},{0.206250,0.131250,0.025000,0.025000},{0.206250,0.131250,0.050000,0.050000},{0.218750,0.131250,0.025000,0.025000},{0.218750,0.131250,0.050000,0.050000},{0.231250,0.131250,0.025000,0.025000},{0.231250,0.131250,0.050000,0.050000},{0.243750,0.131250,0.025000,0.025000},{0.243750,0.131250,0.050000,0.050000},{0.256250,0.131250,0.025000,0.025000},{0.256250,0.131250,0.050000,0.050000},{0.268750,0.131250,0.025000,0.025000},{0.268750,0.131250,0.050000,0.050000},{0.281250,0.131250,0.025000,0.025000},{0.281250,0.131250,0.050000,0.050000},{0.293750,0.131250,0.025000,0.025000},{0.293750,0.131250,0.050000,0.050000},{0.306250,0.131250,0.025000,0.025000},{0.306250,0.131250,0.050000,0.050000},{0.318750,0.131250,0.025000,0.025000},{0.318750,0.131250,0.050000,0.050000},{0.331250,0.131250,0.025000,0.025000},{0.331250,0.131250,0.050000,0.050000},{0.343750,0.131250,0.025000,0.025000},{0.343750,0.131250,0.050000,0.050000},{0.356250,0.131250,0.025000,0.025000},{0.356250,0.131250,0.050000,0.050000},{0.368750,0.131250,0.025000,0.025000},{0.368750,0.131250,0.050000,0.050000},{0.381250,0.131250,0.025000,0.025000},{0.381250,0.131250,0.050000,0.050000},{0.393750,0.131250,0.025000,0.025000},{0.393750,0.131250,0.050000,0.050000},{0.406250,0.131250,0.025000,0.025000},{0.406250,0.131250,0.050000,0.050000},{0.418750,0.131250,0.025000,0.025000},{0.418750,0.131250,0.050000,0.050000},{0.431250,0.131250,0.025000,0.025000},{0.431250,0.131250,0.050000,0.050000},{0.443750,0.131250,0.025000,0.025000},{0.443750,0.131250,0.050000,0.050000},{0.456250,0.131250,0.025000,0.025000},{0.456250,0.131250,0.050000,0.050000},{0.468750,0.131250,0.025000,0.025000},{0.468750,0.131250,0.050000,0.050000},{0.481250,0.131250,0.025000,0.025000},{0.481250,0.131250,0.050000,0.050000},{0.493750,0.131250,0.025000,0.025000},{0.493750,0.131250,0.050000,0.050000},{0.506250,0.131250,0.025000,0.025000},{0.506250,0.131250,0.050000,0.050000},{0.518750,0.131250,0.025000,0.025000},{0.518750,0.131250,0.050000,0.050000},{0.531250,0.131250,0.025000,0.025000},{0.531250,0.131250,0.050000,0.050000},{0.543750,0.131250,0.025000,0.025000},{0.543750,0.131250,0.050000,0.050000},{0.556250,0.131250,0.025000,0.025000},{0.556250,0.131250,0.050000,0.050000},{0.568750,0.131250,0.025000,0.025000},{0.568750,0.131250,0.050000,0.050000},{0.581250,0.131250,0.025000,0.025000},{0.581250,0.131250,0.050000,0.050000},{0.593750,0.131250,0.025000,0.025000},{0.593750,0.131250,0.050000,0.050000},{0.606250,0.131250,0.025000,0.025000},{0.606250,0.131250,0.050000,0.050000},{0.618750,0.131250,0.025000,0.025000},{0.618750,0.131250,0.050000,0.050000},{0.631250,0.131250,0.025000,0.025000},{0.631250,0.131250,0.050000,0.050000},{0.643750,0.131250,0.025000,0.025000},{0.643750,0.131250,0.050000,0.050000},{0.656250,0.131250,0.025000,0.025000},{0.656250,0.131250,0.050000,0.050000},{0.668750,0.131250,0.025000,0.025000},{0.668750,0.131250,0.050000,0.050000},{0.681250,0.131250,0.025000,0.025000},{0.681250,0.131250,0.050000,0.050000},{0.693750,0.131250,0.025000,0.025000},{0.693750,0.131250,0.050000,0.050000},{0.706250,0.131250,0.025000,0.025000},{0.706250,0.131250,0.050000,0.050000},{0.718750,0.131250,0.025000,0.025000},{0.718750,0.131250,0.050000,0.050000},{0.731250,0.131250,0.025000,0.025000},{0.731250,0.131250,0.050000,0.050000},{0.743750,0.131250,0.025000,0.025000},{0.743750,0.131250,0.050000,0.050000},{0.756250,0.131250,0.025000,0.025000},{0.756250,0.131250,0.050000,0.050000},{0.768750,0.131250,0.025000,0.025000},{0.768750,0.131250,0.050000,0.050000},{0.781250,0.131250,0.025000,0.025000},{0.781250,0.131250,0.050000,0.050000},{0.793750,0.131250,0.025000,0.025000},{0.793750,0.131250,0.050000,0.050000},{0.806250,0.131250,0.025000,0.025000},{0.806250,0.131250,0.050000,0.050000},{0.818750,0.131250,0.025000,0.025000},{0.818750,0.131250,0.050000,0.050000},{0.831250,0.131250,0.025000,0.025000},{0.831250,0.131250,0.050000,0.050000},{0.843750,0.131250,0.025000,0.025000},{0.843750,0.131250,0.050000,0.050000},{0.856250,0.131250,0.025000,0.025000},{0.856250,0.131250,0.050000,0.050000},{0.868750,0.131250,0.025000,0.025000},{0.868750,0.131250,0.050000,0.050000},{0.881250,0.131250,0.025000,0.025000},{0.881250,0.131250,0.050000,0.050000},{0.893750,0.131250,0.025000,0.025000},{0.893750,0.131250,0.050000,0.050000},{0.906250,0.131250,0.025000,0.025000},{0.906250,0.131250,0.050000,0.050000},{0.918750,0.131250,0.025000,0.025000},{0.918750,0.131250,0.050000,0.050000},{0.931250,0.131250,0.025000,0.025000},{0.931250,0.131250,0.050000,0.050000},{0.943750,0.131250,0.025000,0.025000},{0.943750,0.131250,0.050000,0.050000},{0.956250,0.131250,0.025000,0.025000},{0.956250,0.131250,0.050000,0.050000},{0.968750,0.131250,0.025000,0.025000},{0.968750,0.131250,0.050000,0.050000},{0.981250,0.131250,0.025000,0.025000},{0.981250,0.131250,0.050000,0.050000},{0.993750,0.131250,0.025000,0.025000},{0.993750,0.131250,0.050000,0.050000},{0.006250,0.143750,0.025000,0.025000},{0.006250,0.143750,0.050000,0.050000},{0.018750,0.143750,0.025000,0.025000},{0.018750,0.143750,0.050000,0.050000},{0.031250,0.143750,0.025000,0.025000},{0.031250,0.143750,0.050000,0.050000},{0.043750,0.143750,0.025000,0.025000},{0.043750,0.143750,0.050000,0.050000},{0.056250,0.143750,0.025000,0.025000},{0.056250,0.143750,0.050000,0.050000},{0.068750,0.143750,0.025000,0.025000},{0.068750,0.143750,0.050000,0.050000},{0.081250,0.143750,0.025000,0.025000},{0.081250,0.143750,0.050000,0.050000},{0.093750,0.143750,0.025000,0.025000},{0.093750,0.143750,0.050000,0.050000},{0.106250,0.143750,0.025000,0.025000},{0.106250,0.143750,0.050000,0.050000},{0.118750,0.143750,0.025000,0.025000},{0.118750,0.143750,0.050000,0.050000},{0.131250,0.143750,0.025000,0.025000},{0.131250,0.143750,0.050000,0.050000},{0.143750,0.143750,0.025000,0.025000},{0.143750,0.143750,0.050000,0.050000},{0.156250,0.143750,0.025000,0.025000},{0.156250,0.143750,0.050000,0.050000},{0.168750,0.143750,0.025000,0.025000},{0.168750,0.143750,0.050000,0.050000},{0.181250,0.143750,0.025000,0.025000},{0.181250,0.143750,0.050000,0.050000},{0.193750,0.143750,0.025000,0.025000},{0.193750,0.143750,0.050000,0.050000},{0.206250,0.143750,0.025000,0.025000},{0.206250,0.143750,0.050000,0.050000},{0.218750,0.143750,0.025000,0.025000},{0.218750,0.143750,0.050000,0.050000},{0.231250,0.143750,0.025000,0.025000},{0.231250,0.143750,0.050000,0.050000},{0.243750,0.143750,0.025000,0.025000},{0.243750,0.143750,0.050000,0.050000},{0.256250,0.143750,0.025000,0.025000},{0.256250,0.143750,0.050000,0.050000},{0.268750,0.143750,0.025000,0.025000},{0.268750,0.143750,0.050000,0.050000},{0.281250,0.143750,0.025000,0.025000},{0.281250,0.143750,0.050000,0.050000},{0.293750,0.143750,0.025000,0.025000},{0.293750,0.143750,0.050000,0.050000},{0.306250,0.143750,0.025000,0.025000},{0.306250,0.143750,0.050000,0.050000},{0.318750,0.143750,0.025000,0.025000},{0.318750,0.143750,0.050000,0.050000},{0.331250,0.143750,0.025000,0.025000},{0.331250,0.143750,0.050000,0.050000},{0.343750,0.143750,0.025000,0.025000},{0.343750,0.143750,0.050000,0.050000},{0.356250,0.143750,0.025000,0.025000},{0.356250,0.143750,0.050000,0.050000},{0.368750,0.143750,0.025000,0.025000},{0.368750,0.143750,0.050000,0.050000},{0.381250,0.143750,0.025000,0.025000},{0.381250,0.143750,0.050000,0.050000},{0.393750,0.143750,0.025000,0.025000},{0.393750,0.143750,0.050000,0.050000},{0.406250,0.143750,0.025000,0.025000},{0.406250,0.143750,0.050000,0.050000},{0.418750,0.143750,0.025000,0.025000},{0.418750,0.143750,0.050000,0.050000},{0.431250,0.143750,0.025000,0.025000},{0.431250,0.143750,0.050000,0.050000},{0.443750,0.143750,0.025000,0.025000},{0.443750,0.143750,0.050000,0.050000},{0.456250,0.143750,0.025000,0.025000},{0.456250,0.143750,0.050000,0.050000},{0.468750,0.143750,0.025000,0.025000},{0.468750,0.143750,0.050000,0.050000},{0.481250,0.143750,0.025000,0.025000},{0.481250,0.143750,0.050000,0.050000},{0.493750,0.143750,0.025000,0.025000},{0.493750,0.143750,0.050000,0.050000},{0.506250,0.143750,0.025000,0.025000},{0.506250,0.143750,0.050000,0.050000},{0.518750,0.143750,0.025000,0.025000},{0.518750,0.143750,0.050000,0.050000},{0.531250,0.143750,0.025000,0.025000},{0.531250,0.143750,0.050000,0.050000},{0.543750,0.143750,0.025000,0.025000},{0.543750,0.143750,0.050000,0.050000},{0.556250,0.143750,0.025000,0.025000},{0.556250,0.143750,0.050000,0.050000},{0.568750,0.143750,0.025000,0.025000},{0.568750,0.143750,0.050000,0.050000},{0.581250,0.143750,0.025000,0.025000},{0.581250,0.143750,0.050000,0.050000},{0.593750,0.143750,0.025000,0.025000},{0.593750,0.143750,0.050000,0.050000},{0.606250,0.143750,0.025000,0.025000},{0.606250,0.143750,0.050000,0.050000},{0.618750,0.143750,0.025000,0.025000},{0.618750,0.143750,0.050000,0.050000},{0.631250,0.143750,0.025000,0.025000},{0.631250,0.143750,0.050000,0.050000},{0.643750,0.143750,0.025000,0.025000},{0.643750,0.143750,0.050000,0.050000},{0.656250,0.143750,0.025000,0.025000},{0.656250,0.143750,0.050000,0.050000},{0.668750,0.143750,0.025000,0.025000},{0.668750,0.143750,0.050000,0.050000},{0.681250,0.143750,0.025000,0.025000},{0.681250,0.143750,0.050000,0.050000},{0.693750,0.143750,0.025000,0.025000},{0.693750,0.143750,0.050000,0.050000},{0.706250,0.143750,0.025000,0.025000},{0.706250,0.143750,0.050000,0.050000},{0.718750,0.143750,0.025000,0.025000},{0.718750,0.143750,0.050000,0.050000},{0.731250,0.143750,0.025000,0.025000},{0.731250,0.143750,0.050000,0.050000},{0.743750,0.143750,0.025000,0.025000},{0.743750,0.143750,0.050000,0.050000},{0.756250,0.143750,0.025000,0.025000},{0.756250,0.143750,0.050000,0.050000},{0.768750,0.143750,0.025000,0.025000},{0.768750,0.143750,0.050000,0.050000},{0.781250,0.143750,0.025000,0.025000},{0.781250,0.143750,0.050000,0.050000},{0.793750,0.143750,0.025000,0.025000},{0.793750,0.143750,0.050000,0.050000},{0.806250,0.143750,0.025000,0.025000},{0.806250,0.143750,0.050000,0.050000},{0.818750,0.143750,0.025000,0.025000},{0.818750,0.143750,0.050000,0.050000},{0.831250,0.143750,0.025000,0.025000},{0.831250,0.143750,0.050000,0.050000},{0.843750,0.143750,0.025000,0.025000},{0.843750,0.143750,0.050000,0.050000},{0.856250,0.143750,0.025000,0.025000},{0.856250,0.143750,0.050000,0.050000},{0.868750,0.143750,0.025000,0.025000},{0.868750,0.143750,0.050000,0.050000},{0.881250,0.143750,0.025000,0.025000},{0.881250,0.143750,0.050000,0.050000},{0.893750,0.143750,0.025000,0.025000},{0.893750,0.143750,0.050000,0.050000},{0.906250,0.143750,0.025000,0.025000},{0.906250,0.143750,0.050000,0.050000},{0.918750,0.143750,0.025000,0.025000},{0.918750,0.143750,0.050000,0.050000},{0.931250,0.143750,0.025000,0.025000},{0.931250,0.143750,0.050000,0.050000},{0.943750,0.143750,0.025000,0.025000},{0.943750,0.143750,0.050000,0.050000},{0.956250,0.143750,0.025000,0.025000},{0.956250,0.143750,0.050000,0.050000},{0.968750,0.143750,0.025000,0.025000},{0.968750,0.143750,0.050000,0.050000},{0.981250,0.143750,0.025000,0.025000},{0.981250,0.143750,0.050000,0.050000},{0.993750,0.143750,0.025000,0.025000},{0.993750,0.143750,0.050000,0.050000},{0.006250,0.156250,0.025000,0.025000},{0.006250,0.156250,0.050000,0.050000},{0.018750,0.156250,0.025000,0.025000},{0.018750,0.156250,0.050000,0.050000},{0.031250,0.156250,0.025000,0.025000},{0.031250,0.156250,0.050000,0.050000},{0.043750,0.156250,0.025000,0.025000},{0.043750,0.156250,0.050000,0.050000},{0.056250,0.156250,0.025000,0.025000},{0.056250,0.156250,0.050000,0.050000},{0.068750,0.156250,0.025000,0.025000},{0.068750,0.156250,0.050000,0.050000},{0.081250,0.156250,0.025000,0.025000},{0.081250,0.156250,0.050000,0.050000},{0.093750,0.156250,0.025000,0.025000},{0.093750,0.156250,0.050000,0.050000},{0.106250,0.156250,0.025000,0.025000},{0.106250,0.156250,0.050000,0.050000},{0.118750,0.156250,0.025000,0.025000},{0.118750,0.156250,0.050000,0.050000},{0.131250,0.156250,0.025000,0.025000},{0.131250,0.156250,0.050000,0.050000},{0.143750,0.156250,0.025000,0.025000},{0.143750,0.156250,0.050000,0.050000},{0.156250,0.156250,0.025000,0.025000},{0.156250,0.156250,0.050000,0.050000},{0.168750,0.156250,0.025000,0.025000},{0.168750,0.156250,0.050000,0.050000},{0.181250,0.156250,0.025000,0.025000},{0.181250,0.156250,0.050000,0.050000},{0.193750,0.156250,0.025000,0.025000},{0.193750,0.156250,0.050000,0.050000},{0.206250,0.156250,0.025000,0.025000},{0.206250,0.156250,0.050000,0.050000},{0.218750,0.156250,0.025000,0.025000},{0.218750,0.156250,0.050000,0.050000},{0.231250,0.156250,0.025000,0.025000},{0.231250,0.156250,0.050000,0.050000},{0.243750,0.156250,0.025000,0.025000},{0.243750,0.156250,0.050000,0.050000},{0.256250,0.156250,0.025000,0.025000},{0.256250,0.156250,0.050000,0.050000},{0.268750,0.156250,0.025000,0.025000},{0.268750,0.156250,0.050000,0.050000},{0.281250,0.156250,0.025000,0.025000},{0.281250,0.156250,0.050000,0.050000},{0.293750,0.156250,0.025000,0.025000},{0.293750,0.156250,0.050000,0.050000},{0.306250,0.156250,0.025000,0.025000},{0.306250,0.156250,0.050000,0.050000},{0.318750,0.156250,0.025000,0.025000},{0.318750,0.156250,0.050000,0.050000},{0.331250,0.156250,0.025000,0.025000},{0.331250,0.156250,0.050000,0.050000},{0.343750,0.156250,0.025000,0.025000},{0.343750,0.156250,0.050000,0.050000},{0.356250,0.156250,0.025000,0.025000},{0.356250,0.156250,0.050000,0.050000},{0.368750,0.156250,0.025000,0.025000},{0.368750,0.156250,0.050000,0.050000},{0.381250,0.156250,0.025000,0.025000},{0.381250,0.156250,0.050000,0.050000},{0.393750,0.156250,0.025000,0.025000},{0.393750,0.156250,0.050000,0.050000},{0.406250,0.156250,0.025000,0.025000},{0.406250,0.156250,0.050000,0.050000},{0.418750,0.156250,0.025000,0.025000},{0.418750,0.156250,0.050000,0.050000},{0.431250,0.156250,0.025000,0.025000},{0.431250,0.156250,0.050000,0.050000},{0.443750,0.156250,0.025000,0.025000},{0.443750,0.156250,0.050000,0.050000},{0.456250,0.156250,0.025000,0.025000},{0.456250,0.156250,0.050000,0.050000},{0.468750,0.156250,0.025000,0.025000},{0.468750,0.156250,0.050000,0.050000},{0.481250,0.156250,0.025000,0.025000},{0.481250,0.156250,0.050000,0.050000},{0.493750,0.156250,0.025000,0.025000},{0.493750,0.156250,0.050000,0.050000},{0.506250,0.156250,0.025000,0.025000},{0.506250,0.156250,0.050000,0.050000},{0.518750,0.156250,0.025000,0.025000},{0.518750,0.156250,0.050000,0.050000},{0.531250,0.156250,0.025000,0.025000},{0.531250,0.156250,0.050000,0.050000},{0.543750,0.156250,0.025000,0.025000},{0.543750,0.156250,0.050000,0.050000},{0.556250,0.156250,0.025000,0.025000},{0.556250,0.156250,0.050000,0.050000},{0.568750,0.156250,0.025000,0.025000},{0.568750,0.156250,0.050000,0.050000},{0.581250,0.156250,0.025000,0.025000},{0.581250,0.156250,0.050000,0.050000},{0.593750,0.156250,0.025000,0.025000},{0.593750,0.156250,0.050000,0.050000},{0.606250,0.156250,0.025000,0.025000},{0.606250,0.156250,0.050000,0.050000},{0.618750,0.156250,0.025000,0.025000},{0.618750,0.156250,0.050000,0.050000},{0.631250,0.156250,0.025000,0.025000},{0.631250,0.156250,0.050000,0.050000},{0.643750,0.156250,0.025000,0.025000},{0.643750,0.156250,0.050000,0.050000},{0.656250,0.156250,0.025000,0.025000},{0.656250,0.156250,0.050000,0.050000},{0.668750,0.156250,0.025000,0.025000},{0.668750,0.156250,0.050000,0.050000},{0.681250,0.156250,0.025000,0.025000},{0.681250,0.156250,0.050000,0.050000},{0.693750,0.156250,0.025000,0.025000},{0.693750,0.156250,0.050000,0.050000},{0.706250,0.156250,0.025000,0.025000},{0.706250,0.156250,0.050000,0.050000},{0.718750,0.156250,0.025000,0.025000},{0.718750,0.156250,0.050000,0.050000},{0.731250,0.156250,0.025000,0.025000},{0.731250,0.156250,0.050000,0.050000},{0.743750,0.156250,0.025000,0.025000},{0.743750,0.156250,0.050000,0.050000},{0.756250,0.156250,0.025000,0.025000},{0.756250,0.156250,0.050000,0.050000},{0.768750,0.156250,0.025000,0.025000},{0.768750,0.156250,0.050000,0.050000},{0.781250,0.156250,0.025000,0.025000},{0.781250,0.156250,0.050000,0.050000},{0.793750,0.156250,0.025000,0.025000},{0.793750,0.156250,0.050000,0.050000},{0.806250,0.156250,0.025000,0.025000},{0.806250,0.156250,0.050000,0.050000},{0.818750,0.156250,0.025000,0.025000},{0.818750,0.156250,0.050000,0.050000},{0.831250,0.156250,0.025000,0.025000},{0.831250,0.156250,0.050000,0.050000},{0.843750,0.156250,0.025000,0.025000},{0.843750,0.156250,0.050000,0.050000},{0.856250,0.156250,0.025000,0.025000},{0.856250,0.156250,0.050000,0.050000},{0.868750,0.156250,0.025000,0.025000},{0.868750,0.156250,0.050000,0.050000},{0.881250,0.156250,0.025000,0.025000},{0.881250,0.156250,0.050000,0.050000},{0.893750,0.156250,0.025000,0.025000},{0.893750,0.156250,0.050000,0.050000},{0.906250,0.156250,0.025000,0.025000},{0.906250,0.156250,0.050000,0.050000},{0.918750,0.156250,0.025000,0.025000},{0.918750,0.156250,0.050000,0.050000},{0.931250,0.156250,0.025000,0.025000},{0.931250,0.156250,0.050000,0.050000},{0.943750,0.156250,0.025000,0.025000},{0.943750,0.156250,0.050000,0.050000},{0.956250,0.156250,0.025000,0.025000},{0.956250,0.156250,0.050000,0.050000},{0.968750,0.156250,0.025000,0.025000},{0.968750,0.156250,0.050000,0.050000},{0.981250,0.156250,0.025000,0.025000},{0.981250,0.156250,0.050000,0.050000},{0.993750,0.156250,0.025000,0.025000},{0.993750,0.156250,0.050000,0.050000},{0.006250,0.168750,0.025000,0.025000},{0.006250,0.168750,0.050000,0.050000},{0.018750,0.168750,0.025000,0.025000},{0.018750,0.168750,0.050000,0.050000},{0.031250,0.168750,0.025000,0.025000},{0.031250,0.168750,0.050000,0.050000},{0.043750,0.168750,0.025000,0.025000},{0.043750,0.168750,0.050000,0.050000},{0.056250,0.168750,0.025000,0.025000},{0.056250,0.168750,0.050000,0.050000},{0.068750,0.168750,0.025000,0.025000},{0.068750,0.168750,0.050000,0.050000},{0.081250,0.168750,0.025000,0.025000},{0.081250,0.168750,0.050000,0.050000},{0.093750,0.168750,0.025000,0.025000},{0.093750,0.168750,0.050000,0.050000},{0.106250,0.168750,0.025000,0.025000},{0.106250,0.168750,0.050000,0.050000},{0.118750,0.168750,0.025000,0.025000},{0.118750,0.168750,0.050000,0.050000},{0.131250,0.168750,0.025000,0.025000},{0.131250,0.168750,0.050000,0.050000},{0.143750,0.168750,0.025000,0.025000},{0.143750,0.168750,0.050000,0.050000},{0.156250,0.168750,0.025000,0.025000},{0.156250,0.168750,0.050000,0.050000},{0.168750,0.168750,0.025000,0.025000},{0.168750,0.168750,0.050000,0.050000},{0.181250,0.168750,0.025000,0.025000},{0.181250,0.168750,0.050000,0.050000},{0.193750,0.168750,0.025000,0.025000},{0.193750,0.168750,0.050000,0.050000},{0.206250,0.168750,0.025000,0.025000},{0.206250,0.168750,0.050000,0.050000},{0.218750,0.168750,0.025000,0.025000},{0.218750,0.168750,0.050000,0.050000},{0.231250,0.168750,0.025000,0.025000},{0.231250,0.168750,0.050000,0.050000},{0.243750,0.168750,0.025000,0.025000},{0.243750,0.168750,0.050000,0.050000},{0.256250,0.168750,0.025000,0.025000},{0.256250,0.168750,0.050000,0.050000},{0.268750,0.168750,0.025000,0.025000},{0.268750,0.168750,0.050000,0.050000},{0.281250,0.168750,0.025000,0.025000},{0.281250,0.168750,0.050000,0.050000},{0.293750,0.168750,0.025000,0.025000},{0.293750,0.168750,0.050000,0.050000},{0.306250,0.168750,0.025000,0.025000},{0.306250,0.168750,0.050000,0.050000},{0.318750,0.168750,0.025000,0.025000},{0.318750,0.168750,0.050000,0.050000},{0.331250,0.168750,0.025000,0.025000},{0.331250,0.168750,0.050000,0.050000},{0.343750,0.168750,0.025000,0.025000},{0.343750,0.168750,0.050000,0.050000},{0.356250,0.168750,0.025000,0.025000},{0.356250,0.168750,0.050000,0.050000},{0.368750,0.168750,0.025000,0.025000},{0.368750,0.168750,0.050000,0.050000},{0.381250,0.168750,0.025000,0.025000},{0.381250,0.168750,0.050000,0.050000},{0.393750,0.168750,0.025000,0.025000},{0.393750,0.168750,0.050000,0.050000},{0.406250,0.168750,0.025000,0.025000},{0.406250,0.168750,0.050000,0.050000},{0.418750,0.168750,0.025000,0.025000},{0.418750,0.168750,0.050000,0.050000},{0.431250,0.168750,0.025000,0.025000},{0.431250,0.168750,0.050000,0.050000},{0.443750,0.168750,0.025000,0.025000},{0.443750,0.168750,0.050000,0.050000},{0.456250,0.168750,0.025000,0.025000},{0.456250,0.168750,0.050000,0.050000},{0.468750,0.168750,0.025000,0.025000},{0.468750,0.168750,0.050000,0.050000},{0.481250,0.168750,0.025000,0.025000},{0.481250,0.168750,0.050000,0.050000},{0.493750,0.168750,0.025000,0.025000},{0.493750,0.168750,0.050000,0.050000},{0.506250,0.168750,0.025000,0.025000},{0.506250,0.168750,0.050000,0.050000},{0.518750,0.168750,0.025000,0.025000},{0.518750,0.168750,0.050000,0.050000},{0.531250,0.168750,0.025000,0.025000},{0.531250,0.168750,0.050000,0.050000},{0.543750,0.168750,0.025000,0.025000},{0.543750,0.168750,0.050000,0.050000},{0.556250,0.168750,0.025000,0.025000},{0.556250,0.168750,0.050000,0.050000},{0.568750,0.168750,0.025000,0.025000},{0.568750,0.168750,0.050000,0.050000},{0.581250,0.168750,0.025000,0.025000},{0.581250,0.168750,0.050000,0.050000},{0.593750,0.168750,0.025000,0.025000},{0.593750,0.168750,0.050000,0.050000},{0.606250,0.168750,0.025000,0.025000},{0.606250,0.168750,0.050000,0.050000},{0.618750,0.168750,0.025000,0.025000},{0.618750,0.168750,0.050000,0.050000},{0.631250,0.168750,0.025000,0.025000},{0.631250,0.168750,0.050000,0.050000},{0.643750,0.168750,0.025000,0.025000},{0.643750,0.168750,0.050000,0.050000},{0.656250,0.168750,0.025000,0.025000},{0.656250,0.168750,0.050000,0.050000},{0.668750,0.168750,0.025000,0.025000},{0.668750,0.168750,0.050000,0.050000},{0.681250,0.168750,0.025000,0.025000},{0.681250,0.168750,0.050000,0.050000},{0.693750,0.168750,0.025000,0.025000},{0.693750,0.168750,0.050000,0.050000},{0.706250,0.168750,0.025000,0.025000},{0.706250,0.168750,0.050000,0.050000},{0.718750,0.168750,0.025000,0.025000},{0.718750,0.168750,0.050000,0.050000},{0.731250,0.168750,0.025000,0.025000},{0.731250,0.168750,0.050000,0.050000},{0.743750,0.168750,0.025000,0.025000},{0.743750,0.168750,0.050000,0.050000},{0.756250,0.168750,0.025000,0.025000},{0.756250,0.168750,0.050000,0.050000},{0.768750,0.168750,0.025000,0.025000},{0.768750,0.168750,0.050000,0.050000},{0.781250,0.168750,0.025000,0.025000},{0.781250,0.168750,0.050000,0.050000},{0.793750,0.168750,0.025000,0.025000},{0.793750,0.168750,0.050000,0.050000},{0.806250,0.168750,0.025000,0.025000},{0.806250,0.168750,0.050000,0.050000},{0.818750,0.168750,0.025000,0.025000},{0.818750,0.168750,0.050000,0.050000},{0.831250,0.168750,0.025000,0.025000},{0.831250,0.168750,0.050000,0.050000},{0.843750,0.168750,0.025000,0.025000},{0.843750,0.168750,0.050000,0.050000},{0.856250,0.168750,0.025000,0.025000},{0.856250,0.168750,0.050000,0.050000},{0.868750,0.168750,0.025000,0.025000},{0.868750,0.168750,0.050000,0.050000},{0.881250,0.168750,0.025000,0.025000},{0.881250,0.168750,0.050000,0.050000},{0.893750,0.168750,0.025000,0.025000},{0.893750,0.168750,0.050000,0.050000},{0.906250,0.168750,0.025000,0.025000},{0.906250,0.168750,0.050000,0.050000},{0.918750,0.168750,0.025000,0.025000},{0.918750,0.168750,0.050000,0.050000},{0.931250,0.168750,0.025000,0.025000},{0.931250,0.168750,0.050000,0.050000},{0.943750,0.168750,0.025000,0.025000},{0.943750,0.168750,0.050000,0.050000},{0.956250,0.168750,0.025000,0.025000},{0.956250,0.168750,0.050000,0.050000},{0.968750,0.168750,0.025000,0.025000},{0.968750,0.168750,0.050000,0.050000},{0.981250,0.168750,0.025000,0.025000},{0.981250,0.168750,0.050000,0.050000},{0.993750,0.168750,0.025000,0.025000},{0.993750,0.168750,0.050000,0.050000},{0.006250,0.181250,0.025000,0.025000},{0.006250,0.181250,0.050000,0.050000},{0.018750,0.181250,0.025000,0.025000},{0.018750,0.181250,0.050000,0.050000},{0.031250,0.181250,0.025000,0.025000},{0.031250,0.181250,0.050000,0.050000},{0.043750,0.181250,0.025000,0.025000},{0.043750,0.181250,0.050000,0.050000},{0.056250,0.181250,0.025000,0.025000},{0.056250,0.181250,0.050000,0.050000},{0.068750,0.181250,0.025000,0.025000},{0.068750,0.181250,0.050000,0.050000},{0.081250,0.181250,0.025000,0.025000},{0.081250,0.181250,0.050000,0.050000},{0.093750,0.181250,0.025000,0.025000},{0.093750,0.181250,0.050000,0.050000},{0.106250,0.181250,0.025000,0.025000},{0.106250,0.181250,0.050000,0.050000},{0.118750,0.181250,0.025000,0.025000},{0.118750,0.181250,0.050000,0.050000},{0.131250,0.181250,0.025000,0.025000},{0.131250,0.181250,0.050000,0.050000},{0.143750,0.181250,0.025000,0.025000},{0.143750,0.181250,0.050000,0.050000},{0.156250,0.181250,0.025000,0.025000},{0.156250,0.181250,0.050000,0.050000},{0.168750,0.181250,0.025000,0.025000},{0.168750,0.181250,0.050000,0.050000},{0.181250,0.181250,0.025000,0.025000},{0.181250,0.181250,0.050000,0.050000},{0.193750,0.181250,0.025000,0.025000},{0.193750,0.181250,0.050000,0.050000},{0.206250,0.181250,0.025000,0.025000},{0.206250,0.181250,0.050000,0.050000},{0.218750,0.181250,0.025000,0.025000},{0.218750,0.181250,0.050000,0.050000},{0.231250,0.181250,0.025000,0.025000},{0.231250,0.181250,0.050000,0.050000},{0.243750,0.181250,0.025000,0.025000},{0.243750,0.181250,0.050000,0.050000},{0.256250,0.181250,0.025000,0.025000},{0.256250,0.181250,0.050000,0.050000},{0.268750,0.181250,0.025000,0.025000},{0.268750,0.181250,0.050000,0.050000},{0.281250,0.181250,0.025000,0.025000},{0.281250,0.181250,0.050000,0.050000},{0.293750,0.181250,0.025000,0.025000},{0.293750,0.181250,0.050000,0.050000},{0.306250,0.181250,0.025000,0.025000},{0.306250,0.181250,0.050000,0.050000},{0.318750,0.181250,0.025000,0.025000},{0.318750,0.181250,0.050000,0.050000},{0.331250,0.181250,0.025000,0.025000},{0.331250,0.181250,0.050000,0.050000},{0.343750,0.181250,0.025000,0.025000},{0.343750,0.181250,0.050000,0.050000},{0.356250,0.181250,0.025000,0.025000},{0.356250,0.181250,0.050000,0.050000},{0.368750,0.181250,0.025000,0.025000},{0.368750,0.181250,0.050000,0.050000},{0.381250,0.181250,0.025000,0.025000},{0.381250,0.181250,0.050000,0.050000},{0.393750,0.181250,0.025000,0.025000},{0.393750,0.181250,0.050000,0.050000},{0.406250,0.181250,0.025000,0.025000},{0.406250,0.181250,0.050000,0.050000},{0.418750,0.181250,0.025000,0.025000},{0.418750,0.181250,0.050000,0.050000},{0.431250,0.181250,0.025000,0.025000},{0.431250,0.181250,0.050000,0.050000},{0.443750,0.181250,0.025000,0.025000},{0.443750,0.181250,0.050000,0.050000},{0.456250,0.181250,0.025000,0.025000},{0.456250,0.181250,0.050000,0.050000},{0.468750,0.181250,0.025000,0.025000},{0.468750,0.181250,0.050000,0.050000},{0.481250,0.181250,0.025000,0.025000},{0.481250,0.181250,0.050000,0.050000},{0.493750,0.181250,0.025000,0.025000},{0.493750,0.181250,0.050000,0.050000},{0.506250,0.181250,0.025000,0.025000},{0.506250,0.181250,0.050000,0.050000},{0.518750,0.181250,0.025000,0.025000},{0.518750,0.181250,0.050000,0.050000},{0.531250,0.181250,0.025000,0.025000},{0.531250,0.181250,0.050000,0.050000},{0.543750,0.181250,0.025000,0.025000},{0.543750,0.181250,0.050000,0.050000},{0.556250,0.181250,0.025000,0.025000},{0.556250,0.181250,0.050000,0.050000},{0.568750,0.181250,0.025000,0.025000},{0.568750,0.181250,0.050000,0.050000},{0.581250,0.181250,0.025000,0.025000},{0.581250,0.181250,0.050000,0.050000},{0.593750,0.181250,0.025000,0.025000},{0.593750,0.181250,0.050000,0.050000},{0.606250,0.181250,0.025000,0.025000},{0.606250,0.181250,0.050000,0.050000},{0.618750,0.181250,0.025000,0.025000},{0.618750,0.181250,0.050000,0.050000},{0.631250,0.181250,0.025000,0.025000},{0.631250,0.181250,0.050000,0.050000},{0.643750,0.181250,0.025000,0.025000},{0.643750,0.181250,0.050000,0.050000},{0.656250,0.181250,0.025000,0.025000},{0.656250,0.181250,0.050000,0.050000},{0.668750,0.181250,0.025000,0.025000},{0.668750,0.181250,0.050000,0.050000},{0.681250,0.181250,0.025000,0.025000},{0.681250,0.181250,0.050000,0.050000},{0.693750,0.181250,0.025000,0.025000},{0.693750,0.181250,0.050000,0.050000},{0.706250,0.181250,0.025000,0.025000},{0.706250,0.181250,0.050000,0.050000},{0.718750,0.181250,0.025000,0.025000},{0.718750,0.181250,0.050000,0.050000},{0.731250,0.181250,0.025000,0.025000},{0.731250,0.181250,0.050000,0.050000},{0.743750,0.181250,0.025000,0.025000},{0.743750,0.181250,0.050000,0.050000},{0.756250,0.181250,0.025000,0.025000},{0.756250,0.181250,0.050000,0.050000},{0.768750,0.181250,0.025000,0.025000},{0.768750,0.181250,0.050000,0.050000},{0.781250,0.181250,0.025000,0.025000},{0.781250,0.181250,0.050000,0.050000},{0.793750,0.181250,0.025000,0.025000},{0.793750,0.181250,0.050000,0.050000},{0.806250,0.181250,0.025000,0.025000},{0.806250,0.181250,0.050000,0.050000},{0.818750,0.181250,0.025000,0.025000},{0.818750,0.181250,0.050000,0.050000},{0.831250,0.181250,0.025000,0.025000},{0.831250,0.181250,0.050000,0.050000},{0.843750,0.181250,0.025000,0.025000},{0.843750,0.181250,0.050000,0.050000},{0.856250,0.181250,0.025000,0.025000},{0.856250,0.181250,0.050000,0.050000},{0.868750,0.181250,0.025000,0.025000},{0.868750,0.181250,0.050000,0.050000},{0.881250,0.181250,0.025000,0.025000},{0.881250,0.181250,0.050000,0.050000},{0.893750,0.181250,0.025000,0.025000},{0.893750,0.181250,0.050000,0.050000},{0.906250,0.181250,0.025000,0.025000},{0.906250,0.181250,0.050000,0.050000},{0.918750,0.181250,0.025000,0.025000},{0.918750,0.181250,0.050000,0.050000},{0.931250,0.181250,0.025000,0.025000},{0.931250,0.181250,0.050000,0.050000},{0.943750,0.181250,0.025000,0.025000},{0.943750,0.181250,0.050000,0.050000},{0.956250,0.181250,0.025000,0.025000},{0.956250,0.181250,0.050000,0.050000},{0.968750,0.181250,0.025000,0.025000},{0.968750,0.181250,0.050000,0.050000},{0.981250,0.181250,0.025000,0.025000},{0.981250,0.181250,0.050000,0.050000},{0.993750,0.181250,0.025000,0.025000},{0.993750,0.181250,0.050000,0.050000},{0.006250,0.193750,0.025000,0.025000},{0.006250,0.193750,0.050000,0.050000},{0.018750,0.193750,0.025000,0.025000},{0.018750,0.193750,0.050000,0.050000},{0.031250,0.193750,0.025000,0.025000},{0.031250,0.193750,0.050000,0.050000},{0.043750,0.193750,0.025000,0.025000},{0.043750,0.193750,0.050000,0.050000},{0.056250,0.193750,0.025000,0.025000},{0.056250,0.193750,0.050000,0.050000},{0.068750,0.193750,0.025000,0.025000},{0.068750,0.193750,0.050000,0.050000},{0.081250,0.193750,0.025000,0.025000},{0.081250,0.193750,0.050000,0.050000},{0.093750,0.193750,0.025000,0.025000},{0.093750,0.193750,0.050000,0.050000},{0.106250,0.193750,0.025000,0.025000},{0.106250,0.193750,0.050000,0.050000},{0.118750,0.193750,0.025000,0.025000},{0.118750,0.193750,0.050000,0.050000},{0.131250,0.193750,0.025000,0.025000},{0.131250,0.193750,0.050000,0.050000},{0.143750,0.193750,0.025000,0.025000},{0.143750,0.193750,0.050000,0.050000},{0.156250,0.193750,0.025000,0.025000},{0.156250,0.193750,0.050000,0.050000},{0.168750,0.193750,0.025000,0.025000},{0.168750,0.193750,0.050000,0.050000},{0.181250,0.193750,0.025000,0.025000},{0.181250,0.193750,0.050000,0.050000},{0.193750,0.193750,0.025000,0.025000},{0.193750,0.193750,0.050000,0.050000},{0.206250,0.193750,0.025000,0.025000},{0.206250,0.193750,0.050000,0.050000},{0.218750,0.193750,0.025000,0.025000},{0.218750,0.193750,0.050000,0.050000},{0.231250,0.193750,0.025000,0.025000},{0.231250,0.193750,0.050000,0.050000},{0.243750,0.193750,0.025000,0.025000},{0.243750,0.193750,0.050000,0.050000},{0.256250,0.193750,0.025000,0.025000},{0.256250,0.193750,0.050000,0.050000},{0.268750,0.193750,0.025000,0.025000},{0.268750,0.193750,0.050000,0.050000},{0.281250,0.193750,0.025000,0.025000},{0.281250,0.193750,0.050000,0.050000},{0.293750,0.193750,0.025000,0.025000},{0.293750,0.193750,0.050000,0.050000},{0.306250,0.193750,0.025000,0.025000},{0.306250,0.193750,0.050000,0.050000},{0.318750,0.193750,0.025000,0.025000},{0.318750,0.193750,0.050000,0.050000},{0.331250,0.193750,0.025000,0.025000},{0.331250,0.193750,0.050000,0.050000},{0.343750,0.193750,0.025000,0.025000},{0.343750,0.193750,0.050000,0.050000},{0.356250,0.193750,0.025000,0.025000},{0.356250,0.193750,0.050000,0.050000},{0.368750,0.193750,0.025000,0.025000},{0.368750,0.193750,0.050000,0.050000},{0.381250,0.193750,0.025000,0.025000},{0.381250,0.193750,0.050000,0.050000},{0.393750,0.193750,0.025000,0.025000},{0.393750,0.193750,0.050000,0.050000},{0.406250,0.193750,0.025000,0.025000},{0.406250,0.193750,0.050000,0.050000},{0.418750,0.193750,0.025000,0.025000},{0.418750,0.193750,0.050000,0.050000},{0.431250,0.193750,0.025000,0.025000},{0.431250,0.193750,0.050000,0.050000},{0.443750,0.193750,0.025000,0.025000},{0.443750,0.193750,0.050000,0.050000},{0.456250,0.193750,0.025000,0.025000},{0.456250,0.193750,0.050000,0.050000},{0.468750,0.193750,0.025000,0.025000},{0.468750,0.193750,0.050000,0.050000},{0.481250,0.193750,0.025000,0.025000},{0.481250,0.193750,0.050000,0.050000},{0.493750,0.193750,0.025000,0.025000},{0.493750,0.193750,0.050000,0.050000},{0.506250,0.193750,0.025000,0.025000},{0.506250,0.193750,0.050000,0.050000},{0.518750,0.193750,0.025000,0.025000},{0.518750,0.193750,0.050000,0.050000},{0.531250,0.193750,0.025000,0.025000},{0.531250,0.193750,0.050000,0.050000},{0.543750,0.193750,0.025000,0.025000},{0.543750,0.193750,0.050000,0.050000},{0.556250,0.193750,0.025000,0.025000},{0.556250,0.193750,0.050000,0.050000},{0.568750,0.193750,0.025000,0.025000},{0.568750,0.193750,0.050000,0.050000},{0.581250,0.193750,0.025000,0.025000},{0.581250,0.193750,0.050000,0.050000},{0.593750,0.193750,0.025000,0.025000},{0.593750,0.193750,0.050000,0.050000},{0.606250,0.193750,0.025000,0.025000},{0.606250,0.193750,0.050000,0.050000},{0.618750,0.193750,0.025000,0.025000},{0.618750,0.193750,0.050000,0.050000},{0.631250,0.193750,0.025000,0.025000},{0.631250,0.193750,0.050000,0.050000},{0.643750,0.193750,0.025000,0.025000},{0.643750,0.193750,0.050000,0.050000},{0.656250,0.193750,0.025000,0.025000},{0.656250,0.193750,0.050000,0.050000},{0.668750,0.193750,0.025000,0.025000},{0.668750,0.193750,0.050000,0.050000},{0.681250,0.193750,0.025000,0.025000},{0.681250,0.193750,0.050000,0.050000},{0.693750,0.193750,0.025000,0.025000},{0.693750,0.193750,0.050000,0.050000},{0.706250,0.193750,0.025000,0.025000},{0.706250,0.193750,0.050000,0.050000},{0.718750,0.193750,0.025000,0.025000},{0.718750,0.193750,0.050000,0.050000},{0.731250,0.193750,0.025000,0.025000},{0.731250,0.193750,0.050000,0.050000},{0.743750,0.193750,0.025000,0.025000},{0.743750,0.193750,0.050000,0.050000},{0.756250,0.193750,0.025000,0.025000},{0.756250,0.193750,0.050000,0.050000},{0.768750,0.193750,0.025000,0.025000},{0.768750,0.193750,0.050000,0.050000},{0.781250,0.193750,0.025000,0.025000},{0.781250,0.193750,0.050000,0.050000},{0.793750,0.193750,0.025000,0.025000},{0.793750,0.193750,0.050000,0.050000},{0.806250,0.193750,0.025000,0.025000},{0.806250,0.193750,0.050000,0.050000},{0.818750,0.193750,0.025000,0.025000},{0.818750,0.193750,0.050000,0.050000},{0.831250,0.193750,0.025000,0.025000},{0.831250,0.193750,0.050000,0.050000},{0.843750,0.193750,0.025000,0.025000},{0.843750,0.193750,0.050000,0.050000},{0.856250,0.193750,0.025000,0.025000},{0.856250,0.193750,0.050000,0.050000},{0.868750,0.193750,0.025000,0.025000},{0.868750,0.193750,0.050000,0.050000},{0.881250,0.193750,0.025000,0.025000},{0.881250,0.193750,0.050000,0.050000},{0.893750,0.193750,0.025000,0.025000},{0.893750,0.193750,0.050000,0.050000},{0.906250,0.193750,0.025000,0.025000},{0.906250,0.193750,0.050000,0.050000},{0.918750,0.193750,0.025000,0.025000},{0.918750,0.193750,0.050000,0.050000},{0.931250,0.193750,0.025000,0.025000},{0.931250,0.193750,0.050000,0.050000},{0.943750,0.193750,0.025000,0.025000},{0.943750,0.193750,0.050000,0.050000},{0.956250,0.193750,0.025000,0.025000},{0.956250,0.193750,0.050000,0.050000},{0.968750,0.193750,0.025000,0.025000},{0.968750,0.193750,0.050000,0.050000},{0.981250,0.193750,0.025000,0.025000},{0.981250,0.193750,0.050000,0.050000},{0.993750,0.193750,0.025000,0.025000},{0.993750,0.193750,0.050000,0.050000},{0.006250,0.206250,0.025000,0.025000},{0.006250,0.206250,0.050000,0.050000},{0.018750,0.206250,0.025000,0.025000},{0.018750,0.206250,0.050000,0.050000},{0.031250,0.206250,0.025000,0.025000},{0.031250,0.206250,0.050000,0.050000},{0.043750,0.206250,0.025000,0.025000},{0.043750,0.206250,0.050000,0.050000},{0.056250,0.206250,0.025000,0.025000},{0.056250,0.206250,0.050000,0.050000},{0.068750,0.206250,0.025000,0.025000},{0.068750,0.206250,0.050000,0.050000},{0.081250,0.206250,0.025000,0.025000},{0.081250,0.206250,0.050000,0.050000},{0.093750,0.206250,0.025000,0.025000},{0.093750,0.206250,0.050000,0.050000},{0.106250,0.206250,0.025000,0.025000},{0.106250,0.206250,0.050000,0.050000},{0.118750,0.206250,0.025000,0.025000},{0.118750,0.206250,0.050000,0.050000},{0.131250,0.206250,0.025000,0.025000},{0.131250,0.206250,0.050000,0.050000},{0.143750,0.206250,0.025000,0.025000},{0.143750,0.206250,0.050000,0.050000},{0.156250,0.206250,0.025000,0.025000},{0.156250,0.206250,0.050000,0.050000},{0.168750,0.206250,0.025000,0.025000},{0.168750,0.206250,0.050000,0.050000},{0.181250,0.206250,0.025000,0.025000},{0.181250,0.206250,0.050000,0.050000},{0.193750,0.206250,0.025000,0.025000},{0.193750,0.206250,0.050000,0.050000},{0.206250,0.206250,0.025000,0.025000},{0.206250,0.206250,0.050000,0.050000},{0.218750,0.206250,0.025000,0.025000},{0.218750,0.206250,0.050000,0.050000},{0.231250,0.206250,0.025000,0.025000},{0.231250,0.206250,0.050000,0.050000},{0.243750,0.206250,0.025000,0.025000},{0.243750,0.206250,0.050000,0.050000},{0.256250,0.206250,0.025000,0.025000},{0.256250,0.206250,0.050000,0.050000},{0.268750,0.206250,0.025000,0.025000},{0.268750,0.206250,0.050000,0.050000},{0.281250,0.206250,0.025000,0.025000},{0.281250,0.206250,0.050000,0.050000},{0.293750,0.206250,0.025000,0.025000},{0.293750,0.206250,0.050000,0.050000},{0.306250,0.206250,0.025000,0.025000},{0.306250,0.206250,0.050000,0.050000},{0.318750,0.206250,0.025000,0.025000},{0.318750,0.206250,0.050000,0.050000},{0.331250,0.206250,0.025000,0.025000},{0.331250,0.206250,0.050000,0.050000},{0.343750,0.206250,0.025000,0.025000},{0.343750,0.206250,0.050000,0.050000},{0.356250,0.206250,0.025000,0.025000},{0.356250,0.206250,0.050000,0.050000},{0.368750,0.206250,0.025000,0.025000},{0.368750,0.206250,0.050000,0.050000},{0.381250,0.206250,0.025000,0.025000},{0.381250,0.206250,0.050000,0.050000},{0.393750,0.206250,0.025000,0.025000},{0.393750,0.206250,0.050000,0.050000},{0.406250,0.206250,0.025000,0.025000},{0.406250,0.206250,0.050000,0.050000},{0.418750,0.206250,0.025000,0.025000},{0.418750,0.206250,0.050000,0.050000},{0.431250,0.206250,0.025000,0.025000},{0.431250,0.206250,0.050000,0.050000},{0.443750,0.206250,0.025000,0.025000},{0.443750,0.206250,0.050000,0.050000},{0.456250,0.206250,0.025000,0.025000},{0.456250,0.206250,0.050000,0.050000},{0.468750,0.206250,0.025000,0.025000},{0.468750,0.206250,0.050000,0.050000},{0.481250,0.206250,0.025000,0.025000},{0.481250,0.206250,0.050000,0.050000},{0.493750,0.206250,0.025000,0.025000},{0.493750,0.206250,0.050000,0.050000},{0.506250,0.206250,0.025000,0.025000},{0.506250,0.206250,0.050000,0.050000},{0.518750,0.206250,0.025000,0.025000},{0.518750,0.206250,0.050000,0.050000},{0.531250,0.206250,0.025000,0.025000},{0.531250,0.206250,0.050000,0.050000},{0.543750,0.206250,0.025000,0.025000},{0.543750,0.206250,0.050000,0.050000},{0.556250,0.206250,0.025000,0.025000},{0.556250,0.206250,0.050000,0.050000},{0.568750,0.206250,0.025000,0.025000},{0.568750,0.206250,0.050000,0.050000},{0.581250,0.206250,0.025000,0.025000},{0.581250,0.206250,0.050000,0.050000},{0.593750,0.206250,0.025000,0.025000},{0.593750,0.206250,0.050000,0.050000},{0.606250,0.206250,0.025000,0.025000},{0.606250,0.206250,0.050000,0.050000},{0.618750,0.206250,0.025000,0.025000},{0.618750,0.206250,0.050000,0.050000},{0.631250,0.206250,0.025000,0.025000},{0.631250,0.206250,0.050000,0.050000},{0.643750,0.206250,0.025000,0.025000},{0.643750,0.206250,0.050000,0.050000},{0.656250,0.206250,0.025000,0.025000},{0.656250,0.206250,0.050000,0.050000},{0.668750,0.206250,0.025000,0.025000},{0.668750,0.206250,0.050000,0.050000},{0.681250,0.206250,0.025000,0.025000},{0.681250,0.206250,0.050000,0.050000},{0.693750,0.206250,0.025000,0.025000},{0.693750,0.206250,0.050000,0.050000},{0.706250,0.206250,0.025000,0.025000},{0.706250,0.206250,0.050000,0.050000},{0.718750,0.206250,0.025000,0.025000},{0.718750,0.206250,0.050000,0.050000},{0.731250,0.206250,0.025000,0.025000},{0.731250,0.206250,0.050000,0.050000},{0.743750,0.206250,0.025000,0.025000},{0.743750,0.206250,0.050000,0.050000},{0.756250,0.206250,0.025000,0.025000},{0.756250,0.206250,0.050000,0.050000},{0.768750,0.206250,0.025000,0.025000},{0.768750,0.206250,0.050000,0.050000},{0.781250,0.206250,0.025000,0.025000},{0.781250,0.206250,0.050000,0.050000},{0.793750,0.206250,0.025000,0.025000},{0.793750,0.206250,0.050000,0.050000},{0.806250,0.206250,0.025000,0.025000},{0.806250,0.206250,0.050000,0.050000},{0.818750,0.206250,0.025000,0.025000},{0.818750,0.206250,0.050000,0.050000},{0.831250,0.206250,0.025000,0.025000},{0.831250,0.206250,0.050000,0.050000},{0.843750,0.206250,0.025000,0.025000},{0.843750,0.206250,0.050000,0.050000},{0.856250,0.206250,0.025000,0.025000},{0.856250,0.206250,0.050000,0.050000},{0.868750,0.206250,0.025000,0.025000},{0.868750,0.206250,0.050000,0.050000},{0.881250,0.206250,0.025000,0.025000},{0.881250,0.206250,0.050000,0.050000},{0.893750,0.206250,0.025000,0.025000},{0.893750,0.206250,0.050000,0.050000},{0.906250,0.206250,0.025000,0.025000},{0.906250,0.206250,0.050000,0.050000},{0.918750,0.206250,0.025000,0.025000},{0.918750,0.206250,0.050000,0.050000},{0.931250,0.206250,0.025000,0.025000},{0.931250,0.206250,0.050000,0.050000},{0.943750,0.206250,0.025000,0.025000},{0.943750,0.206250,0.050000,0.050000},{0.956250,0.206250,0.025000,0.025000},{0.956250,0.206250,0.050000,0.050000},{0.968750,0.206250,0.025000,0.025000},{0.968750,0.206250,0.050000,0.050000},{0.981250,0.206250,0.025000,0.025000},{0.981250,0.206250,0.050000,0.050000},{0.993750,0.206250,0.025000,0.025000},{0.993750,0.206250,0.050000,0.050000},{0.006250,0.218750,0.025000,0.025000},{0.006250,0.218750,0.050000,0.050000},{0.018750,0.218750,0.025000,0.025000},{0.018750,0.218750,0.050000,0.050000},{0.031250,0.218750,0.025000,0.025000},{0.031250,0.218750,0.050000,0.050000},{0.043750,0.218750,0.025000,0.025000},{0.043750,0.218750,0.050000,0.050000},{0.056250,0.218750,0.025000,0.025000},{0.056250,0.218750,0.050000,0.050000},{0.068750,0.218750,0.025000,0.025000},{0.068750,0.218750,0.050000,0.050000},{0.081250,0.218750,0.025000,0.025000},{0.081250,0.218750,0.050000,0.050000},{0.093750,0.218750,0.025000,0.025000},{0.093750,0.218750,0.050000,0.050000},{0.106250,0.218750,0.025000,0.025000},{0.106250,0.218750,0.050000,0.050000},{0.118750,0.218750,0.025000,0.025000},{0.118750,0.218750,0.050000,0.050000},{0.131250,0.218750,0.025000,0.025000},{0.131250,0.218750,0.050000,0.050000},{0.143750,0.218750,0.025000,0.025000},{0.143750,0.218750,0.050000,0.050000},{0.156250,0.218750,0.025000,0.025000},{0.156250,0.218750,0.050000,0.050000},{0.168750,0.218750,0.025000,0.025000},{0.168750,0.218750,0.050000,0.050000},{0.181250,0.218750,0.025000,0.025000},{0.181250,0.218750,0.050000,0.050000},{0.193750,0.218750,0.025000,0.025000},{0.193750,0.218750,0.050000,0.050000},{0.206250,0.218750,0.025000,0.025000},{0.206250,0.218750,0.050000,0.050000},{0.218750,0.218750,0.025000,0.025000},{0.218750,0.218750,0.050000,0.050000},{0.231250,0.218750,0.025000,0.025000},{0.231250,0.218750,0.050000,0.050000},{0.243750,0.218750,0.025000,0.025000},{0.243750,0.218750,0.050000,0.050000},{0.256250,0.218750,0.025000,0.025000},{0.256250,0.218750,0.050000,0.050000},{0.268750,0.218750,0.025000,0.025000},{0.268750,0.218750,0.050000,0.050000},{0.281250,0.218750,0.025000,0.025000},{0.281250,0.218750,0.050000,0.050000},{0.293750,0.218750,0.025000,0.025000},{0.293750,0.218750,0.050000,0.050000},{0.306250,0.218750,0.025000,0.025000},{0.306250,0.218750,0.050000,0.050000},{0.318750,0.218750,0.025000,0.025000},{0.318750,0.218750,0.050000,0.050000},{0.331250,0.218750,0.025000,0.025000},{0.331250,0.218750,0.050000,0.050000},{0.343750,0.218750,0.025000,0.025000},{0.343750,0.218750,0.050000,0.050000},{0.356250,0.218750,0.025000,0.025000},{0.356250,0.218750,0.050000,0.050000},{0.368750,0.218750,0.025000,0.025000},{0.368750,0.218750,0.050000,0.050000},{0.381250,0.218750,0.025000,0.025000},{0.381250,0.218750,0.050000,0.050000},{0.393750,0.218750,0.025000,0.025000},{0.393750,0.218750,0.050000,0.050000},{0.406250,0.218750,0.025000,0.025000},{0.406250,0.218750,0.050000,0.050000},{0.418750,0.218750,0.025000,0.025000},{0.418750,0.218750,0.050000,0.050000},{0.431250,0.218750,0.025000,0.025000},{0.431250,0.218750,0.050000,0.050000},{0.443750,0.218750,0.025000,0.025000},{0.443750,0.218750,0.050000,0.050000},{0.456250,0.218750,0.025000,0.025000},{0.456250,0.218750,0.050000,0.050000},{0.468750,0.218750,0.025000,0.025000},{0.468750,0.218750,0.050000,0.050000},{0.481250,0.218750,0.025000,0.025000},{0.481250,0.218750,0.050000,0.050000},{0.493750,0.218750,0.025000,0.025000},{0.493750,0.218750,0.050000,0.050000},{0.506250,0.218750,0.025000,0.025000},{0.506250,0.218750,0.050000,0.050000},{0.518750,0.218750,0.025000,0.025000},{0.518750,0.218750,0.050000,0.050000},{0.531250,0.218750,0.025000,0.025000},{0.531250,0.218750,0.050000,0.050000},{0.543750,0.218750,0.025000,0.025000},{0.543750,0.218750,0.050000,0.050000},{0.556250,0.218750,0.025000,0.025000},{0.556250,0.218750,0.050000,0.050000},{0.568750,0.218750,0.025000,0.025000},{0.568750,0.218750,0.050000,0.050000},{0.581250,0.218750,0.025000,0.025000},{0.581250,0.218750,0.050000,0.050000},{0.593750,0.218750,0.025000,0.025000},{0.593750,0.218750,0.050000,0.050000},{0.606250,0.218750,0.025000,0.025000},{0.606250,0.218750,0.050000,0.050000},{0.618750,0.218750,0.025000,0.025000},{0.618750,0.218750,0.050000,0.050000},{0.631250,0.218750,0.025000,0.025000},{0.631250,0.218750,0.050000,0.050000},{0.643750,0.218750,0.025000,0.025000},{0.643750,0.218750,0.050000,0.050000},{0.656250,0.218750,0.025000,0.025000},{0.656250,0.218750,0.050000,0.050000},{0.668750,0.218750,0.025000,0.025000},{0.668750,0.218750,0.050000,0.050000},{0.681250,0.218750,0.025000,0.025000},{0.681250,0.218750,0.050000,0.050000},{0.693750,0.218750,0.025000,0.025000},{0.693750,0.218750,0.050000,0.050000},{0.706250,0.218750,0.025000,0.025000},{0.706250,0.218750,0.050000,0.050000},{0.718750,0.218750,0.025000,0.025000},{0.718750,0.218750,0.050000,0.050000},{0.731250,0.218750,0.025000,0.025000},{0.731250,0.218750,0.050000,0.050000},{0.743750,0.218750,0.025000,0.025000},{0.743750,0.218750,0.050000,0.050000},{0.756250,0.218750,0.025000,0.025000},{0.756250,0.218750,0.050000,0.050000},{0.768750,0.218750,0.025000,0.025000},{0.768750,0.218750,0.050000,0.050000},{0.781250,0.218750,0.025000,0.025000},{0.781250,0.218750,0.050000,0.050000},{0.793750,0.218750,0.025000,0.025000},{0.793750,0.218750,0.050000,0.050000},{0.806250,0.218750,0.025000,0.025000},{0.806250,0.218750,0.050000,0.050000},{0.818750,0.218750,0.025000,0.025000},{0.818750,0.218750,0.050000,0.050000},{0.831250,0.218750,0.025000,0.025000},{0.831250,0.218750,0.050000,0.050000},{0.843750,0.218750,0.025000,0.025000},{0.843750,0.218750,0.050000,0.050000},{0.856250,0.218750,0.025000,0.025000},{0.856250,0.218750,0.050000,0.050000},{0.868750,0.218750,0.025000,0.025000},{0.868750,0.218750,0.050000,0.050000},{0.881250,0.218750,0.025000,0.025000},{0.881250,0.218750,0.050000,0.050000},{0.893750,0.218750,0.025000,0.025000},{0.893750,0.218750,0.050000,0.050000},{0.906250,0.218750,0.025000,0.025000},{0.906250,0.218750,0.050000,0.050000},{0.918750,0.218750,0.025000,0.025000},{0.918750,0.218750,0.050000,0.050000},{0.931250,0.218750,0.025000,0.025000},{0.931250,0.218750,0.050000,0.050000},{0.943750,0.218750,0.025000,0.025000},{0.943750,0.218750,0.050000,0.050000},{0.956250,0.218750,0.025000,0.025000},{0.956250,0.218750,0.050000,0.050000},{0.968750,0.218750,0.025000,0.025000},{0.968750,0.218750,0.050000,0.050000},{0.981250,0.218750,0.025000,0.025000},{0.981250,0.218750,0.050000,0.050000},{0.993750,0.218750,0.025000,0.025000},{0.993750,0.218750,0.050000,0.050000},{0.006250,0.231250,0.025000,0.025000},{0.006250,0.231250,0.050000,0.050000},{0.018750,0.231250,0.025000,0.025000},{0.018750,0.231250,0.050000,0.050000},{0.031250,0.231250,0.025000,0.025000},{0.031250,0.231250,0.050000,0.050000},{0.043750,0.231250,0.025000,0.025000},{0.043750,0.231250,0.050000,0.050000},{0.056250,0.231250,0.025000,0.025000},{0.056250,0.231250,0.050000,0.050000},{0.068750,0.231250,0.025000,0.025000},{0.068750,0.231250,0.050000,0.050000},{0.081250,0.231250,0.025000,0.025000},{0.081250,0.231250,0.050000,0.050000},{0.093750,0.231250,0.025000,0.025000},{0.093750,0.231250,0.050000,0.050000},{0.106250,0.231250,0.025000,0.025000},{0.106250,0.231250,0.050000,0.050000},{0.118750,0.231250,0.025000,0.025000},{0.118750,0.231250,0.050000,0.050000},{0.131250,0.231250,0.025000,0.025000},{0.131250,0.231250,0.050000,0.050000},{0.143750,0.231250,0.025000,0.025000},{0.143750,0.231250,0.050000,0.050000},{0.156250,0.231250,0.025000,0.025000},{0.156250,0.231250,0.050000,0.050000},{0.168750,0.231250,0.025000,0.025000},{0.168750,0.231250,0.050000,0.050000},{0.181250,0.231250,0.025000,0.025000},{0.181250,0.231250,0.050000,0.050000},{0.193750,0.231250,0.025000,0.025000},{0.193750,0.231250,0.050000,0.050000},{0.206250,0.231250,0.025000,0.025000},{0.206250,0.231250,0.050000,0.050000},{0.218750,0.231250,0.025000,0.025000},{0.218750,0.231250,0.050000,0.050000},{0.231250,0.231250,0.025000,0.025000},{0.231250,0.231250,0.050000,0.050000},{0.243750,0.231250,0.025000,0.025000},{0.243750,0.231250,0.050000,0.050000},{0.256250,0.231250,0.025000,0.025000},{0.256250,0.231250,0.050000,0.050000},{0.268750,0.231250,0.025000,0.025000},{0.268750,0.231250,0.050000,0.050000},{0.281250,0.231250,0.025000,0.025000},{0.281250,0.231250,0.050000,0.050000},{0.293750,0.231250,0.025000,0.025000},{0.293750,0.231250,0.050000,0.050000},{0.306250,0.231250,0.025000,0.025000},{0.306250,0.231250,0.050000,0.050000},{0.318750,0.231250,0.025000,0.025000},{0.318750,0.231250,0.050000,0.050000},{0.331250,0.231250,0.025000,0.025000},{0.331250,0.231250,0.050000,0.050000},{0.343750,0.231250,0.025000,0.025000},{0.343750,0.231250,0.050000,0.050000},{0.356250,0.231250,0.025000,0.025000},{0.356250,0.231250,0.050000,0.050000},{0.368750,0.231250,0.025000,0.025000},{0.368750,0.231250,0.050000,0.050000},{0.381250,0.231250,0.025000,0.025000},{0.381250,0.231250,0.050000,0.050000},{0.393750,0.231250,0.025000,0.025000},{0.393750,0.231250,0.050000,0.050000},{0.406250,0.231250,0.025000,0.025000},{0.406250,0.231250,0.050000,0.050000},{0.418750,0.231250,0.025000,0.025000},{0.418750,0.231250,0.050000,0.050000},{0.431250,0.231250,0.025000,0.025000},{0.431250,0.231250,0.050000,0.050000},{0.443750,0.231250,0.025000,0.025000},{0.443750,0.231250,0.050000,0.050000},{0.456250,0.231250,0.025000,0.025000},{0.456250,0.231250,0.050000,0.050000},{0.468750,0.231250,0.025000,0.025000},{0.468750,0.231250,0.050000,0.050000},{0.481250,0.231250,0.025000,0.025000},{0.481250,0.231250,0.050000,0.050000},{0.493750,0.231250,0.025000,0.025000},{0.493750,0.231250,0.050000,0.050000},{0.506250,0.231250,0.025000,0.025000},{0.506250,0.231250,0.050000,0.050000},{0.518750,0.231250,0.025000,0.025000},{0.518750,0.231250,0.050000,0.050000},{0.531250,0.231250,0.025000,0.025000},{0.531250,0.231250,0.050000,0.050000},{0.543750,0.231250,0.025000,0.025000},{0.543750,0.231250,0.050000,0.050000},{0.556250,0.231250,0.025000,0.025000},{0.556250,0.231250,0.050000,0.050000},{0.568750,0.231250,0.025000,0.025000},{0.568750,0.231250,0.050000,0.050000},{0.581250,0.231250,0.025000,0.025000},{0.581250,0.231250,0.050000,0.050000},{0.593750,0.231250,0.025000,0.025000},{0.593750,0.231250,0.050000,0.050000},{0.606250,0.231250,0.025000,0.025000},{0.606250,0.231250,0.050000,0.050000},{0.618750,0.231250,0.025000,0.025000},{0.618750,0.231250,0.050000,0.050000},{0.631250,0.231250,0.025000,0.025000},{0.631250,0.231250,0.050000,0.050000},{0.643750,0.231250,0.025000,0.025000},{0.643750,0.231250,0.050000,0.050000},{0.656250,0.231250,0.025000,0.025000},{0.656250,0.231250,0.050000,0.050000},{0.668750,0.231250,0.025000,0.025000},{0.668750,0.231250,0.050000,0.050000},{0.681250,0.231250,0.025000,0.025000},{0.681250,0.231250,0.050000,0.050000},{0.693750,0.231250,0.025000,0.025000},{0.693750,0.231250,0.050000,0.050000},{0.706250,0.231250,0.025000,0.025000},{0.706250,0.231250,0.050000,0.050000},{0.718750,0.231250,0.025000,0.025000},{0.718750,0.231250,0.050000,0.050000},{0.731250,0.231250,0.025000,0.025000},{0.731250,0.231250,0.050000,0.050000},{0.743750,0.231250,0.025000,0.025000},{0.743750,0.231250,0.050000,0.050000},{0.756250,0.231250,0.025000,0.025000},{0.756250,0.231250,0.050000,0.050000},{0.768750,0.231250,0.025000,0.025000},{0.768750,0.231250,0.050000,0.050000},{0.781250,0.231250,0.025000,0.025000},{0.781250,0.231250,0.050000,0.050000},{0.793750,0.231250,0.025000,0.025000},{0.793750,0.231250,0.050000,0.050000},{0.806250,0.231250,0.025000,0.025000},{0.806250,0.231250,0.050000,0.050000},{0.818750,0.231250,0.025000,0.025000},{0.818750,0.231250,0.050000,0.050000},{0.831250,0.231250,0.025000,0.025000},{0.831250,0.231250,0.050000,0.050000},{0.843750,0.231250,0.025000,0.025000},{0.843750,0.231250,0.050000,0.050000},{0.856250,0.231250,0.025000,0.025000},{0.856250,0.231250,0.050000,0.050000},{0.868750,0.231250,0.025000,0.025000},{0.868750,0.231250,0.050000,0.050000},{0.881250,0.231250,0.025000,0.025000},{0.881250,0.231250,0.050000,0.050000},{0.893750,0.231250,0.025000,0.025000},{0.893750,0.231250,0.050000,0.050000},{0.906250,0.231250,0.025000,0.025000},{0.906250,0.231250,0.050000,0.050000},{0.918750,0.231250,0.025000,0.025000},{0.918750,0.231250,0.050000,0.050000},{0.931250,0.231250,0.025000,0.025000},{0.931250,0.231250,0.050000,0.050000},{0.943750,0.231250,0.025000,0.025000},{0.943750,0.231250,0.050000,0.050000},{0.956250,0.231250,0.025000,0.025000},{0.956250,0.231250,0.050000,0.050000},{0.968750,0.231250,0.025000,0.025000},{0.968750,0.231250,0.050000,0.050000},{0.981250,0.231250,0.025000,0.025000},{0.981250,0.231250,0.050000,0.050000},{0.993750,0.231250,0.025000,0.025000},{0.993750,0.231250,0.050000,0.050000},{0.006250,0.243750,0.025000,0.025000},{0.006250,0.243750,0.050000,0.050000},{0.018750,0.243750,0.025000,0.025000},{0.018750,0.243750,0.050000,0.050000},{0.031250,0.243750,0.025000,0.025000},{0.031250,0.243750,0.050000,0.050000},{0.043750,0.243750,0.025000,0.025000},{0.043750,0.243750,0.050000,0.050000},{0.056250,0.243750,0.025000,0.025000},{0.056250,0.243750,0.050000,0.050000},{0.068750,0.243750,0.025000,0.025000},{0.068750,0.243750,0.050000,0.050000},{0.081250,0.243750,0.025000,0.025000},{0.081250,0.243750,0.050000,0.050000},{0.093750,0.243750,0.025000,0.025000},{0.093750,0.243750,0.050000,0.050000},{0.106250,0.243750,0.025000,0.025000},{0.106250,0.243750,0.050000,0.050000},{0.118750,0.243750,0.025000,0.025000},{0.118750,0.243750,0.050000,0.050000},{0.131250,0.243750,0.025000,0.025000},{0.131250,0.243750,0.050000,0.050000},{0.143750,0.243750,0.025000,0.025000},{0.143750,0.243750,0.050000,0.050000},{0.156250,0.243750,0.025000,0.025000},{0.156250,0.243750,0.050000,0.050000},{0.168750,0.243750,0.025000,0.025000},{0.168750,0.243750,0.050000,0.050000},{0.181250,0.243750,0.025000,0.025000},{0.181250,0.243750,0.050000,0.050000},{0.193750,0.243750,0.025000,0.025000},{0.193750,0.243750,0.050000,0.050000},{0.206250,0.243750,0.025000,0.025000},{0.206250,0.243750,0.050000,0.050000},{0.218750,0.243750,0.025000,0.025000},{0.218750,0.243750,0.050000,0.050000},{0.231250,0.243750,0.025000,0.025000},{0.231250,0.243750,0.050000,0.050000},{0.243750,0.243750,0.025000,0.025000},{0.243750,0.243750,0.050000,0.050000},{0.256250,0.243750,0.025000,0.025000},{0.256250,0.243750,0.050000,0.050000},{0.268750,0.243750,0.025000,0.025000},{0.268750,0.243750,0.050000,0.050000},{0.281250,0.243750,0.025000,0.025000},{0.281250,0.243750,0.050000,0.050000},{0.293750,0.243750,0.025000,0.025000},{0.293750,0.243750,0.050000,0.050000},{0.306250,0.243750,0.025000,0.025000},{0.306250,0.243750,0.050000,0.050000},{0.318750,0.243750,0.025000,0.025000},{0.318750,0.243750,0.050000,0.050000},{0.331250,0.243750,0.025000,0.025000},{0.331250,0.243750,0.050000,0.050000},{0.343750,0.243750,0.025000,0.025000},{0.343750,0.243750,0.050000,0.050000},{0.356250,0.243750,0.025000,0.025000},{0.356250,0.243750,0.050000,0.050000},{0.368750,0.243750,0.025000,0.025000},{0.368750,0.243750,0.050000,0.050000},{0.381250,0.243750,0.025000,0.025000},{0.381250,0.243750,0.050000,0.050000},{0.393750,0.243750,0.025000,0.025000},{0.393750,0.243750,0.050000,0.050000},{0.406250,0.243750,0.025000,0.025000},{0.406250,0.243750,0.050000,0.050000},{0.418750,0.243750,0.025000,0.025000},{0.418750,0.243750,0.050000,0.050000},{0.431250,0.243750,0.025000,0.025000},{0.431250,0.243750,0.050000,0.050000},{0.443750,0.243750,0.025000,0.025000},{0.443750,0.243750,0.050000,0.050000},{0.456250,0.243750,0.025000,0.025000},{0.456250,0.243750,0.050000,0.050000},{0.468750,0.243750,0.025000,0.025000},{0.468750,0.243750,0.050000,0.050000},{0.481250,0.243750,0.025000,0.025000},{0.481250,0.243750,0.050000,0.050000},{0.493750,0.243750,0.025000,0.025000},{0.493750,0.243750,0.050000,0.050000},{0.506250,0.243750,0.025000,0.025000},{0.506250,0.243750,0.050000,0.050000},{0.518750,0.243750,0.025000,0.025000},{0.518750,0.243750,0.050000,0.050000},{0.531250,0.243750,0.025000,0.025000},{0.531250,0.243750,0.050000,0.050000},{0.543750,0.243750,0.025000,0.025000},{0.543750,0.243750,0.050000,0.050000},{0.556250,0.243750,0.025000,0.025000},{0.556250,0.243750,0.050000,0.050000},{0.568750,0.243750,0.025000,0.025000},{0.568750,0.243750,0.050000,0.050000},{0.581250,0.243750,0.025000,0.025000},{0.581250,0.243750,0.050000,0.050000},{0.593750,0.243750,0.025000,0.025000},{0.593750,0.243750,0.050000,0.050000},{0.606250,0.243750,0.025000,0.025000},{0.606250,0.243750,0.050000,0.050000},{0.618750,0.243750,0.025000,0.025000},{0.618750,0.243750,0.050000,0.050000},{0.631250,0.243750,0.025000,0.025000},{0.631250,0.243750,0.050000,0.050000},{0.643750,0.243750,0.025000,0.025000},{0.643750,0.243750,0.050000,0.050000},{0.656250,0.243750,0.025000,0.025000},{0.656250,0.243750,0.050000,0.050000},{0.668750,0.243750,0.025000,0.025000},{0.668750,0.243750,0.050000,0.050000},{0.681250,0.243750,0.025000,0.025000},{0.681250,0.243750,0.050000,0.050000},{0.693750,0.243750,0.025000,0.025000},{0.693750,0.243750,0.050000,0.050000},{0.706250,0.243750,0.025000,0.025000},{0.706250,0.243750,0.050000,0.050000},{0.718750,0.243750,0.025000,0.025000},{0.718750,0.243750,0.050000,0.050000},{0.731250,0.243750,0.025000,0.025000},{0.731250,0.243750,0.050000,0.050000},{0.743750,0.243750,0.025000,0.025000},{0.743750,0.243750,0.050000,0.050000},{0.756250,0.243750,0.025000,0.025000},{0.756250,0.243750,0.050000,0.050000},{0.768750,0.243750,0.025000,0.025000},{0.768750,0.243750,0.050000,0.050000},{0.781250,0.243750,0.025000,0.025000},{0.781250,0.243750,0.050000,0.050000},{0.793750,0.243750,0.025000,0.025000},{0.793750,0.243750,0.050000,0.050000},{0.806250,0.243750,0.025000,0.025000},{0.806250,0.243750,0.050000,0.050000},{0.818750,0.243750,0.025000,0.025000},{0.818750,0.243750,0.050000,0.050000},{0.831250,0.243750,0.025000,0.025000},{0.831250,0.243750,0.050000,0.050000},{0.843750,0.243750,0.025000,0.025000},{0.843750,0.243750,0.050000,0.050000},{0.856250,0.243750,0.025000,0.025000},{0.856250,0.243750,0.050000,0.050000},{0.868750,0.243750,0.025000,0.025000},{0.868750,0.243750,0.050000,0.050000},{0.881250,0.243750,0.025000,0.025000},{0.881250,0.243750,0.050000,0.050000},{0.893750,0.243750,0.025000,0.025000},{0.893750,0.243750,0.050000,0.050000},{0.906250,0.243750,0.025000,0.025000},{0.906250,0.243750,0.050000,0.050000},{0.918750,0.243750,0.025000,0.025000},{0.918750,0.243750,0.050000,0.050000},{0.931250,0.243750,0.025000,0.025000},{0.931250,0.243750,0.050000,0.050000},{0.943750,0.243750,0.025000,0.025000},{0.943750,0.243750,0.050000,0.050000},{0.956250,0.243750,0.025000,0.025000},{0.956250,0.243750,0.050000,0.050000},{0.968750,0.243750,0.025000,0.025000},{0.968750,0.243750,0.050000,0.050000},{0.981250,0.243750,0.025000,0.025000},{0.981250,0.243750,0.050000,0.050000},{0.993750,0.243750,0.025000,0.025000},{0.993750,0.243750,0.050000,0.050000},{0.006250,0.256250,0.025000,0.025000},{0.006250,0.256250,0.050000,0.050000},{0.018750,0.256250,0.025000,0.025000},{0.018750,0.256250,0.050000,0.050000},{0.031250,0.256250,0.025000,0.025000},{0.031250,0.256250,0.050000,0.050000},{0.043750,0.256250,0.025000,0.025000},{0.043750,0.256250,0.050000,0.050000},{0.056250,0.256250,0.025000,0.025000},{0.056250,0.256250,0.050000,0.050000},{0.068750,0.256250,0.025000,0.025000},{0.068750,0.256250,0.050000,0.050000},{0.081250,0.256250,0.025000,0.025000},{0.081250,0.256250,0.050000,0.050000},{0.093750,0.256250,0.025000,0.025000},{0.093750,0.256250,0.050000,0.050000},{0.106250,0.256250,0.025000,0.025000},{0.106250,0.256250,0.050000,0.050000},{0.118750,0.256250,0.025000,0.025000},{0.118750,0.256250,0.050000,0.050000},{0.131250,0.256250,0.025000,0.025000},{0.131250,0.256250,0.050000,0.050000},{0.143750,0.256250,0.025000,0.025000},{0.143750,0.256250,0.050000,0.050000},{0.156250,0.256250,0.025000,0.025000},{0.156250,0.256250,0.050000,0.050000},{0.168750,0.256250,0.025000,0.025000},{0.168750,0.256250,0.050000,0.050000},{0.181250,0.256250,0.025000,0.025000},{0.181250,0.256250,0.050000,0.050000},{0.193750,0.256250,0.025000,0.025000},{0.193750,0.256250,0.050000,0.050000},{0.206250,0.256250,0.025000,0.025000},{0.206250,0.256250,0.050000,0.050000},{0.218750,0.256250,0.025000,0.025000},{0.218750,0.256250,0.050000,0.050000},{0.231250,0.256250,0.025000,0.025000},{0.231250,0.256250,0.050000,0.050000},{0.243750,0.256250,0.025000,0.025000},{0.243750,0.256250,0.050000,0.050000},{0.256250,0.256250,0.025000,0.025000},{0.256250,0.256250,0.050000,0.050000},{0.268750,0.256250,0.025000,0.025000},{0.268750,0.256250,0.050000,0.050000},{0.281250,0.256250,0.025000,0.025000},{0.281250,0.256250,0.050000,0.050000},{0.293750,0.256250,0.025000,0.025000},{0.293750,0.256250,0.050000,0.050000},{0.306250,0.256250,0.025000,0.025000},{0.306250,0.256250,0.050000,0.050000},{0.318750,0.256250,0.025000,0.025000},{0.318750,0.256250,0.050000,0.050000},{0.331250,0.256250,0.025000,0.025000},{0.331250,0.256250,0.050000,0.050000},{0.343750,0.256250,0.025000,0.025000},{0.343750,0.256250,0.050000,0.050000},{0.356250,0.256250,0.025000,0.025000},{0.356250,0.256250,0.050000,0.050000},{0.368750,0.256250,0.025000,0.025000},{0.368750,0.256250,0.050000,0.050000},{0.381250,0.256250,0.025000,0.025000},{0.381250,0.256250,0.050000,0.050000},{0.393750,0.256250,0.025000,0.025000},{0.393750,0.256250,0.050000,0.050000},{0.406250,0.256250,0.025000,0.025000},{0.406250,0.256250,0.050000,0.050000},{0.418750,0.256250,0.025000,0.025000},{0.418750,0.256250,0.050000,0.050000},{0.431250,0.256250,0.025000,0.025000},{0.431250,0.256250,0.050000,0.050000},{0.443750,0.256250,0.025000,0.025000},{0.443750,0.256250,0.050000,0.050000},{0.456250,0.256250,0.025000,0.025000},{0.456250,0.256250,0.050000,0.050000},{0.468750,0.256250,0.025000,0.025000},{0.468750,0.256250,0.050000,0.050000},{0.481250,0.256250,0.025000,0.025000},{0.481250,0.256250,0.050000,0.050000},{0.493750,0.256250,0.025000,0.025000},{0.493750,0.256250,0.050000,0.050000},{0.506250,0.256250,0.025000,0.025000},{0.506250,0.256250,0.050000,0.050000},{0.518750,0.256250,0.025000,0.025000},{0.518750,0.256250,0.050000,0.050000},{0.531250,0.256250,0.025000,0.025000},{0.531250,0.256250,0.050000,0.050000},{0.543750,0.256250,0.025000,0.025000},{0.543750,0.256250,0.050000,0.050000},{0.556250,0.256250,0.025000,0.025000},{0.556250,0.256250,0.050000,0.050000},{0.568750,0.256250,0.025000,0.025000},{0.568750,0.256250,0.050000,0.050000},{0.581250,0.256250,0.025000,0.025000},{0.581250,0.256250,0.050000,0.050000},{0.593750,0.256250,0.025000,0.025000},{0.593750,0.256250,0.050000,0.050000},{0.606250,0.256250,0.025000,0.025000},{0.606250,0.256250,0.050000,0.050000},{0.618750,0.256250,0.025000,0.025000},{0.618750,0.256250,0.050000,0.050000},{0.631250,0.256250,0.025000,0.025000},{0.631250,0.256250,0.050000,0.050000},{0.643750,0.256250,0.025000,0.025000},{0.643750,0.256250,0.050000,0.050000},{0.656250,0.256250,0.025000,0.025000},{0.656250,0.256250,0.050000,0.050000},{0.668750,0.256250,0.025000,0.025000},{0.668750,0.256250,0.050000,0.050000},{0.681250,0.256250,0.025000,0.025000},{0.681250,0.256250,0.050000,0.050000},{0.693750,0.256250,0.025000,0.025000},{0.693750,0.256250,0.050000,0.050000},{0.706250,0.256250,0.025000,0.025000},{0.706250,0.256250,0.050000,0.050000},{0.718750,0.256250,0.025000,0.025000},{0.718750,0.256250,0.050000,0.050000},{0.731250,0.256250,0.025000,0.025000},{0.731250,0.256250,0.050000,0.050000},{0.743750,0.256250,0.025000,0.025000},{0.743750,0.256250,0.050000,0.050000},{0.756250,0.256250,0.025000,0.025000},{0.756250,0.256250,0.050000,0.050000},{0.768750,0.256250,0.025000,0.025000},{0.768750,0.256250,0.050000,0.050000},{0.781250,0.256250,0.025000,0.025000},{0.781250,0.256250,0.050000,0.050000},{0.793750,0.256250,0.025000,0.025000},{0.793750,0.256250,0.050000,0.050000},{0.806250,0.256250,0.025000,0.025000},{0.806250,0.256250,0.050000,0.050000},{0.818750,0.256250,0.025000,0.025000},{0.818750,0.256250,0.050000,0.050000},{0.831250,0.256250,0.025000,0.025000},{0.831250,0.256250,0.050000,0.050000},{0.843750,0.256250,0.025000,0.025000},{0.843750,0.256250,0.050000,0.050000},{0.856250,0.256250,0.025000,0.025000},{0.856250,0.256250,0.050000,0.050000},{0.868750,0.256250,0.025000,0.025000},{0.868750,0.256250,0.050000,0.050000},{0.881250,0.256250,0.025000,0.025000},{0.881250,0.256250,0.050000,0.050000},{0.893750,0.256250,0.025000,0.025000},{0.893750,0.256250,0.050000,0.050000},{0.906250,0.256250,0.025000,0.025000},{0.906250,0.256250,0.050000,0.050000},{0.918750,0.256250,0.025000,0.025000},{0.918750,0.256250,0.050000,0.050000},{0.931250,0.256250,0.025000,0.025000},{0.931250,0.256250,0.050000,0.050000},{0.943750,0.256250,0.025000,0.025000},{0.943750,0.256250,0.050000,0.050000},{0.956250,0.256250,0.025000,0.025000},{0.956250,0.256250,0.050000,0.050000},{0.968750,0.256250,0.025000,0.025000},{0.968750,0.256250,0.050000,0.050000},{0.981250,0.256250,0.025000,0.025000},{0.981250,0.256250,0.050000,0.050000},{0.993750,0.256250,0.025000,0.025000},{0.993750,0.256250,0.050000,0.050000},{0.006250,0.268750,0.025000,0.025000},{0.006250,0.268750,0.050000,0.050000},{0.018750,0.268750,0.025000,0.025000},{0.018750,0.268750,0.050000,0.050000},{0.031250,0.268750,0.025000,0.025000},{0.031250,0.268750,0.050000,0.050000},{0.043750,0.268750,0.025000,0.025000},{0.043750,0.268750,0.050000,0.050000},{0.056250,0.268750,0.025000,0.025000},{0.056250,0.268750,0.050000,0.050000},{0.068750,0.268750,0.025000,0.025000},{0.068750,0.268750,0.050000,0.050000},{0.081250,0.268750,0.025000,0.025000},{0.081250,0.268750,0.050000,0.050000},{0.093750,0.268750,0.025000,0.025000},{0.093750,0.268750,0.050000,0.050000},{0.106250,0.268750,0.025000,0.025000},{0.106250,0.268750,0.050000,0.050000},{0.118750,0.268750,0.025000,0.025000},{0.118750,0.268750,0.050000,0.050000},{0.131250,0.268750,0.025000,0.025000},{0.131250,0.268750,0.050000,0.050000},{0.143750,0.268750,0.025000,0.025000},{0.143750,0.268750,0.050000,0.050000},{0.156250,0.268750,0.025000,0.025000},{0.156250,0.268750,0.050000,0.050000},{0.168750,0.268750,0.025000,0.025000},{0.168750,0.268750,0.050000,0.050000},{0.181250,0.268750,0.025000,0.025000},{0.181250,0.268750,0.050000,0.050000},{0.193750,0.268750,0.025000,0.025000},{0.193750,0.268750,0.050000,0.050000},{0.206250,0.268750,0.025000,0.025000},{0.206250,0.268750,0.050000,0.050000},{0.218750,0.268750,0.025000,0.025000},{0.218750,0.268750,0.050000,0.050000},{0.231250,0.268750,0.025000,0.025000},{0.231250,0.268750,0.050000,0.050000},{0.243750,0.268750,0.025000,0.025000},{0.243750,0.268750,0.050000,0.050000},{0.256250,0.268750,0.025000,0.025000},{0.256250,0.268750,0.050000,0.050000},{0.268750,0.268750,0.025000,0.025000},{0.268750,0.268750,0.050000,0.050000},{0.281250,0.268750,0.025000,0.025000},{0.281250,0.268750,0.050000,0.050000},{0.293750,0.268750,0.025000,0.025000},{0.293750,0.268750,0.050000,0.050000},{0.306250,0.268750,0.025000,0.025000},{0.306250,0.268750,0.050000,0.050000},{0.318750,0.268750,0.025000,0.025000},{0.318750,0.268750,0.050000,0.050000},{0.331250,0.268750,0.025000,0.025000},{0.331250,0.268750,0.050000,0.050000},{0.343750,0.268750,0.025000,0.025000},{0.343750,0.268750,0.050000,0.050000},{0.356250,0.268750,0.025000,0.025000},{0.356250,0.268750,0.050000,0.050000},{0.368750,0.268750,0.025000,0.025000},{0.368750,0.268750,0.050000,0.050000},{0.381250,0.268750,0.025000,0.025000},{0.381250,0.268750,0.050000,0.050000},{0.393750,0.268750,0.025000,0.025000},{0.393750,0.268750,0.050000,0.050000},{0.406250,0.268750,0.025000,0.025000},{0.406250,0.268750,0.050000,0.050000},{0.418750,0.268750,0.025000,0.025000},{0.418750,0.268750,0.050000,0.050000},{0.431250,0.268750,0.025000,0.025000},{0.431250,0.268750,0.050000,0.050000},{0.443750,0.268750,0.025000,0.025000},{0.443750,0.268750,0.050000,0.050000},{0.456250,0.268750,0.025000,0.025000},{0.456250,0.268750,0.050000,0.050000},{0.468750,0.268750,0.025000,0.025000},{0.468750,0.268750,0.050000,0.050000},{0.481250,0.268750,0.025000,0.025000},{0.481250,0.268750,0.050000,0.050000},{0.493750,0.268750,0.025000,0.025000},{0.493750,0.268750,0.050000,0.050000},{0.506250,0.268750,0.025000,0.025000},{0.506250,0.268750,0.050000,0.050000},{0.518750,0.268750,0.025000,0.025000},{0.518750,0.268750,0.050000,0.050000},{0.531250,0.268750,0.025000,0.025000},{0.531250,0.268750,0.050000,0.050000},{0.543750,0.268750,0.025000,0.025000},{0.543750,0.268750,0.050000,0.050000},{0.556250,0.268750,0.025000,0.025000},{0.556250,0.268750,0.050000,0.050000},{0.568750,0.268750,0.025000,0.025000},{0.568750,0.268750,0.050000,0.050000},{0.581250,0.268750,0.025000,0.025000},{0.581250,0.268750,0.050000,0.050000},{0.593750,0.268750,0.025000,0.025000},{0.593750,0.268750,0.050000,0.050000},{0.606250,0.268750,0.025000,0.025000},{0.606250,0.268750,0.050000,0.050000},{0.618750,0.268750,0.025000,0.025000},{0.618750,0.268750,0.050000,0.050000},{0.631250,0.268750,0.025000,0.025000},{0.631250,0.268750,0.050000,0.050000},{0.643750,0.268750,0.025000,0.025000},{0.643750,0.268750,0.050000,0.050000},{0.656250,0.268750,0.025000,0.025000},{0.656250,0.268750,0.050000,0.050000},{0.668750,0.268750,0.025000,0.025000},{0.668750,0.268750,0.050000,0.050000},{0.681250,0.268750,0.025000,0.025000},{0.681250,0.268750,0.050000,0.050000},{0.693750,0.268750,0.025000,0.025000},{0.693750,0.268750,0.050000,0.050000},{0.706250,0.268750,0.025000,0.025000},{0.706250,0.268750,0.050000,0.050000},{0.718750,0.268750,0.025000,0.025000},{0.718750,0.268750,0.050000,0.050000},{0.731250,0.268750,0.025000,0.025000},{0.731250,0.268750,0.050000,0.050000},{0.743750,0.268750,0.025000,0.025000},{0.743750,0.268750,0.050000,0.050000},{0.756250,0.268750,0.025000,0.025000},{0.756250,0.268750,0.050000,0.050000},{0.768750,0.268750,0.025000,0.025000},{0.768750,0.268750,0.050000,0.050000},{0.781250,0.268750,0.025000,0.025000},{0.781250,0.268750,0.050000,0.050000},{0.793750,0.268750,0.025000,0.025000},{0.793750,0.268750,0.050000,0.050000},{0.806250,0.268750,0.025000,0.025000},{0.806250,0.268750,0.050000,0.050000},{0.818750,0.268750,0.025000,0.025000},{0.818750,0.268750,0.050000,0.050000},{0.831250,0.268750,0.025000,0.025000},{0.831250,0.268750,0.050000,0.050000},{0.843750,0.268750,0.025000,0.025000},{0.843750,0.268750,0.050000,0.050000},{0.856250,0.268750,0.025000,0.025000},{0.856250,0.268750,0.050000,0.050000},{0.868750,0.268750,0.025000,0.025000},{0.868750,0.268750,0.050000,0.050000},{0.881250,0.268750,0.025000,0.025000},{0.881250,0.268750,0.050000,0.050000},{0.893750,0.268750,0.025000,0.025000},{0.893750,0.268750,0.050000,0.050000},{0.906250,0.268750,0.025000,0.025000},{0.906250,0.268750,0.050000,0.050000},{0.918750,0.268750,0.025000,0.025000},{0.918750,0.268750,0.050000,0.050000},{0.931250,0.268750,0.025000,0.025000},{0.931250,0.268750,0.050000,0.050000},{0.943750,0.268750,0.025000,0.025000},{0.943750,0.268750,0.050000,0.050000},{0.956250,0.268750,0.025000,0.025000},{0.956250,0.268750,0.050000,0.050000},{0.968750,0.268750,0.025000,0.025000},{0.968750,0.268750,0.050000,0.050000},{0.981250,0.268750,0.025000,0.025000},{0.981250,0.268750,0.050000,0.050000},{0.993750,0.268750,0.025000,0.025000},{0.993750,0.268750,0.050000,0.050000},{0.006250,0.281250,0.025000,0.025000},{0.006250,0.281250,0.050000,0.050000},{0.018750,0.281250,0.025000,0.025000},{0.018750,0.281250,0.050000,0.050000},{0.031250,0.281250,0.025000,0.025000},{0.031250,0.281250,0.050000,0.050000},{0.043750,0.281250,0.025000,0.025000},{0.043750,0.281250,0.050000,0.050000},{0.056250,0.281250,0.025000,0.025000},{0.056250,0.281250,0.050000,0.050000},{0.068750,0.281250,0.025000,0.025000},{0.068750,0.281250,0.050000,0.050000},{0.081250,0.281250,0.025000,0.025000},{0.081250,0.281250,0.050000,0.050000},{0.093750,0.281250,0.025000,0.025000},{0.093750,0.281250,0.050000,0.050000},{0.106250,0.281250,0.025000,0.025000},{0.106250,0.281250,0.050000,0.050000},{0.118750,0.281250,0.025000,0.025000},{0.118750,0.281250,0.050000,0.050000},{0.131250,0.281250,0.025000,0.025000},{0.131250,0.281250,0.050000,0.050000},{0.143750,0.281250,0.025000,0.025000},{0.143750,0.281250,0.050000,0.050000},{0.156250,0.281250,0.025000,0.025000},{0.156250,0.281250,0.050000,0.050000},{0.168750,0.281250,0.025000,0.025000},{0.168750,0.281250,0.050000,0.050000},{0.181250,0.281250,0.025000,0.025000},{0.181250,0.281250,0.050000,0.050000},{0.193750,0.281250,0.025000,0.025000},{0.193750,0.281250,0.050000,0.050000},{0.206250,0.281250,0.025000,0.025000},{0.206250,0.281250,0.050000,0.050000},{0.218750,0.281250,0.025000,0.025000},{0.218750,0.281250,0.050000,0.050000},{0.231250,0.281250,0.025000,0.025000},{0.231250,0.281250,0.050000,0.050000},{0.243750,0.281250,0.025000,0.025000},{0.243750,0.281250,0.050000,0.050000},{0.256250,0.281250,0.025000,0.025000},{0.256250,0.281250,0.050000,0.050000},{0.268750,0.281250,0.025000,0.025000},{0.268750,0.281250,0.050000,0.050000},{0.281250,0.281250,0.025000,0.025000},{0.281250,0.281250,0.050000,0.050000},{0.293750,0.281250,0.025000,0.025000},{0.293750,0.281250,0.050000,0.050000},{0.306250,0.281250,0.025000,0.025000},{0.306250,0.281250,0.050000,0.050000},{0.318750,0.281250,0.025000,0.025000},{0.318750,0.281250,0.050000,0.050000},{0.331250,0.281250,0.025000,0.025000},{0.331250,0.281250,0.050000,0.050000},{0.343750,0.281250,0.025000,0.025000},{0.343750,0.281250,0.050000,0.050000},{0.356250,0.281250,0.025000,0.025000},{0.356250,0.281250,0.050000,0.050000},{0.368750,0.281250,0.025000,0.025000},{0.368750,0.281250,0.050000,0.050000},{0.381250,0.281250,0.025000,0.025000},{0.381250,0.281250,0.050000,0.050000},{0.393750,0.281250,0.025000,0.025000},{0.393750,0.281250,0.050000,0.050000},{0.406250,0.281250,0.025000,0.025000},{0.406250,0.281250,0.050000,0.050000},{0.418750,0.281250,0.025000,0.025000},{0.418750,0.281250,0.050000,0.050000},{0.431250,0.281250,0.025000,0.025000},{0.431250,0.281250,0.050000,0.050000},{0.443750,0.281250,0.025000,0.025000},{0.443750,0.281250,0.050000,0.050000},{0.456250,0.281250,0.025000,0.025000},{0.456250,0.281250,0.050000,0.050000},{0.468750,0.281250,0.025000,0.025000},{0.468750,0.281250,0.050000,0.050000},{0.481250,0.281250,0.025000,0.025000},{0.481250,0.281250,0.050000,0.050000},{0.493750,0.281250,0.025000,0.025000},{0.493750,0.281250,0.050000,0.050000},{0.506250,0.281250,0.025000,0.025000},{0.506250,0.281250,0.050000,0.050000},{0.518750,0.281250,0.025000,0.025000},{0.518750,0.281250,0.050000,0.050000},{0.531250,0.281250,0.025000,0.025000},{0.531250,0.281250,0.050000,0.050000},{0.543750,0.281250,0.025000,0.025000},{0.543750,0.281250,0.050000,0.050000},{0.556250,0.281250,0.025000,0.025000},{0.556250,0.281250,0.050000,0.050000},{0.568750,0.281250,0.025000,0.025000},{0.568750,0.281250,0.050000,0.050000},{0.581250,0.281250,0.025000,0.025000},{0.581250,0.281250,0.050000,0.050000},{0.593750,0.281250,0.025000,0.025000},{0.593750,0.281250,0.050000,0.050000},{0.606250,0.281250,0.025000,0.025000},{0.606250,0.281250,0.050000,0.050000},{0.618750,0.281250,0.025000,0.025000},{0.618750,0.281250,0.050000,0.050000},{0.631250,0.281250,0.025000,0.025000},{0.631250,0.281250,0.050000,0.050000},{0.643750,0.281250,0.025000,0.025000},{0.643750,0.281250,0.050000,0.050000},{0.656250,0.281250,0.025000,0.025000},{0.656250,0.281250,0.050000,0.050000},{0.668750,0.281250,0.025000,0.025000},{0.668750,0.281250,0.050000,0.050000},{0.681250,0.281250,0.025000,0.025000},{0.681250,0.281250,0.050000,0.050000},{0.693750,0.281250,0.025000,0.025000},{0.693750,0.281250,0.050000,0.050000},{0.706250,0.281250,0.025000,0.025000},{0.706250,0.281250,0.050000,0.050000},{0.718750,0.281250,0.025000,0.025000},{0.718750,0.281250,0.050000,0.050000},{0.731250,0.281250,0.025000,0.025000},{0.731250,0.281250,0.050000,0.050000},{0.743750,0.281250,0.025000,0.025000},{0.743750,0.281250,0.050000,0.050000},{0.756250,0.281250,0.025000,0.025000},{0.756250,0.281250,0.050000,0.050000},{0.768750,0.281250,0.025000,0.025000},{0.768750,0.281250,0.050000,0.050000},{0.781250,0.281250,0.025000,0.025000},{0.781250,0.281250,0.050000,0.050000},{0.793750,0.281250,0.025000,0.025000},{0.793750,0.281250,0.050000,0.050000},{0.806250,0.281250,0.025000,0.025000},{0.806250,0.281250,0.050000,0.050000},{0.818750,0.281250,0.025000,0.025000},{0.818750,0.281250,0.050000,0.050000},{0.831250,0.281250,0.025000,0.025000},{0.831250,0.281250,0.050000,0.050000},{0.843750,0.281250,0.025000,0.025000},{0.843750,0.281250,0.050000,0.050000},{0.856250,0.281250,0.025000,0.025000},{0.856250,0.281250,0.050000,0.050000},{0.868750,0.281250,0.025000,0.025000},{0.868750,0.281250,0.050000,0.050000},{0.881250,0.281250,0.025000,0.025000},{0.881250,0.281250,0.050000,0.050000},{0.893750,0.281250,0.025000,0.025000},{0.893750,0.281250,0.050000,0.050000},{0.906250,0.281250,0.025000,0.025000},{0.906250,0.281250,0.050000,0.050000},{0.918750,0.281250,0.025000,0.025000},{0.918750,0.281250,0.050000,0.050000},{0.931250,0.281250,0.025000,0.025000},{0.931250,0.281250,0.050000,0.050000},{0.943750,0.281250,0.025000,0.025000},{0.943750,0.281250,0.050000,0.050000},{0.956250,0.281250,0.025000,0.025000},{0.956250,0.281250,0.050000,0.050000},{0.968750,0.281250,0.025000,0.025000},{0.968750,0.281250,0.050000,0.050000},{0.981250,0.281250,0.025000,0.025000},{0.981250,0.281250,0.050000,0.050000},{0.993750,0.281250,0.025000,0.025000},{0.993750,0.281250,0.050000,0.050000},{0.006250,0.293750,0.025000,0.025000},{0.006250,0.293750,0.050000,0.050000},{0.018750,0.293750,0.025000,0.025000},{0.018750,0.293750,0.050000,0.050000},{0.031250,0.293750,0.025000,0.025000},{0.031250,0.293750,0.050000,0.050000},{0.043750,0.293750,0.025000,0.025000},{0.043750,0.293750,0.050000,0.050000},{0.056250,0.293750,0.025000,0.025000},{0.056250,0.293750,0.050000,0.050000},{0.068750,0.293750,0.025000,0.025000},{0.068750,0.293750,0.050000,0.050000},{0.081250,0.293750,0.025000,0.025000},{0.081250,0.293750,0.050000,0.050000},{0.093750,0.293750,0.025000,0.025000},{0.093750,0.293750,0.050000,0.050000},{0.106250,0.293750,0.025000,0.025000},{0.106250,0.293750,0.050000,0.050000},{0.118750,0.293750,0.025000,0.025000},{0.118750,0.293750,0.050000,0.050000},{0.131250,0.293750,0.025000,0.025000},{0.131250,0.293750,0.050000,0.050000},{0.143750,0.293750,0.025000,0.025000},{0.143750,0.293750,0.050000,0.050000},{0.156250,0.293750,0.025000,0.025000},{0.156250,0.293750,0.050000,0.050000},{0.168750,0.293750,0.025000,0.025000},{0.168750,0.293750,0.050000,0.050000},{0.181250,0.293750,0.025000,0.025000},{0.181250,0.293750,0.050000,0.050000},{0.193750,0.293750,0.025000,0.025000},{0.193750,0.293750,0.050000,0.050000},{0.206250,0.293750,0.025000,0.025000},{0.206250,0.293750,0.050000,0.050000},{0.218750,0.293750,0.025000,0.025000},{0.218750,0.293750,0.050000,0.050000},{0.231250,0.293750,0.025000,0.025000},{0.231250,0.293750,0.050000,0.050000},{0.243750,0.293750,0.025000,0.025000},{0.243750,0.293750,0.050000,0.050000},{0.256250,0.293750,0.025000,0.025000},{0.256250,0.293750,0.050000,0.050000},{0.268750,0.293750,0.025000,0.025000},{0.268750,0.293750,0.050000,0.050000},{0.281250,0.293750,0.025000,0.025000},{0.281250,0.293750,0.050000,0.050000},{0.293750,0.293750,0.025000,0.025000},{0.293750,0.293750,0.050000,0.050000},{0.306250,0.293750,0.025000,0.025000},{0.306250,0.293750,0.050000,0.050000},{0.318750,0.293750,0.025000,0.025000},{0.318750,0.293750,0.050000,0.050000},{0.331250,0.293750,0.025000,0.025000},{0.331250,0.293750,0.050000,0.050000},{0.343750,0.293750,0.025000,0.025000},{0.343750,0.293750,0.050000,0.050000},{0.356250,0.293750,0.025000,0.025000},{0.356250,0.293750,0.050000,0.050000},{0.368750,0.293750,0.025000,0.025000},{0.368750,0.293750,0.050000,0.050000},{0.381250,0.293750,0.025000,0.025000},{0.381250,0.293750,0.050000,0.050000},{0.393750,0.293750,0.025000,0.025000},{0.393750,0.293750,0.050000,0.050000},{0.406250,0.293750,0.025000,0.025000},{0.406250,0.293750,0.050000,0.050000},{0.418750,0.293750,0.025000,0.025000},{0.418750,0.293750,0.050000,0.050000},{0.431250,0.293750,0.025000,0.025000},{0.431250,0.293750,0.050000,0.050000},{0.443750,0.293750,0.025000,0.025000},{0.443750,0.293750,0.050000,0.050000},{0.456250,0.293750,0.025000,0.025000},{0.456250,0.293750,0.050000,0.050000},{0.468750,0.293750,0.025000,0.025000},{0.468750,0.293750,0.050000,0.050000},{0.481250,0.293750,0.025000,0.025000},{0.481250,0.293750,0.050000,0.050000},{0.493750,0.293750,0.025000,0.025000},{0.493750,0.293750,0.050000,0.050000},{0.506250,0.293750,0.025000,0.025000},{0.506250,0.293750,0.050000,0.050000},{0.518750,0.293750,0.025000,0.025000},{0.518750,0.293750,0.050000,0.050000},{0.531250,0.293750,0.025000,0.025000},{0.531250,0.293750,0.050000,0.050000},{0.543750,0.293750,0.025000,0.025000},{0.543750,0.293750,0.050000,0.050000},{0.556250,0.293750,0.025000,0.025000},{0.556250,0.293750,0.050000,0.050000},{0.568750,0.293750,0.025000,0.025000},{0.568750,0.293750,0.050000,0.050000},{0.581250,0.293750,0.025000,0.025000},{0.581250,0.293750,0.050000,0.050000},{0.593750,0.293750,0.025000,0.025000},{0.593750,0.293750,0.050000,0.050000},{0.606250,0.293750,0.025000,0.025000},{0.606250,0.293750,0.050000,0.050000},{0.618750,0.293750,0.025000,0.025000},{0.618750,0.293750,0.050000,0.050000},{0.631250,0.293750,0.025000,0.025000},{0.631250,0.293750,0.050000,0.050000},{0.643750,0.293750,0.025000,0.025000},{0.643750,0.293750,0.050000,0.050000},{0.656250,0.293750,0.025000,0.025000},{0.656250,0.293750,0.050000,0.050000},{0.668750,0.293750,0.025000,0.025000},{0.668750,0.293750,0.050000,0.050000},{0.681250,0.293750,0.025000,0.025000},{0.681250,0.293750,0.050000,0.050000},{0.693750,0.293750,0.025000,0.025000},{0.693750,0.293750,0.050000,0.050000},{0.706250,0.293750,0.025000,0.025000},{0.706250,0.293750,0.050000,0.050000},{0.718750,0.293750,0.025000,0.025000},{0.718750,0.293750,0.050000,0.050000},{0.731250,0.293750,0.025000,0.025000},{0.731250,0.293750,0.050000,0.050000},{0.743750,0.293750,0.025000,0.025000},{0.743750,0.293750,0.050000,0.050000},{0.756250,0.293750,0.025000,0.025000},{0.756250,0.293750,0.050000,0.050000},{0.768750,0.293750,0.025000,0.025000},{0.768750,0.293750,0.050000,0.050000},{0.781250,0.293750,0.025000,0.025000},{0.781250,0.293750,0.050000,0.050000},{0.793750,0.293750,0.025000,0.025000},{0.793750,0.293750,0.050000,0.050000},{0.806250,0.293750,0.025000,0.025000},{0.806250,0.293750,0.050000,0.050000},{0.818750,0.293750,0.025000,0.025000},{0.818750,0.293750,0.050000,0.050000},{0.831250,0.293750,0.025000,0.025000},{0.831250,0.293750,0.050000,0.050000},{0.843750,0.293750,0.025000,0.025000},{0.843750,0.293750,0.050000,0.050000},{0.856250,0.293750,0.025000,0.025000},{0.856250,0.293750,0.050000,0.050000},{0.868750,0.293750,0.025000,0.025000},{0.868750,0.293750,0.050000,0.050000},{0.881250,0.293750,0.025000,0.025000},{0.881250,0.293750,0.050000,0.050000},{0.893750,0.293750,0.025000,0.025000},{0.893750,0.293750,0.050000,0.050000},{0.906250,0.293750,0.025000,0.025000},{0.906250,0.293750,0.050000,0.050000},{0.918750,0.293750,0.025000,0.025000},{0.918750,0.293750,0.050000,0.050000},{0.931250,0.293750,0.025000,0.025000},{0.931250,0.293750,0.050000,0.050000},{0.943750,0.293750,0.025000,0.025000},{0.943750,0.293750,0.050000,0.050000},{0.956250,0.293750,0.025000,0.025000},{0.956250,0.293750,0.050000,0.050000},{0.968750,0.293750,0.025000,0.025000},{0.968750,0.293750,0.050000,0.050000},{0.981250,0.293750,0.025000,0.025000},{0.981250,0.293750,0.050000,0.050000},{0.993750,0.293750,0.025000,0.025000},{0.993750,0.293750,0.050000,0.050000},{0.006250,0.306250,0.025000,0.025000},{0.006250,0.306250,0.050000,0.050000},{0.018750,0.306250,0.025000,0.025000},{0.018750,0.306250,0.050000,0.050000},{0.031250,0.306250,0.025000,0.025000},{0.031250,0.306250,0.050000,0.050000},{0.043750,0.306250,0.025000,0.025000},{0.043750,0.306250,0.050000,0.050000},{0.056250,0.306250,0.025000,0.025000},{0.056250,0.306250,0.050000,0.050000},{0.068750,0.306250,0.025000,0.025000},{0.068750,0.306250,0.050000,0.050000},{0.081250,0.306250,0.025000,0.025000},{0.081250,0.306250,0.050000,0.050000},{0.093750,0.306250,0.025000,0.025000},{0.093750,0.306250,0.050000,0.050000},{0.106250,0.306250,0.025000,0.025000},{0.106250,0.306250,0.050000,0.050000},{0.118750,0.306250,0.025000,0.025000},{0.118750,0.306250,0.050000,0.050000},{0.131250,0.306250,0.025000,0.025000},{0.131250,0.306250,0.050000,0.050000},{0.143750,0.306250,0.025000,0.025000},{0.143750,0.306250,0.050000,0.050000},{0.156250,0.306250,0.025000,0.025000},{0.156250,0.306250,0.050000,0.050000},{0.168750,0.306250,0.025000,0.025000},{0.168750,0.306250,0.050000,0.050000},{0.181250,0.306250,0.025000,0.025000},{0.181250,0.306250,0.050000,0.050000},{0.193750,0.306250,0.025000,0.025000},{0.193750,0.306250,0.050000,0.050000},{0.206250,0.306250,0.025000,0.025000},{0.206250,0.306250,0.050000,0.050000},{0.218750,0.306250,0.025000,0.025000},{0.218750,0.306250,0.050000,0.050000},{0.231250,0.306250,0.025000,0.025000},{0.231250,0.306250,0.050000,0.050000},{0.243750,0.306250,0.025000,0.025000},{0.243750,0.306250,0.050000,0.050000},{0.256250,0.306250,0.025000,0.025000},{0.256250,0.306250,0.050000,0.050000},{0.268750,0.306250,0.025000,0.025000},{0.268750,0.306250,0.050000,0.050000},{0.281250,0.306250,0.025000,0.025000},{0.281250,0.306250,0.050000,0.050000},{0.293750,0.306250,0.025000,0.025000},{0.293750,0.306250,0.050000,0.050000},{0.306250,0.306250,0.025000,0.025000},{0.306250,0.306250,0.050000,0.050000},{0.318750,0.306250,0.025000,0.025000},{0.318750,0.306250,0.050000,0.050000},{0.331250,0.306250,0.025000,0.025000},{0.331250,0.306250,0.050000,0.050000},{0.343750,0.306250,0.025000,0.025000},{0.343750,0.306250,0.050000,0.050000},{0.356250,0.306250,0.025000,0.025000},{0.356250,0.306250,0.050000,0.050000},{0.368750,0.306250,0.025000,0.025000},{0.368750,0.306250,0.050000,0.050000},{0.381250,0.306250,0.025000,0.025000},{0.381250,0.306250,0.050000,0.050000},{0.393750,0.306250,0.025000,0.025000},{0.393750,0.306250,0.050000,0.050000},{0.406250,0.306250,0.025000,0.025000},{0.406250,0.306250,0.050000,0.050000},{0.418750,0.306250,0.025000,0.025000},{0.418750,0.306250,0.050000,0.050000},{0.431250,0.306250,0.025000,0.025000},{0.431250,0.306250,0.050000,0.050000},{0.443750,0.306250,0.025000,0.025000},{0.443750,0.306250,0.050000,0.050000},{0.456250,0.306250,0.025000,0.025000},{0.456250,0.306250,0.050000,0.050000},{0.468750,0.306250,0.025000,0.025000},{0.468750,0.306250,0.050000,0.050000},{0.481250,0.306250,0.025000,0.025000},{0.481250,0.306250,0.050000,0.050000},{0.493750,0.306250,0.025000,0.025000},{0.493750,0.306250,0.050000,0.050000},{0.506250,0.306250,0.025000,0.025000},{0.506250,0.306250,0.050000,0.050000},{0.518750,0.306250,0.025000,0.025000},{0.518750,0.306250,0.050000,0.050000},{0.531250,0.306250,0.025000,0.025000},{0.531250,0.306250,0.050000,0.050000},{0.543750,0.306250,0.025000,0.025000},{0.543750,0.306250,0.050000,0.050000},{0.556250,0.306250,0.025000,0.025000},{0.556250,0.306250,0.050000,0.050000},{0.568750,0.306250,0.025000,0.025000},{0.568750,0.306250,0.050000,0.050000},{0.581250,0.306250,0.025000,0.025000},{0.581250,0.306250,0.050000,0.050000},{0.593750,0.306250,0.025000,0.025000},{0.593750,0.306250,0.050000,0.050000},{0.606250,0.306250,0.025000,0.025000},{0.606250,0.306250,0.050000,0.050000},{0.618750,0.306250,0.025000,0.025000},{0.618750,0.306250,0.050000,0.050000},{0.631250,0.306250,0.025000,0.025000},{0.631250,0.306250,0.050000,0.050000},{0.643750,0.306250,0.025000,0.025000},{0.643750,0.306250,0.050000,0.050000},{0.656250,0.306250,0.025000,0.025000},{0.656250,0.306250,0.050000,0.050000},{0.668750,0.306250,0.025000,0.025000},{0.668750,0.306250,0.050000,0.050000},{0.681250,0.306250,0.025000,0.025000},{0.681250,0.306250,0.050000,0.050000},{0.693750,0.306250,0.025000,0.025000},{0.693750,0.306250,0.050000,0.050000},{0.706250,0.306250,0.025000,0.025000},{0.706250,0.306250,0.050000,0.050000},{0.718750,0.306250,0.025000,0.025000},{0.718750,0.306250,0.050000,0.050000},{0.731250,0.306250,0.025000,0.025000},{0.731250,0.306250,0.050000,0.050000},{0.743750,0.306250,0.025000,0.025000},{0.743750,0.306250,0.050000,0.050000},{0.756250,0.306250,0.025000,0.025000},{0.756250,0.306250,0.050000,0.050000},{0.768750,0.306250,0.025000,0.025000},{0.768750,0.306250,0.050000,0.050000},{0.781250,0.306250,0.025000,0.025000},{0.781250,0.306250,0.050000,0.050000},{0.793750,0.306250,0.025000,0.025000},{0.793750,0.306250,0.050000,0.050000},{0.806250,0.306250,0.025000,0.025000},{0.806250,0.306250,0.050000,0.050000},{0.818750,0.306250,0.025000,0.025000},{0.818750,0.306250,0.050000,0.050000},{0.831250,0.306250,0.025000,0.025000},{0.831250,0.306250,0.050000,0.050000},{0.843750,0.306250,0.025000,0.025000},{0.843750,0.306250,0.050000,0.050000},{0.856250,0.306250,0.025000,0.025000},{0.856250,0.306250,0.050000,0.050000},{0.868750,0.306250,0.025000,0.025000},{0.868750,0.306250,0.050000,0.050000},{0.881250,0.306250,0.025000,0.025000},{0.881250,0.306250,0.050000,0.050000},{0.893750,0.306250,0.025000,0.025000},{0.893750,0.306250,0.050000,0.050000},{0.906250,0.306250,0.025000,0.025000},{0.906250,0.306250,0.050000,0.050000},{0.918750,0.306250,0.025000,0.025000},{0.918750,0.306250,0.050000,0.050000},{0.931250,0.306250,0.025000,0.025000},{0.931250,0.306250,0.050000,0.050000},{0.943750,0.306250,0.025000,0.025000},{0.943750,0.306250,0.050000,0.050000},{0.956250,0.306250,0.025000,0.025000},{0.956250,0.306250,0.050000,0.050000},{0.968750,0.306250,0.025000,0.025000},{0.968750,0.306250,0.050000,0.050000},{0.981250,0.306250,0.025000,0.025000},{0.981250,0.306250,0.050000,0.050000},{0.993750,0.306250,0.025000,0.025000},{0.993750,0.306250,0.050000,0.050000},{0.006250,0.318750,0.025000,0.025000},{0.006250,0.318750,0.050000,0.050000},{0.018750,0.318750,0.025000,0.025000},{0.018750,0.318750,0.050000,0.050000},{0.031250,0.318750,0.025000,0.025000},{0.031250,0.318750,0.050000,0.050000},{0.043750,0.318750,0.025000,0.025000},{0.043750,0.318750,0.050000,0.050000},{0.056250,0.318750,0.025000,0.025000},{0.056250,0.318750,0.050000,0.050000},{0.068750,0.318750,0.025000,0.025000},{0.068750,0.318750,0.050000,0.050000},{0.081250,0.318750,0.025000,0.025000},{0.081250,0.318750,0.050000,0.050000},{0.093750,0.318750,0.025000,0.025000},{0.093750,0.318750,0.050000,0.050000},{0.106250,0.318750,0.025000,0.025000},{0.106250,0.318750,0.050000,0.050000},{0.118750,0.318750,0.025000,0.025000},{0.118750,0.318750,0.050000,0.050000},{0.131250,0.318750,0.025000,0.025000},{0.131250,0.318750,0.050000,0.050000},{0.143750,0.318750,0.025000,0.025000},{0.143750,0.318750,0.050000,0.050000},{0.156250,0.318750,0.025000,0.025000},{0.156250,0.318750,0.050000,0.050000},{0.168750,0.318750,0.025000,0.025000},{0.168750,0.318750,0.050000,0.050000},{0.181250,0.318750,0.025000,0.025000},{0.181250,0.318750,0.050000,0.050000},{0.193750,0.318750,0.025000,0.025000},{0.193750,0.318750,0.050000,0.050000},{0.206250,0.318750,0.025000,0.025000},{0.206250,0.318750,0.050000,0.050000},{0.218750,0.318750,0.025000,0.025000},{0.218750,0.318750,0.050000,0.050000},{0.231250,0.318750,0.025000,0.025000},{0.231250,0.318750,0.050000,0.050000},{0.243750,0.318750,0.025000,0.025000},{0.243750,0.318750,0.050000,0.050000},{0.256250,0.318750,0.025000,0.025000},{0.256250,0.318750,0.050000,0.050000},{0.268750,0.318750,0.025000,0.025000},{0.268750,0.318750,0.050000,0.050000},{0.281250,0.318750,0.025000,0.025000},{0.281250,0.318750,0.050000,0.050000},{0.293750,0.318750,0.025000,0.025000},{0.293750,0.318750,0.050000,0.050000},{0.306250,0.318750,0.025000,0.025000},{0.306250,0.318750,0.050000,0.050000},{0.318750,0.318750,0.025000,0.025000},{0.318750,0.318750,0.050000,0.050000},{0.331250,0.318750,0.025000,0.025000},{0.331250,0.318750,0.050000,0.050000},{0.343750,0.318750,0.025000,0.025000},{0.343750,0.318750,0.050000,0.050000},{0.356250,0.318750,0.025000,0.025000},{0.356250,0.318750,0.050000,0.050000},{0.368750,0.318750,0.025000,0.025000},{0.368750,0.318750,0.050000,0.050000},{0.381250,0.318750,0.025000,0.025000},{0.381250,0.318750,0.050000,0.050000},{0.393750,0.318750,0.025000,0.025000},{0.393750,0.318750,0.050000,0.050000},{0.406250,0.318750,0.025000,0.025000},{0.406250,0.318750,0.050000,0.050000},{0.418750,0.318750,0.025000,0.025000},{0.418750,0.318750,0.050000,0.050000},{0.431250,0.318750,0.025000,0.025000},{0.431250,0.318750,0.050000,0.050000},{0.443750,0.318750,0.025000,0.025000},{0.443750,0.318750,0.050000,0.050000},{0.456250,0.318750,0.025000,0.025000},{0.456250,0.318750,0.050000,0.050000},{0.468750,0.318750,0.025000,0.025000},{0.468750,0.318750,0.050000,0.050000},{0.481250,0.318750,0.025000,0.025000},{0.481250,0.318750,0.050000,0.050000},{0.493750,0.318750,0.025000,0.025000},{0.493750,0.318750,0.050000,0.050000},{0.506250,0.318750,0.025000,0.025000},{0.506250,0.318750,0.050000,0.050000},{0.518750,0.318750,0.025000,0.025000},{0.518750,0.318750,0.050000,0.050000},{0.531250,0.318750,0.025000,0.025000},{0.531250,0.318750,0.050000,0.050000},{0.543750,0.318750,0.025000,0.025000},{0.543750,0.318750,0.050000,0.050000},{0.556250,0.318750,0.025000,0.025000},{0.556250,0.318750,0.050000,0.050000},{0.568750,0.318750,0.025000,0.025000},{0.568750,0.318750,0.050000,0.050000},{0.581250,0.318750,0.025000,0.025000},{0.581250,0.318750,0.050000,0.050000},{0.593750,0.318750,0.025000,0.025000},{0.593750,0.318750,0.050000,0.050000},{0.606250,0.318750,0.025000,0.025000},{0.606250,0.318750,0.050000,0.050000},{0.618750,0.318750,0.025000,0.025000},{0.618750,0.318750,0.050000,0.050000},{0.631250,0.318750,0.025000,0.025000},{0.631250,0.318750,0.050000,0.050000},{0.643750,0.318750,0.025000,0.025000},{0.643750,0.318750,0.050000,0.050000},{0.656250,0.318750,0.025000,0.025000},{0.656250,0.318750,0.050000,0.050000},{0.668750,0.318750,0.025000,0.025000},{0.668750,0.318750,0.050000,0.050000},{0.681250,0.318750,0.025000,0.025000},{0.681250,0.318750,0.050000,0.050000},{0.693750,0.318750,0.025000,0.025000},{0.693750,0.318750,0.050000,0.050000},{0.706250,0.318750,0.025000,0.025000},{0.706250,0.318750,0.050000,0.050000},{0.718750,0.318750,0.025000,0.025000},{0.718750,0.318750,0.050000,0.050000},{0.731250,0.318750,0.025000,0.025000},{0.731250,0.318750,0.050000,0.050000},{0.743750,0.318750,0.025000,0.025000},{0.743750,0.318750,0.050000,0.050000},{0.756250,0.318750,0.025000,0.025000},{0.756250,0.318750,0.050000,0.050000},{0.768750,0.318750,0.025000,0.025000},{0.768750,0.318750,0.050000,0.050000},{0.781250,0.318750,0.025000,0.025000},{0.781250,0.318750,0.050000,0.050000},{0.793750,0.318750,0.025000,0.025000},{0.793750,0.318750,0.050000,0.050000},{0.806250,0.318750,0.025000,0.025000},{0.806250,0.318750,0.050000,0.050000},{0.818750,0.318750,0.025000,0.025000},{0.818750,0.318750,0.050000,0.050000},{0.831250,0.318750,0.025000,0.025000},{0.831250,0.318750,0.050000,0.050000},{0.843750,0.318750,0.025000,0.025000},{0.843750,0.318750,0.050000,0.050000},{0.856250,0.318750,0.025000,0.025000},{0.856250,0.318750,0.050000,0.050000},{0.868750,0.318750,0.025000,0.025000},{0.868750,0.318750,0.050000,0.050000},{0.881250,0.318750,0.025000,0.025000},{0.881250,0.318750,0.050000,0.050000},{0.893750,0.318750,0.025000,0.025000},{0.893750,0.318750,0.050000,0.050000},{0.906250,0.318750,0.025000,0.025000},{0.906250,0.318750,0.050000,0.050000},{0.918750,0.318750,0.025000,0.025000},{0.918750,0.318750,0.050000,0.050000},{0.931250,0.318750,0.025000,0.025000},{0.931250,0.318750,0.050000,0.050000},{0.943750,0.318750,0.025000,0.025000},{0.943750,0.318750,0.050000,0.050000},{0.956250,0.318750,0.025000,0.025000},{0.956250,0.318750,0.050000,0.050000},{0.968750,0.318750,0.025000,0.025000},{0.968750,0.318750,0.050000,0.050000},{0.981250,0.318750,0.025000,0.025000},{0.981250,0.318750,0.050000,0.050000},{0.993750,0.318750,0.025000,0.025000},{0.993750,0.318750,0.050000,0.050000},{0.006250,0.331250,0.025000,0.025000},{0.006250,0.331250,0.050000,0.050000},{0.018750,0.331250,0.025000,0.025000},{0.018750,0.331250,0.050000,0.050000},{0.031250,0.331250,0.025000,0.025000},{0.031250,0.331250,0.050000,0.050000},{0.043750,0.331250,0.025000,0.025000},{0.043750,0.331250,0.050000,0.050000},{0.056250,0.331250,0.025000,0.025000},{0.056250,0.331250,0.050000,0.050000},{0.068750,0.331250,0.025000,0.025000},{0.068750,0.331250,0.050000,0.050000},{0.081250,0.331250,0.025000,0.025000},{0.081250,0.331250,0.050000,0.050000},{0.093750,0.331250,0.025000,0.025000},{0.093750,0.331250,0.050000,0.050000},{0.106250,0.331250,0.025000,0.025000},{0.106250,0.331250,0.050000,0.050000},{0.118750,0.331250,0.025000,0.025000},{0.118750,0.331250,0.050000,0.050000},{0.131250,0.331250,0.025000,0.025000},{0.131250,0.331250,0.050000,0.050000},{0.143750,0.331250,0.025000,0.025000},{0.143750,0.331250,0.050000,0.050000},{0.156250,0.331250,0.025000,0.025000},{0.156250,0.331250,0.050000,0.050000},{0.168750,0.331250,0.025000,0.025000},{0.168750,0.331250,0.050000,0.050000},{0.181250,0.331250,0.025000,0.025000},{0.181250,0.331250,0.050000,0.050000},{0.193750,0.331250,0.025000,0.025000},{0.193750,0.331250,0.050000,0.050000},{0.206250,0.331250,0.025000,0.025000},{0.206250,0.331250,0.050000,0.050000},{0.218750,0.331250,0.025000,0.025000},{0.218750,0.331250,0.050000,0.050000},{0.231250,0.331250,0.025000,0.025000},{0.231250,0.331250,0.050000,0.050000},{0.243750,0.331250,0.025000,0.025000},{0.243750,0.331250,0.050000,0.050000},{0.256250,0.331250,0.025000,0.025000},{0.256250,0.331250,0.050000,0.050000},{0.268750,0.331250,0.025000,0.025000},{0.268750,0.331250,0.050000,0.050000},{0.281250,0.331250,0.025000,0.025000},{0.281250,0.331250,0.050000,0.050000},{0.293750,0.331250,0.025000,0.025000},{0.293750,0.331250,0.050000,0.050000},{0.306250,0.331250,0.025000,0.025000},{0.306250,0.331250,0.050000,0.050000},{0.318750,0.331250,0.025000,0.025000},{0.318750,0.331250,0.050000,0.050000},{0.331250,0.331250,0.025000,0.025000},{0.331250,0.331250,0.050000,0.050000},{0.343750,0.331250,0.025000,0.025000},{0.343750,0.331250,0.050000,0.050000},{0.356250,0.331250,0.025000,0.025000},{0.356250,0.331250,0.050000,0.050000},{0.368750,0.331250,0.025000,0.025000},{0.368750,0.331250,0.050000,0.050000},{0.381250,0.331250,0.025000,0.025000},{0.381250,0.331250,0.050000,0.050000},{0.393750,0.331250,0.025000,0.025000},{0.393750,0.331250,0.050000,0.050000},{0.406250,0.331250,0.025000,0.025000},{0.406250,0.331250,0.050000,0.050000},{0.418750,0.331250,0.025000,0.025000},{0.418750,0.331250,0.050000,0.050000},{0.431250,0.331250,0.025000,0.025000},{0.431250,0.331250,0.050000,0.050000},{0.443750,0.331250,0.025000,0.025000},{0.443750,0.331250,0.050000,0.050000},{0.456250,0.331250,0.025000,0.025000},{0.456250,0.331250,0.050000,0.050000},{0.468750,0.331250,0.025000,0.025000},{0.468750,0.331250,0.050000,0.050000},{0.481250,0.331250,0.025000,0.025000},{0.481250,0.331250,0.050000,0.050000},{0.493750,0.331250,0.025000,0.025000},{0.493750,0.331250,0.050000,0.050000},{0.506250,0.331250,0.025000,0.025000},{0.506250,0.331250,0.050000,0.050000},{0.518750,0.331250,0.025000,0.025000},{0.518750,0.331250,0.050000,0.050000},{0.531250,0.331250,0.025000,0.025000},{0.531250,0.331250,0.050000,0.050000},{0.543750,0.331250,0.025000,0.025000},{0.543750,0.331250,0.050000,0.050000},{0.556250,0.331250,0.025000,0.025000},{0.556250,0.331250,0.050000,0.050000},{0.568750,0.331250,0.025000,0.025000},{0.568750,0.331250,0.050000,0.050000},{0.581250,0.331250,0.025000,0.025000},{0.581250,0.331250,0.050000,0.050000},{0.593750,0.331250,0.025000,0.025000},{0.593750,0.331250,0.050000,0.050000},{0.606250,0.331250,0.025000,0.025000},{0.606250,0.331250,0.050000,0.050000},{0.618750,0.331250,0.025000,0.025000},{0.618750,0.331250,0.050000,0.050000},{0.631250,0.331250,0.025000,0.025000},{0.631250,0.331250,0.050000,0.050000},{0.643750,0.331250,0.025000,0.025000},{0.643750,0.331250,0.050000,0.050000},{0.656250,0.331250,0.025000,0.025000},{0.656250,0.331250,0.050000,0.050000},{0.668750,0.331250,0.025000,0.025000},{0.668750,0.331250,0.050000,0.050000},{0.681250,0.331250,0.025000,0.025000},{0.681250,0.331250,0.050000,0.050000},{0.693750,0.331250,0.025000,0.025000},{0.693750,0.331250,0.050000,0.050000},{0.706250,0.331250,0.025000,0.025000},{0.706250,0.331250,0.050000,0.050000},{0.718750,0.331250,0.025000,0.025000},{0.718750,0.331250,0.050000,0.050000},{0.731250,0.331250,0.025000,0.025000},{0.731250,0.331250,0.050000,0.050000},{0.743750,0.331250,0.025000,0.025000},{0.743750,0.331250,0.050000,0.050000},{0.756250,0.331250,0.025000,0.025000},{0.756250,0.331250,0.050000,0.050000},{0.768750,0.331250,0.025000,0.025000},{0.768750,0.331250,0.050000,0.050000},{0.781250,0.331250,0.025000,0.025000},{0.781250,0.331250,0.050000,0.050000},{0.793750,0.331250,0.025000,0.025000},{0.793750,0.331250,0.050000,0.050000},{0.806250,0.331250,0.025000,0.025000},{0.806250,0.331250,0.050000,0.050000},{0.818750,0.331250,0.025000,0.025000},{0.818750,0.331250,0.050000,0.050000},{0.831250,0.331250,0.025000,0.025000},{0.831250,0.331250,0.050000,0.050000},{0.843750,0.331250,0.025000,0.025000},{0.843750,0.331250,0.050000,0.050000},{0.856250,0.331250,0.025000,0.025000},{0.856250,0.331250,0.050000,0.050000},{0.868750,0.331250,0.025000,0.025000},{0.868750,0.331250,0.050000,0.050000},{0.881250,0.331250,0.025000,0.025000},{0.881250,0.331250,0.050000,0.050000},{0.893750,0.331250,0.025000,0.025000},{0.893750,0.331250,0.050000,0.050000},{0.906250,0.331250,0.025000,0.025000},{0.906250,0.331250,0.050000,0.050000},{0.918750,0.331250,0.025000,0.025000},{0.918750,0.331250,0.050000,0.050000},{0.931250,0.331250,0.025000,0.025000},{0.931250,0.331250,0.050000,0.050000},{0.943750,0.331250,0.025000,0.025000},{0.943750,0.331250,0.050000,0.050000},{0.956250,0.331250,0.025000,0.025000},{0.956250,0.331250,0.050000,0.050000},{0.968750,0.331250,0.025000,0.025000},{0.968750,0.331250,0.050000,0.050000},{0.981250,0.331250,0.025000,0.025000},{0.981250,0.331250,0.050000,0.050000},{0.993750,0.331250,0.025000,0.025000},{0.993750,0.331250,0.050000,0.050000},{0.006250,0.343750,0.025000,0.025000},{0.006250,0.343750,0.050000,0.050000},{0.018750,0.343750,0.025000,0.025000},{0.018750,0.343750,0.050000,0.050000},{0.031250,0.343750,0.025000,0.025000},{0.031250,0.343750,0.050000,0.050000},{0.043750,0.343750,0.025000,0.025000},{0.043750,0.343750,0.050000,0.050000},{0.056250,0.343750,0.025000,0.025000},{0.056250,0.343750,0.050000,0.050000},{0.068750,0.343750,0.025000,0.025000},{0.068750,0.343750,0.050000,0.050000},{0.081250,0.343750,0.025000,0.025000},{0.081250,0.343750,0.050000,0.050000},{0.093750,0.343750,0.025000,0.025000},{0.093750,0.343750,0.050000,0.050000},{0.106250,0.343750,0.025000,0.025000},{0.106250,0.343750,0.050000,0.050000},{0.118750,0.343750,0.025000,0.025000},{0.118750,0.343750,0.050000,0.050000},{0.131250,0.343750,0.025000,0.025000},{0.131250,0.343750,0.050000,0.050000},{0.143750,0.343750,0.025000,0.025000},{0.143750,0.343750,0.050000,0.050000},{0.156250,0.343750,0.025000,0.025000},{0.156250,0.343750,0.050000,0.050000},{0.168750,0.343750,0.025000,0.025000},{0.168750,0.343750,0.050000,0.050000},{0.181250,0.343750,0.025000,0.025000},{0.181250,0.343750,0.050000,0.050000},{0.193750,0.343750,0.025000,0.025000},{0.193750,0.343750,0.050000,0.050000},{0.206250,0.343750,0.025000,0.025000},{0.206250,0.343750,0.050000,0.050000},{0.218750,0.343750,0.025000,0.025000},{0.218750,0.343750,0.050000,0.050000},{0.231250,0.343750,0.025000,0.025000},{0.231250,0.343750,0.050000,0.050000},{0.243750,0.343750,0.025000,0.025000},{0.243750,0.343750,0.050000,0.050000},{0.256250,0.343750,0.025000,0.025000},{0.256250,0.343750,0.050000,0.050000},{0.268750,0.343750,0.025000,0.025000},{0.268750,0.343750,0.050000,0.050000},{0.281250,0.343750,0.025000,0.025000},{0.281250,0.343750,0.050000,0.050000},{0.293750,0.343750,0.025000,0.025000},{0.293750,0.343750,0.050000,0.050000},{0.306250,0.343750,0.025000,0.025000},{0.306250,0.343750,0.050000,0.050000},{0.318750,0.343750,0.025000,0.025000},{0.318750,0.343750,0.050000,0.050000},{0.331250,0.343750,0.025000,0.025000},{0.331250,0.343750,0.050000,0.050000},{0.343750,0.343750,0.025000,0.025000},{0.343750,0.343750,0.050000,0.050000},{0.356250,0.343750,0.025000,0.025000},{0.356250,0.343750,0.050000,0.050000},{0.368750,0.343750,0.025000,0.025000},{0.368750,0.343750,0.050000,0.050000},{0.381250,0.343750,0.025000,0.025000},{0.381250,0.343750,0.050000,0.050000},{0.393750,0.343750,0.025000,0.025000},{0.393750,0.343750,0.050000,0.050000},{0.406250,0.343750,0.025000,0.025000},{0.406250,0.343750,0.050000,0.050000},{0.418750,0.343750,0.025000,0.025000},{0.418750,0.343750,0.050000,0.050000},{0.431250,0.343750,0.025000,0.025000},{0.431250,0.343750,0.050000,0.050000},{0.443750,0.343750,0.025000,0.025000},{0.443750,0.343750,0.050000,0.050000},{0.456250,0.343750,0.025000,0.025000},{0.456250,0.343750,0.050000,0.050000},{0.468750,0.343750,0.025000,0.025000},{0.468750,0.343750,0.050000,0.050000},{0.481250,0.343750,0.025000,0.025000},{0.481250,0.343750,0.050000,0.050000},{0.493750,0.343750,0.025000,0.025000},{0.493750,0.343750,0.050000,0.050000},{0.506250,0.343750,0.025000,0.025000},{0.506250,0.343750,0.050000,0.050000},{0.518750,0.343750,0.025000,0.025000},{0.518750,0.343750,0.050000,0.050000},{0.531250,0.343750,0.025000,0.025000},{0.531250,0.343750,0.050000,0.050000},{0.543750,0.343750,0.025000,0.025000},{0.543750,0.343750,0.050000,0.050000},{0.556250,0.343750,0.025000,0.025000},{0.556250,0.343750,0.050000,0.050000},{0.568750,0.343750,0.025000,0.025000},{0.568750,0.343750,0.050000,0.050000},{0.581250,0.343750,0.025000,0.025000},{0.581250,0.343750,0.050000,0.050000},{0.593750,0.343750,0.025000,0.025000},{0.593750,0.343750,0.050000,0.050000},{0.606250,0.343750,0.025000,0.025000},{0.606250,0.343750,0.050000,0.050000},{0.618750,0.343750,0.025000,0.025000},{0.618750,0.343750,0.050000,0.050000},{0.631250,0.343750,0.025000,0.025000},{0.631250,0.343750,0.050000,0.050000},{0.643750,0.343750,0.025000,0.025000},{0.643750,0.343750,0.050000,0.050000},{0.656250,0.343750,0.025000,0.025000},{0.656250,0.343750,0.050000,0.050000},{0.668750,0.343750,0.025000,0.025000},{0.668750,0.343750,0.050000,0.050000},{0.681250,0.343750,0.025000,0.025000},{0.681250,0.343750,0.050000,0.050000},{0.693750,0.343750,0.025000,0.025000},{0.693750,0.343750,0.050000,0.050000},{0.706250,0.343750,0.025000,0.025000},{0.706250,0.343750,0.050000,0.050000},{0.718750,0.343750,0.025000,0.025000},{0.718750,0.343750,0.050000,0.050000},{0.731250,0.343750,0.025000,0.025000},{0.731250,0.343750,0.050000,0.050000},{0.743750,0.343750,0.025000,0.025000},{0.743750,0.343750,0.050000,0.050000},{0.756250,0.343750,0.025000,0.025000},{0.756250,0.343750,0.050000,0.050000},{0.768750,0.343750,0.025000,0.025000},{0.768750,0.343750,0.050000,0.050000},{0.781250,0.343750,0.025000,0.025000},{0.781250,0.343750,0.050000,0.050000},{0.793750,0.343750,0.025000,0.025000},{0.793750,0.343750,0.050000,0.050000},{0.806250,0.343750,0.025000,0.025000},{0.806250,0.343750,0.050000,0.050000},{0.818750,0.343750,0.025000,0.025000},{0.818750,0.343750,0.050000,0.050000},{0.831250,0.343750,0.025000,0.025000},{0.831250,0.343750,0.050000,0.050000},{0.843750,0.343750,0.025000,0.025000},{0.843750,0.343750,0.050000,0.050000},{0.856250,0.343750,0.025000,0.025000},{0.856250,0.343750,0.050000,0.050000},{0.868750,0.343750,0.025000,0.025000},{0.868750,0.343750,0.050000,0.050000},{0.881250,0.343750,0.025000,0.025000},{0.881250,0.343750,0.050000,0.050000},{0.893750,0.343750,0.025000,0.025000},{0.893750,0.343750,0.050000,0.050000},{0.906250,0.343750,0.025000,0.025000},{0.906250,0.343750,0.050000,0.050000},{0.918750,0.343750,0.025000,0.025000},{0.918750,0.343750,0.050000,0.050000},{0.931250,0.343750,0.025000,0.025000},{0.931250,0.343750,0.050000,0.050000},{0.943750,0.343750,0.025000,0.025000},{0.943750,0.343750,0.050000,0.050000},{0.956250,0.343750,0.025000,0.025000},{0.956250,0.343750,0.050000,0.050000},{0.968750,0.343750,0.025000,0.025000},{0.968750,0.343750,0.050000,0.050000},{0.981250,0.343750,0.025000,0.025000},{0.981250,0.343750,0.050000,0.050000},{0.993750,0.343750,0.025000,0.025000},{0.993750,0.343750,0.050000,0.050000},{0.006250,0.356250,0.025000,0.025000},{0.006250,0.356250,0.050000,0.050000},{0.018750,0.356250,0.025000,0.025000},{0.018750,0.356250,0.050000,0.050000},{0.031250,0.356250,0.025000,0.025000},{0.031250,0.356250,0.050000,0.050000},{0.043750,0.356250,0.025000,0.025000},{0.043750,0.356250,0.050000,0.050000},{0.056250,0.356250,0.025000,0.025000},{0.056250,0.356250,0.050000,0.050000},{0.068750,0.356250,0.025000,0.025000},{0.068750,0.356250,0.050000,0.050000},{0.081250,0.356250,0.025000,0.025000},{0.081250,0.356250,0.050000,0.050000},{0.093750,0.356250,0.025000,0.025000},{0.093750,0.356250,0.050000,0.050000},{0.106250,0.356250,0.025000,0.025000},{0.106250,0.356250,0.050000,0.050000},{0.118750,0.356250,0.025000,0.025000},{0.118750,0.356250,0.050000,0.050000},{0.131250,0.356250,0.025000,0.025000},{0.131250,0.356250,0.050000,0.050000},{0.143750,0.356250,0.025000,0.025000},{0.143750,0.356250,0.050000,0.050000},{0.156250,0.356250,0.025000,0.025000},{0.156250,0.356250,0.050000,0.050000},{0.168750,0.356250,0.025000,0.025000},{0.168750,0.356250,0.050000,0.050000},{0.181250,0.356250,0.025000,0.025000},{0.181250,0.356250,0.050000,0.050000},{0.193750,0.356250,0.025000,0.025000},{0.193750,0.356250,0.050000,0.050000},{0.206250,0.356250,0.025000,0.025000},{0.206250,0.356250,0.050000,0.050000},{0.218750,0.356250,0.025000,0.025000},{0.218750,0.356250,0.050000,0.050000},{0.231250,0.356250,0.025000,0.025000},{0.231250,0.356250,0.050000,0.050000},{0.243750,0.356250,0.025000,0.025000},{0.243750,0.356250,0.050000,0.050000},{0.256250,0.356250,0.025000,0.025000},{0.256250,0.356250,0.050000,0.050000},{0.268750,0.356250,0.025000,0.025000},{0.268750,0.356250,0.050000,0.050000},{0.281250,0.356250,0.025000,0.025000},{0.281250,0.356250,0.050000,0.050000},{0.293750,0.356250,0.025000,0.025000},{0.293750,0.356250,0.050000,0.050000},{0.306250,0.356250,0.025000,0.025000},{0.306250,0.356250,0.050000,0.050000},{0.318750,0.356250,0.025000,0.025000},{0.318750,0.356250,0.050000,0.050000},{0.331250,0.356250,0.025000,0.025000},{0.331250,0.356250,0.050000,0.050000},{0.343750,0.356250,0.025000,0.025000},{0.343750,0.356250,0.050000,0.050000},{0.356250,0.356250,0.025000,0.025000},{0.356250,0.356250,0.050000,0.050000},{0.368750,0.356250,0.025000,0.025000},{0.368750,0.356250,0.050000,0.050000},{0.381250,0.356250,0.025000,0.025000},{0.381250,0.356250,0.050000,0.050000},{0.393750,0.356250,0.025000,0.025000},{0.393750,0.356250,0.050000,0.050000},{0.406250,0.356250,0.025000,0.025000},{0.406250,0.356250,0.050000,0.050000},{0.418750,0.356250,0.025000,0.025000},{0.418750,0.356250,0.050000,0.050000},{0.431250,0.356250,0.025000,0.025000},{0.431250,0.356250,0.050000,0.050000},{0.443750,0.356250,0.025000,0.025000},{0.443750,0.356250,0.050000,0.050000},{0.456250,0.356250,0.025000,0.025000},{0.456250,0.356250,0.050000,0.050000},{0.468750,0.356250,0.025000,0.025000},{0.468750,0.356250,0.050000,0.050000},{0.481250,0.356250,0.025000,0.025000},{0.481250,0.356250,0.050000,0.050000},{0.493750,0.356250,0.025000,0.025000},{0.493750,0.356250,0.050000,0.050000},{0.506250,0.356250,0.025000,0.025000},{0.506250,0.356250,0.050000,0.050000},{0.518750,0.356250,0.025000,0.025000},{0.518750,0.356250,0.050000,0.050000},{0.531250,0.356250,0.025000,0.025000},{0.531250,0.356250,0.050000,0.050000},{0.543750,0.356250,0.025000,0.025000},{0.543750,0.356250,0.050000,0.050000},{0.556250,0.356250,0.025000,0.025000},{0.556250,0.356250,0.050000,0.050000},{0.568750,0.356250,0.025000,0.025000},{0.568750,0.356250,0.050000,0.050000},{0.581250,0.356250,0.025000,0.025000},{0.581250,0.356250,0.050000,0.050000},{0.593750,0.356250,0.025000,0.025000},{0.593750,0.356250,0.050000,0.050000},{0.606250,0.356250,0.025000,0.025000},{0.606250,0.356250,0.050000,0.050000},{0.618750,0.356250,0.025000,0.025000},{0.618750,0.356250,0.050000,0.050000},{0.631250,0.356250,0.025000,0.025000},{0.631250,0.356250,0.050000,0.050000},{0.643750,0.356250,0.025000,0.025000},{0.643750,0.356250,0.050000,0.050000},{0.656250,0.356250,0.025000,0.025000},{0.656250,0.356250,0.050000,0.050000},{0.668750,0.356250,0.025000,0.025000},{0.668750,0.356250,0.050000,0.050000},{0.681250,0.356250,0.025000,0.025000},{0.681250,0.356250,0.050000,0.050000},{0.693750,0.356250,0.025000,0.025000},{0.693750,0.356250,0.050000,0.050000},{0.706250,0.356250,0.025000,0.025000},{0.706250,0.356250,0.050000,0.050000},{0.718750,0.356250,0.025000,0.025000},{0.718750,0.356250,0.050000,0.050000},{0.731250,0.356250,0.025000,0.025000},{0.731250,0.356250,0.050000,0.050000},{0.743750,0.356250,0.025000,0.025000},{0.743750,0.356250,0.050000,0.050000},{0.756250,0.356250,0.025000,0.025000},{0.756250,0.356250,0.050000,0.050000},{0.768750,0.356250,0.025000,0.025000},{0.768750,0.356250,0.050000,0.050000},{0.781250,0.356250,0.025000,0.025000},{0.781250,0.356250,0.050000,0.050000},{0.793750,0.356250,0.025000,0.025000},{0.793750,0.356250,0.050000,0.050000},{0.806250,0.356250,0.025000,0.025000},{0.806250,0.356250,0.050000,0.050000},{0.818750,0.356250,0.025000,0.025000},{0.818750,0.356250,0.050000,0.050000},{0.831250,0.356250,0.025000,0.025000},{0.831250,0.356250,0.050000,0.050000},{0.843750,0.356250,0.025000,0.025000},{0.843750,0.356250,0.050000,0.050000},{0.856250,0.356250,0.025000,0.025000},{0.856250,0.356250,0.050000,0.050000},{0.868750,0.356250,0.025000,0.025000},{0.868750,0.356250,0.050000,0.050000},{0.881250,0.356250,0.025000,0.025000},{0.881250,0.356250,0.050000,0.050000},{0.893750,0.356250,0.025000,0.025000},{0.893750,0.356250,0.050000,0.050000},{0.906250,0.356250,0.025000,0.025000},{0.906250,0.356250,0.050000,0.050000},{0.918750,0.356250,0.025000,0.025000},{0.918750,0.356250,0.050000,0.050000},{0.931250,0.356250,0.025000,0.025000},{0.931250,0.356250,0.050000,0.050000},{0.943750,0.356250,0.025000,0.025000},{0.943750,0.356250,0.050000,0.050000},{0.956250,0.356250,0.025000,0.025000},{0.956250,0.356250,0.050000,0.050000},{0.968750,0.356250,0.025000,0.025000},{0.968750,0.356250,0.050000,0.050000},{0.981250,0.356250,0.025000,0.025000},{0.981250,0.356250,0.050000,0.050000},{0.993750,0.356250,0.025000,0.025000},{0.993750,0.356250,0.050000,0.050000},{0.006250,0.368750,0.025000,0.025000},{0.006250,0.368750,0.050000,0.050000},{0.018750,0.368750,0.025000,0.025000},{0.018750,0.368750,0.050000,0.050000},{0.031250,0.368750,0.025000,0.025000},{0.031250,0.368750,0.050000,0.050000},{0.043750,0.368750,0.025000,0.025000},{0.043750,0.368750,0.050000,0.050000},{0.056250,0.368750,0.025000,0.025000},{0.056250,0.368750,0.050000,0.050000},{0.068750,0.368750,0.025000,0.025000},{0.068750,0.368750,0.050000,0.050000},{0.081250,0.368750,0.025000,0.025000},{0.081250,0.368750,0.050000,0.050000},{0.093750,0.368750,0.025000,0.025000},{0.093750,0.368750,0.050000,0.050000},{0.106250,0.368750,0.025000,0.025000},{0.106250,0.368750,0.050000,0.050000},{0.118750,0.368750,0.025000,0.025000},{0.118750,0.368750,0.050000,0.050000},{0.131250,0.368750,0.025000,0.025000},{0.131250,0.368750,0.050000,0.050000},{0.143750,0.368750,0.025000,0.025000},{0.143750,0.368750,0.050000,0.050000},{0.156250,0.368750,0.025000,0.025000},{0.156250,0.368750,0.050000,0.050000},{0.168750,0.368750,0.025000,0.025000},{0.168750,0.368750,0.050000,0.050000},{0.181250,0.368750,0.025000,0.025000},{0.181250,0.368750,0.050000,0.050000},{0.193750,0.368750,0.025000,0.025000},{0.193750,0.368750,0.050000,0.050000},{0.206250,0.368750,0.025000,0.025000},{0.206250,0.368750,0.050000,0.050000},{0.218750,0.368750,0.025000,0.025000},{0.218750,0.368750,0.050000,0.050000},{0.231250,0.368750,0.025000,0.025000},{0.231250,0.368750,0.050000,0.050000},{0.243750,0.368750,0.025000,0.025000},{0.243750,0.368750,0.050000,0.050000},{0.256250,0.368750,0.025000,0.025000},{0.256250,0.368750,0.050000,0.050000},{0.268750,0.368750,0.025000,0.025000},{0.268750,0.368750,0.050000,0.050000},{0.281250,0.368750,0.025000,0.025000},{0.281250,0.368750,0.050000,0.050000},{0.293750,0.368750,0.025000,0.025000},{0.293750,0.368750,0.050000,0.050000},{0.306250,0.368750,0.025000,0.025000},{0.306250,0.368750,0.050000,0.050000},{0.318750,0.368750,0.025000,0.025000},{0.318750,0.368750,0.050000,0.050000},{0.331250,0.368750,0.025000,0.025000},{0.331250,0.368750,0.050000,0.050000},{0.343750,0.368750,0.025000,0.025000},{0.343750,0.368750,0.050000,0.050000},{0.356250,0.368750,0.025000,0.025000},{0.356250,0.368750,0.050000,0.050000},{0.368750,0.368750,0.025000,0.025000},{0.368750,0.368750,0.050000,0.050000},{0.381250,0.368750,0.025000,0.025000},{0.381250,0.368750,0.050000,0.050000},{0.393750,0.368750,0.025000,0.025000},{0.393750,0.368750,0.050000,0.050000},{0.406250,0.368750,0.025000,0.025000},{0.406250,0.368750,0.050000,0.050000},{0.418750,0.368750,0.025000,0.025000},{0.418750,0.368750,0.050000,0.050000},{0.431250,0.368750,0.025000,0.025000},{0.431250,0.368750,0.050000,0.050000},{0.443750,0.368750,0.025000,0.025000},{0.443750,0.368750,0.050000,0.050000},{0.456250,0.368750,0.025000,0.025000},{0.456250,0.368750,0.050000,0.050000},{0.468750,0.368750,0.025000,0.025000},{0.468750,0.368750,0.050000,0.050000},{0.481250,0.368750,0.025000,0.025000},{0.481250,0.368750,0.050000,0.050000},{0.493750,0.368750,0.025000,0.025000},{0.493750,0.368750,0.050000,0.050000},{0.506250,0.368750,0.025000,0.025000},{0.506250,0.368750,0.050000,0.050000},{0.518750,0.368750,0.025000,0.025000},{0.518750,0.368750,0.050000,0.050000},{0.531250,0.368750,0.025000,0.025000},{0.531250,0.368750,0.050000,0.050000},{0.543750,0.368750,0.025000,0.025000},{0.543750,0.368750,0.050000,0.050000},{0.556250,0.368750,0.025000,0.025000},{0.556250,0.368750,0.050000,0.050000},{0.568750,0.368750,0.025000,0.025000},{0.568750,0.368750,0.050000,0.050000},{0.581250,0.368750,0.025000,0.025000},{0.581250,0.368750,0.050000,0.050000},{0.593750,0.368750,0.025000,0.025000},{0.593750,0.368750,0.050000,0.050000},{0.606250,0.368750,0.025000,0.025000},{0.606250,0.368750,0.050000,0.050000},{0.618750,0.368750,0.025000,0.025000},{0.618750,0.368750,0.050000,0.050000},{0.631250,0.368750,0.025000,0.025000},{0.631250,0.368750,0.050000,0.050000},{0.643750,0.368750,0.025000,0.025000},{0.643750,0.368750,0.050000,0.050000},{0.656250,0.368750,0.025000,0.025000},{0.656250,0.368750,0.050000,0.050000},{0.668750,0.368750,0.025000,0.025000},{0.668750,0.368750,0.050000,0.050000},{0.681250,0.368750,0.025000,0.025000},{0.681250,0.368750,0.050000,0.050000},{0.693750,0.368750,0.025000,0.025000},{0.693750,0.368750,0.050000,0.050000},{0.706250,0.368750,0.025000,0.025000},{0.706250,0.368750,0.050000,0.050000},{0.718750,0.368750,0.025000,0.025000},{0.718750,0.368750,0.050000,0.050000},{0.731250,0.368750,0.025000,0.025000},{0.731250,0.368750,0.050000,0.050000},{0.743750,0.368750,0.025000,0.025000},{0.743750,0.368750,0.050000,0.050000},{0.756250,0.368750,0.025000,0.025000},{0.756250,0.368750,0.050000,0.050000},{0.768750,0.368750,0.025000,0.025000},{0.768750,0.368750,0.050000,0.050000},{0.781250,0.368750,0.025000,0.025000},{0.781250,0.368750,0.050000,0.050000},{0.793750,0.368750,0.025000,0.025000},{0.793750,0.368750,0.050000,0.050000},{0.806250,0.368750,0.025000,0.025000},{0.806250,0.368750,0.050000,0.050000},{0.818750,0.368750,0.025000,0.025000},{0.818750,0.368750,0.050000,0.050000},{0.831250,0.368750,0.025000,0.025000},{0.831250,0.368750,0.050000,0.050000},{0.843750,0.368750,0.025000,0.025000},{0.843750,0.368750,0.050000,0.050000},{0.856250,0.368750,0.025000,0.025000},{0.856250,0.368750,0.050000,0.050000},{0.868750,0.368750,0.025000,0.025000},{0.868750,0.368750,0.050000,0.050000},{0.881250,0.368750,0.025000,0.025000},{0.881250,0.368750,0.050000,0.050000},{0.893750,0.368750,0.025000,0.025000},{0.893750,0.368750,0.050000,0.050000},{0.906250,0.368750,0.025000,0.025000},{0.906250,0.368750,0.050000,0.050000},{0.918750,0.368750,0.025000,0.025000},{0.918750,0.368750,0.050000,0.050000},{0.931250,0.368750,0.025000,0.025000},{0.931250,0.368750,0.050000,0.050000},{0.943750,0.368750,0.025000,0.025000},{0.943750,0.368750,0.050000,0.050000},{0.956250,0.368750,0.025000,0.025000},{0.956250,0.368750,0.050000,0.050000},{0.968750,0.368750,0.025000,0.025000},{0.968750,0.368750,0.050000,0.050000},{0.981250,0.368750,0.025000,0.025000},{0.981250,0.368750,0.050000,0.050000},{0.993750,0.368750,0.025000,0.025000},{0.993750,0.368750,0.050000,0.050000},{0.006250,0.381250,0.025000,0.025000},{0.006250,0.381250,0.050000,0.050000},{0.018750,0.381250,0.025000,0.025000},{0.018750,0.381250,0.050000,0.050000},{0.031250,0.381250,0.025000,0.025000},{0.031250,0.381250,0.050000,0.050000},{0.043750,0.381250,0.025000,0.025000},{0.043750,0.381250,0.050000,0.050000},{0.056250,0.381250,0.025000,0.025000},{0.056250,0.381250,0.050000,0.050000},{0.068750,0.381250,0.025000,0.025000},{0.068750,0.381250,0.050000,0.050000},{0.081250,0.381250,0.025000,0.025000},{0.081250,0.381250,0.050000,0.050000},{0.093750,0.381250,0.025000,0.025000},{0.093750,0.381250,0.050000,0.050000},{0.106250,0.381250,0.025000,0.025000},{0.106250,0.381250,0.050000,0.050000},{0.118750,0.381250,0.025000,0.025000},{0.118750,0.381250,0.050000,0.050000},{0.131250,0.381250,0.025000,0.025000},{0.131250,0.381250,0.050000,0.050000},{0.143750,0.381250,0.025000,0.025000},{0.143750,0.381250,0.050000,0.050000},{0.156250,0.381250,0.025000,0.025000},{0.156250,0.381250,0.050000,0.050000},{0.168750,0.381250,0.025000,0.025000},{0.168750,0.381250,0.050000,0.050000},{0.181250,0.381250,0.025000,0.025000},{0.181250,0.381250,0.050000,0.050000},{0.193750,0.381250,0.025000,0.025000},{0.193750,0.381250,0.050000,0.050000},{0.206250,0.381250,0.025000,0.025000},{0.206250,0.381250,0.050000,0.050000},{0.218750,0.381250,0.025000,0.025000},{0.218750,0.381250,0.050000,0.050000},{0.231250,0.381250,0.025000,0.025000},{0.231250,0.381250,0.050000,0.050000},{0.243750,0.381250,0.025000,0.025000},{0.243750,0.381250,0.050000,0.050000},{0.256250,0.381250,0.025000,0.025000},{0.256250,0.381250,0.050000,0.050000},{0.268750,0.381250,0.025000,0.025000},{0.268750,0.381250,0.050000,0.050000},{0.281250,0.381250,0.025000,0.025000},{0.281250,0.381250,0.050000,0.050000},{0.293750,0.381250,0.025000,0.025000},{0.293750,0.381250,0.050000,0.050000},{0.306250,0.381250,0.025000,0.025000},{0.306250,0.381250,0.050000,0.050000},{0.318750,0.381250,0.025000,0.025000},{0.318750,0.381250,0.050000,0.050000},{0.331250,0.381250,0.025000,0.025000},{0.331250,0.381250,0.050000,0.050000},{0.343750,0.381250,0.025000,0.025000},{0.343750,0.381250,0.050000,0.050000},{0.356250,0.381250,0.025000,0.025000},{0.356250,0.381250,0.050000,0.050000},{0.368750,0.381250,0.025000,0.025000},{0.368750,0.381250,0.050000,0.050000},{0.381250,0.381250,0.025000,0.025000},{0.381250,0.381250,0.050000,0.050000},{0.393750,0.381250,0.025000,0.025000},{0.393750,0.381250,0.050000,0.050000},{0.406250,0.381250,0.025000,0.025000},{0.406250,0.381250,0.050000,0.050000},{0.418750,0.381250,0.025000,0.025000},{0.418750,0.381250,0.050000,0.050000},{0.431250,0.381250,0.025000,0.025000},{0.431250,0.381250,0.050000,0.050000},{0.443750,0.381250,0.025000,0.025000},{0.443750,0.381250,0.050000,0.050000},{0.456250,0.381250,0.025000,0.025000},{0.456250,0.381250,0.050000,0.050000},{0.468750,0.381250,0.025000,0.025000},{0.468750,0.381250,0.050000,0.050000},{0.481250,0.381250,0.025000,0.025000},{0.481250,0.381250,0.050000,0.050000},{0.493750,0.381250,0.025000,0.025000},{0.493750,0.381250,0.050000,0.050000},{0.506250,0.381250,0.025000,0.025000},{0.506250,0.381250,0.050000,0.050000},{0.518750,0.381250,0.025000,0.025000},{0.518750,0.381250,0.050000,0.050000},{0.531250,0.381250,0.025000,0.025000},{0.531250,0.381250,0.050000,0.050000},{0.543750,0.381250,0.025000,0.025000},{0.543750,0.381250,0.050000,0.050000},{0.556250,0.381250,0.025000,0.025000},{0.556250,0.381250,0.050000,0.050000},{0.568750,0.381250,0.025000,0.025000},{0.568750,0.381250,0.050000,0.050000},{0.581250,0.381250,0.025000,0.025000},{0.581250,0.381250,0.050000,0.050000},{0.593750,0.381250,0.025000,0.025000},{0.593750,0.381250,0.050000,0.050000},{0.606250,0.381250,0.025000,0.025000},{0.606250,0.381250,0.050000,0.050000},{0.618750,0.381250,0.025000,0.025000},{0.618750,0.381250,0.050000,0.050000},{0.631250,0.381250,0.025000,0.025000},{0.631250,0.381250,0.050000,0.050000},{0.643750,0.381250,0.025000,0.025000},{0.643750,0.381250,0.050000,0.050000},{0.656250,0.381250,0.025000,0.025000},{0.656250,0.381250,0.050000,0.050000},{0.668750,0.381250,0.025000,0.025000},{0.668750,0.381250,0.050000,0.050000},{0.681250,0.381250,0.025000,0.025000},{0.681250,0.381250,0.050000,0.050000},{0.693750,0.381250,0.025000,0.025000},{0.693750,0.381250,0.050000,0.050000},{0.706250,0.381250,0.025000,0.025000},{0.706250,0.381250,0.050000,0.050000},{0.718750,0.381250,0.025000,0.025000},{0.718750,0.381250,0.050000,0.050000},{0.731250,0.381250,0.025000,0.025000},{0.731250,0.381250,0.050000,0.050000},{0.743750,0.381250,0.025000,0.025000},{0.743750,0.381250,0.050000,0.050000},{0.756250,0.381250,0.025000,0.025000},{0.756250,0.381250,0.050000,0.050000},{0.768750,0.381250,0.025000,0.025000},{0.768750,0.381250,0.050000,0.050000},{0.781250,0.381250,0.025000,0.025000},{0.781250,0.381250,0.050000,0.050000},{0.793750,0.381250,0.025000,0.025000},{0.793750,0.381250,0.050000,0.050000},{0.806250,0.381250,0.025000,0.025000},{0.806250,0.381250,0.050000,0.050000},{0.818750,0.381250,0.025000,0.025000},{0.818750,0.381250,0.050000,0.050000},{0.831250,0.381250,0.025000,0.025000},{0.831250,0.381250,0.050000,0.050000},{0.843750,0.381250,0.025000,0.025000},{0.843750,0.381250,0.050000,0.050000},{0.856250,0.381250,0.025000,0.025000},{0.856250,0.381250,0.050000,0.050000},{0.868750,0.381250,0.025000,0.025000},{0.868750,0.381250,0.050000,0.050000},{0.881250,0.381250,0.025000,0.025000},{0.881250,0.381250,0.050000,0.050000},{0.893750,0.381250,0.025000,0.025000},{0.893750,0.381250,0.050000,0.050000},{0.906250,0.381250,0.025000,0.025000},{0.906250,0.381250,0.050000,0.050000},{0.918750,0.381250,0.025000,0.025000},{0.918750,0.381250,0.050000,0.050000},{0.931250,0.381250,0.025000,0.025000},{0.931250,0.381250,0.050000,0.050000},{0.943750,0.381250,0.025000,0.025000},{0.943750,0.381250,0.050000,0.050000},{0.956250,0.381250,0.025000,0.025000},{0.956250,0.381250,0.050000,0.050000},{0.968750,0.381250,0.025000,0.025000},{0.968750,0.381250,0.050000,0.050000},{0.981250,0.381250,0.025000,0.025000},{0.981250,0.381250,0.050000,0.050000},{0.993750,0.381250,0.025000,0.025000},{0.993750,0.381250,0.050000,0.050000},{0.006250,0.393750,0.025000,0.025000},{0.006250,0.393750,0.050000,0.050000},{0.018750,0.393750,0.025000,0.025000},{0.018750,0.393750,0.050000,0.050000},{0.031250,0.393750,0.025000,0.025000},{0.031250,0.393750,0.050000,0.050000},{0.043750,0.393750,0.025000,0.025000},{0.043750,0.393750,0.050000,0.050000},{0.056250,0.393750,0.025000,0.025000},{0.056250,0.393750,0.050000,0.050000},{0.068750,0.393750,0.025000,0.025000},{0.068750,0.393750,0.050000,0.050000},{0.081250,0.393750,0.025000,0.025000},{0.081250,0.393750,0.050000,0.050000},{0.093750,0.393750,0.025000,0.025000},{0.093750,0.393750,0.050000,0.050000},{0.106250,0.393750,0.025000,0.025000},{0.106250,0.393750,0.050000,0.050000},{0.118750,0.393750,0.025000,0.025000},{0.118750,0.393750,0.050000,0.050000},{0.131250,0.393750,0.025000,0.025000},{0.131250,0.393750,0.050000,0.050000},{0.143750,0.393750,0.025000,0.025000},{0.143750,0.393750,0.050000,0.050000},{0.156250,0.393750,0.025000,0.025000},{0.156250,0.393750,0.050000,0.050000},{0.168750,0.393750,0.025000,0.025000},{0.168750,0.393750,0.050000,0.050000},{0.181250,0.393750,0.025000,0.025000},{0.181250,0.393750,0.050000,0.050000},{0.193750,0.393750,0.025000,0.025000},{0.193750,0.393750,0.050000,0.050000},{0.206250,0.393750,0.025000,0.025000},{0.206250,0.393750,0.050000,0.050000},{0.218750,0.393750,0.025000,0.025000},{0.218750,0.393750,0.050000,0.050000},{0.231250,0.393750,0.025000,0.025000},{0.231250,0.393750,0.050000,0.050000},{0.243750,0.393750,0.025000,0.025000},{0.243750,0.393750,0.050000,0.050000},{0.256250,0.393750,0.025000,0.025000},{0.256250,0.393750,0.050000,0.050000},{0.268750,0.393750,0.025000,0.025000},{0.268750,0.393750,0.050000,0.050000},{0.281250,0.393750,0.025000,0.025000},{0.281250,0.393750,0.050000,0.050000},{0.293750,0.393750,0.025000,0.025000},{0.293750,0.393750,0.050000,0.050000},{0.306250,0.393750,0.025000,0.025000},{0.306250,0.393750,0.050000,0.050000},{0.318750,0.393750,0.025000,0.025000},{0.318750,0.393750,0.050000,0.050000},{0.331250,0.393750,0.025000,0.025000},{0.331250,0.393750,0.050000,0.050000},{0.343750,0.393750,0.025000,0.025000},{0.343750,0.393750,0.050000,0.050000},{0.356250,0.393750,0.025000,0.025000},{0.356250,0.393750,0.050000,0.050000},{0.368750,0.393750,0.025000,0.025000},{0.368750,0.393750,0.050000,0.050000},{0.381250,0.393750,0.025000,0.025000},{0.381250,0.393750,0.050000,0.050000},{0.393750,0.393750,0.025000,0.025000},{0.393750,0.393750,0.050000,0.050000},{0.406250,0.393750,0.025000,0.025000},{0.406250,0.393750,0.050000,0.050000},{0.418750,0.393750,0.025000,0.025000},{0.418750,0.393750,0.050000,0.050000},{0.431250,0.393750,0.025000,0.025000},{0.431250,0.393750,0.050000,0.050000},{0.443750,0.393750,0.025000,0.025000},{0.443750,0.393750,0.050000,0.050000},{0.456250,0.393750,0.025000,0.025000},{0.456250,0.393750,0.050000,0.050000},{0.468750,0.393750,0.025000,0.025000},{0.468750,0.393750,0.050000,0.050000},{0.481250,0.393750,0.025000,0.025000},{0.481250,0.393750,0.050000,0.050000},{0.493750,0.393750,0.025000,0.025000},{0.493750,0.393750,0.050000,0.050000},{0.506250,0.393750,0.025000,0.025000},{0.506250,0.393750,0.050000,0.050000},{0.518750,0.393750,0.025000,0.025000},{0.518750,0.393750,0.050000,0.050000},{0.531250,0.393750,0.025000,0.025000},{0.531250,0.393750,0.050000,0.050000},{0.543750,0.393750,0.025000,0.025000},{0.543750,0.393750,0.050000,0.050000},{0.556250,0.393750,0.025000,0.025000},{0.556250,0.393750,0.050000,0.050000},{0.568750,0.393750,0.025000,0.025000},{0.568750,0.393750,0.050000,0.050000},{0.581250,0.393750,0.025000,0.025000},{0.581250,0.393750,0.050000,0.050000},{0.593750,0.393750,0.025000,0.025000},{0.593750,0.393750,0.050000,0.050000},{0.606250,0.393750,0.025000,0.025000},{0.606250,0.393750,0.050000,0.050000},{0.618750,0.393750,0.025000,0.025000},{0.618750,0.393750,0.050000,0.050000},{0.631250,0.393750,0.025000,0.025000},{0.631250,0.393750,0.050000,0.050000},{0.643750,0.393750,0.025000,0.025000},{0.643750,0.393750,0.050000,0.050000},{0.656250,0.393750,0.025000,0.025000},{0.656250,0.393750,0.050000,0.050000},{0.668750,0.393750,0.025000,0.025000},{0.668750,0.393750,0.050000,0.050000},{0.681250,0.393750,0.025000,0.025000},{0.681250,0.393750,0.050000,0.050000},{0.693750,0.393750,0.025000,0.025000},{0.693750,0.393750,0.050000,0.050000},{0.706250,0.393750,0.025000,0.025000},{0.706250,0.393750,0.050000,0.050000},{0.718750,0.393750,0.025000,0.025000},{0.718750,0.393750,0.050000,0.050000},{0.731250,0.393750,0.025000,0.025000},{0.731250,0.393750,0.050000,0.050000},{0.743750,0.393750,0.025000,0.025000},{0.743750,0.393750,0.050000,0.050000},{0.756250,0.393750,0.025000,0.025000},{0.756250,0.393750,0.050000,0.050000},{0.768750,0.393750,0.025000,0.025000},{0.768750,0.393750,0.050000,0.050000},{0.781250,0.393750,0.025000,0.025000},{0.781250,0.393750,0.050000,0.050000},{0.793750,0.393750,0.025000,0.025000},{0.793750,0.393750,0.050000,0.050000},{0.806250,0.393750,0.025000,0.025000},{0.806250,0.393750,0.050000,0.050000},{0.818750,0.393750,0.025000,0.025000},{0.818750,0.393750,0.050000,0.050000},{0.831250,0.393750,0.025000,0.025000},{0.831250,0.393750,0.050000,0.050000},{0.843750,0.393750,0.025000,0.025000},{0.843750,0.393750,0.050000,0.050000},{0.856250,0.393750,0.025000,0.025000},{0.856250,0.393750,0.050000,0.050000},{0.868750,0.393750,0.025000,0.025000},{0.868750,0.393750,0.050000,0.050000},{0.881250,0.393750,0.025000,0.025000},{0.881250,0.393750,0.050000,0.050000},{0.893750,0.393750,0.025000,0.025000},{0.893750,0.393750,0.050000,0.050000},{0.906250,0.393750,0.025000,0.025000},{0.906250,0.393750,0.050000,0.050000},{0.918750,0.393750,0.025000,0.025000},{0.918750,0.393750,0.050000,0.050000},{0.931250,0.393750,0.025000,0.025000},{0.931250,0.393750,0.050000,0.050000},{0.943750,0.393750,0.025000,0.025000},{0.943750,0.393750,0.050000,0.050000},{0.956250,0.393750,0.025000,0.025000},{0.956250,0.393750,0.050000,0.050000},{0.968750,0.393750,0.025000,0.025000},{0.968750,0.393750,0.050000,0.050000},{0.981250,0.393750,0.025000,0.025000},{0.981250,0.393750,0.050000,0.050000},{0.993750,0.393750,0.025000,0.025000},{0.993750,0.393750,0.050000,0.050000},{0.006250,0.406250,0.025000,0.025000},{0.006250,0.406250,0.050000,0.050000},{0.018750,0.406250,0.025000,0.025000},{0.018750,0.406250,0.050000,0.050000},{0.031250,0.406250,0.025000,0.025000},{0.031250,0.406250,0.050000,0.050000},{0.043750,0.406250,0.025000,0.025000},{0.043750,0.406250,0.050000,0.050000},{0.056250,0.406250,0.025000,0.025000},{0.056250,0.406250,0.050000,0.050000},{0.068750,0.406250,0.025000,0.025000},{0.068750,0.406250,0.050000,0.050000},{0.081250,0.406250,0.025000,0.025000},{0.081250,0.406250,0.050000,0.050000},{0.093750,0.406250,0.025000,0.025000},{0.093750,0.406250,0.050000,0.050000},{0.106250,0.406250,0.025000,0.025000},{0.106250,0.406250,0.050000,0.050000},{0.118750,0.406250,0.025000,0.025000},{0.118750,0.406250,0.050000,0.050000},{0.131250,0.406250,0.025000,0.025000},{0.131250,0.406250,0.050000,0.050000},{0.143750,0.406250,0.025000,0.025000},{0.143750,0.406250,0.050000,0.050000},{0.156250,0.406250,0.025000,0.025000},{0.156250,0.406250,0.050000,0.050000},{0.168750,0.406250,0.025000,0.025000},{0.168750,0.406250,0.050000,0.050000},{0.181250,0.406250,0.025000,0.025000},{0.181250,0.406250,0.050000,0.050000},{0.193750,0.406250,0.025000,0.025000},{0.193750,0.406250,0.050000,0.050000},{0.206250,0.406250,0.025000,0.025000},{0.206250,0.406250,0.050000,0.050000},{0.218750,0.406250,0.025000,0.025000},{0.218750,0.406250,0.050000,0.050000},{0.231250,0.406250,0.025000,0.025000},{0.231250,0.406250,0.050000,0.050000},{0.243750,0.406250,0.025000,0.025000},{0.243750,0.406250,0.050000,0.050000},{0.256250,0.406250,0.025000,0.025000},{0.256250,0.406250,0.050000,0.050000},{0.268750,0.406250,0.025000,0.025000},{0.268750,0.406250,0.050000,0.050000},{0.281250,0.406250,0.025000,0.025000},{0.281250,0.406250,0.050000,0.050000},{0.293750,0.406250,0.025000,0.025000},{0.293750,0.406250,0.050000,0.050000},{0.306250,0.406250,0.025000,0.025000},{0.306250,0.406250,0.050000,0.050000},{0.318750,0.406250,0.025000,0.025000},{0.318750,0.406250,0.050000,0.050000},{0.331250,0.406250,0.025000,0.025000},{0.331250,0.406250,0.050000,0.050000},{0.343750,0.406250,0.025000,0.025000},{0.343750,0.406250,0.050000,0.050000},{0.356250,0.406250,0.025000,0.025000},{0.356250,0.406250,0.050000,0.050000},{0.368750,0.406250,0.025000,0.025000},{0.368750,0.406250,0.050000,0.050000},{0.381250,0.406250,0.025000,0.025000},{0.381250,0.406250,0.050000,0.050000},{0.393750,0.406250,0.025000,0.025000},{0.393750,0.406250,0.050000,0.050000},{0.406250,0.406250,0.025000,0.025000},{0.406250,0.406250,0.050000,0.050000},{0.418750,0.406250,0.025000,0.025000},{0.418750,0.406250,0.050000,0.050000},{0.431250,0.406250,0.025000,0.025000},{0.431250,0.406250,0.050000,0.050000},{0.443750,0.406250,0.025000,0.025000},{0.443750,0.406250,0.050000,0.050000},{0.456250,0.406250,0.025000,0.025000},{0.456250,0.406250,0.050000,0.050000},{0.468750,0.406250,0.025000,0.025000},{0.468750,0.406250,0.050000,0.050000},{0.481250,0.406250,0.025000,0.025000},{0.481250,0.406250,0.050000,0.050000},{0.493750,0.406250,0.025000,0.025000},{0.493750,0.406250,0.050000,0.050000},{0.506250,0.406250,0.025000,0.025000},{0.506250,0.406250,0.050000,0.050000},{0.518750,0.406250,0.025000,0.025000},{0.518750,0.406250,0.050000,0.050000},{0.531250,0.406250,0.025000,0.025000},{0.531250,0.406250,0.050000,0.050000},{0.543750,0.406250,0.025000,0.025000},{0.543750,0.406250,0.050000,0.050000},{0.556250,0.406250,0.025000,0.025000},{0.556250,0.406250,0.050000,0.050000},{0.568750,0.406250,0.025000,0.025000},{0.568750,0.406250,0.050000,0.050000},{0.581250,0.406250,0.025000,0.025000},{0.581250,0.406250,0.050000,0.050000},{0.593750,0.406250,0.025000,0.025000},{0.593750,0.406250,0.050000,0.050000},{0.606250,0.406250,0.025000,0.025000},{0.606250,0.406250,0.050000,0.050000},{0.618750,0.406250,0.025000,0.025000},{0.618750,0.406250,0.050000,0.050000},{0.631250,0.406250,0.025000,0.025000},{0.631250,0.406250,0.050000,0.050000},{0.643750,0.406250,0.025000,0.025000},{0.643750,0.406250,0.050000,0.050000},{0.656250,0.406250,0.025000,0.025000},{0.656250,0.406250,0.050000,0.050000},{0.668750,0.406250,0.025000,0.025000},{0.668750,0.406250,0.050000,0.050000},{0.681250,0.406250,0.025000,0.025000},{0.681250,0.406250,0.050000,0.050000},{0.693750,0.406250,0.025000,0.025000},{0.693750,0.406250,0.050000,0.050000},{0.706250,0.406250,0.025000,0.025000},{0.706250,0.406250,0.050000,0.050000},{0.718750,0.406250,0.025000,0.025000},{0.718750,0.406250,0.050000,0.050000},{0.731250,0.406250,0.025000,0.025000},{0.731250,0.406250,0.050000,0.050000},{0.743750,0.406250,0.025000,0.025000},{0.743750,0.406250,0.050000,0.050000},{0.756250,0.406250,0.025000,0.025000},{0.756250,0.406250,0.050000,0.050000},{0.768750,0.406250,0.025000,0.025000},{0.768750,0.406250,0.050000,0.050000},{0.781250,0.406250,0.025000,0.025000},{0.781250,0.406250,0.050000,0.050000},{0.793750,0.406250,0.025000,0.025000},{0.793750,0.406250,0.050000,0.050000},{0.806250,0.406250,0.025000,0.025000},{0.806250,0.406250,0.050000,0.050000},{0.818750,0.406250,0.025000,0.025000},{0.818750,0.406250,0.050000,0.050000},{0.831250,0.406250,0.025000,0.025000},{0.831250,0.406250,0.050000,0.050000},{0.843750,0.406250,0.025000,0.025000},{0.843750,0.406250,0.050000,0.050000},{0.856250,0.406250,0.025000,0.025000},{0.856250,0.406250,0.050000,0.050000},{0.868750,0.406250,0.025000,0.025000},{0.868750,0.406250,0.050000,0.050000},{0.881250,0.406250,0.025000,0.025000},{0.881250,0.406250,0.050000,0.050000},{0.893750,0.406250,0.025000,0.025000},{0.893750,0.406250,0.050000,0.050000},{0.906250,0.406250,0.025000,0.025000},{0.906250,0.406250,0.050000,0.050000},{0.918750,0.406250,0.025000,0.025000},{0.918750,0.406250,0.050000,0.050000},{0.931250,0.406250,0.025000,0.025000},{0.931250,0.406250,0.050000,0.050000},{0.943750,0.406250,0.025000,0.025000},{0.943750,0.406250,0.050000,0.050000},{0.956250,0.406250,0.025000,0.025000},{0.956250,0.406250,0.050000,0.050000},{0.968750,0.406250,0.025000,0.025000},{0.968750,0.406250,0.050000,0.050000},{0.981250,0.406250,0.025000,0.025000},{0.981250,0.406250,0.050000,0.050000},{0.993750,0.406250,0.025000,0.025000},{0.993750,0.406250,0.050000,0.050000},{0.006250,0.418750,0.025000,0.025000},{0.006250,0.418750,0.050000,0.050000},{0.018750,0.418750,0.025000,0.025000},{0.018750,0.418750,0.050000,0.050000},{0.031250,0.418750,0.025000,0.025000},{0.031250,0.418750,0.050000,0.050000},{0.043750,0.418750,0.025000,0.025000},{0.043750,0.418750,0.050000,0.050000},{0.056250,0.418750,0.025000,0.025000},{0.056250,0.418750,0.050000,0.050000},{0.068750,0.418750,0.025000,0.025000},{0.068750,0.418750,0.050000,0.050000},{0.081250,0.418750,0.025000,0.025000},{0.081250,0.418750,0.050000,0.050000},{0.093750,0.418750,0.025000,0.025000},{0.093750,0.418750,0.050000,0.050000},{0.106250,0.418750,0.025000,0.025000},{0.106250,0.418750,0.050000,0.050000},{0.118750,0.418750,0.025000,0.025000},{0.118750,0.418750,0.050000,0.050000},{0.131250,0.418750,0.025000,0.025000},{0.131250,0.418750,0.050000,0.050000},{0.143750,0.418750,0.025000,0.025000},{0.143750,0.418750,0.050000,0.050000},{0.156250,0.418750,0.025000,0.025000},{0.156250,0.418750,0.050000,0.050000},{0.168750,0.418750,0.025000,0.025000},{0.168750,0.418750,0.050000,0.050000},{0.181250,0.418750,0.025000,0.025000},{0.181250,0.418750,0.050000,0.050000},{0.193750,0.418750,0.025000,0.025000},{0.193750,0.418750,0.050000,0.050000},{0.206250,0.418750,0.025000,0.025000},{0.206250,0.418750,0.050000,0.050000},{0.218750,0.418750,0.025000,0.025000},{0.218750,0.418750,0.050000,0.050000},{0.231250,0.418750,0.025000,0.025000},{0.231250,0.418750,0.050000,0.050000},{0.243750,0.418750,0.025000,0.025000},{0.243750,0.418750,0.050000,0.050000},{0.256250,0.418750,0.025000,0.025000},{0.256250,0.418750,0.050000,0.050000},{0.268750,0.418750,0.025000,0.025000},{0.268750,0.418750,0.050000,0.050000},{0.281250,0.418750,0.025000,0.025000},{0.281250,0.418750,0.050000,0.050000},{0.293750,0.418750,0.025000,0.025000},{0.293750,0.418750,0.050000,0.050000},{0.306250,0.418750,0.025000,0.025000},{0.306250,0.418750,0.050000,0.050000},{0.318750,0.418750,0.025000,0.025000},{0.318750,0.418750,0.050000,0.050000},{0.331250,0.418750,0.025000,0.025000},{0.331250,0.418750,0.050000,0.050000},{0.343750,0.418750,0.025000,0.025000},{0.343750,0.418750,0.050000,0.050000},{0.356250,0.418750,0.025000,0.025000},{0.356250,0.418750,0.050000,0.050000},{0.368750,0.418750,0.025000,0.025000},{0.368750,0.418750,0.050000,0.050000},{0.381250,0.418750,0.025000,0.025000},{0.381250,0.418750,0.050000,0.050000},{0.393750,0.418750,0.025000,0.025000},{0.393750,0.418750,0.050000,0.050000},{0.406250,0.418750,0.025000,0.025000},{0.406250,0.418750,0.050000,0.050000},{0.418750,0.418750,0.025000,0.025000},{0.418750,0.418750,0.050000,0.050000},{0.431250,0.418750,0.025000,0.025000},{0.431250,0.418750,0.050000,0.050000},{0.443750,0.418750,0.025000,0.025000},{0.443750,0.418750,0.050000,0.050000},{0.456250,0.418750,0.025000,0.025000},{0.456250,0.418750,0.050000,0.050000},{0.468750,0.418750,0.025000,0.025000},{0.468750,0.418750,0.050000,0.050000},{0.481250,0.418750,0.025000,0.025000},{0.481250,0.418750,0.050000,0.050000},{0.493750,0.418750,0.025000,0.025000},{0.493750,0.418750,0.050000,0.050000},{0.506250,0.418750,0.025000,0.025000},{0.506250,0.418750,0.050000,0.050000},{0.518750,0.418750,0.025000,0.025000},{0.518750,0.418750,0.050000,0.050000},{0.531250,0.418750,0.025000,0.025000},{0.531250,0.418750,0.050000,0.050000},{0.543750,0.418750,0.025000,0.025000},{0.543750,0.418750,0.050000,0.050000},{0.556250,0.418750,0.025000,0.025000},{0.556250,0.418750,0.050000,0.050000},{0.568750,0.418750,0.025000,0.025000},{0.568750,0.418750,0.050000,0.050000},{0.581250,0.418750,0.025000,0.025000},{0.581250,0.418750,0.050000,0.050000},{0.593750,0.418750,0.025000,0.025000},{0.593750,0.418750,0.050000,0.050000},{0.606250,0.418750,0.025000,0.025000},{0.606250,0.418750,0.050000,0.050000},{0.618750,0.418750,0.025000,0.025000},{0.618750,0.418750,0.050000,0.050000},{0.631250,0.418750,0.025000,0.025000},{0.631250,0.418750,0.050000,0.050000},{0.643750,0.418750,0.025000,0.025000},{0.643750,0.418750,0.050000,0.050000},{0.656250,0.418750,0.025000,0.025000},{0.656250,0.418750,0.050000,0.050000},{0.668750,0.418750,0.025000,0.025000},{0.668750,0.418750,0.050000,0.050000},{0.681250,0.418750,0.025000,0.025000},{0.681250,0.418750,0.050000,0.050000},{0.693750,0.418750,0.025000,0.025000},{0.693750,0.418750,0.050000,0.050000},{0.706250,0.418750,0.025000,0.025000},{0.706250,0.418750,0.050000,0.050000},{0.718750,0.418750,0.025000,0.025000},{0.718750,0.418750,0.050000,0.050000},{0.731250,0.418750,0.025000,0.025000},{0.731250,0.418750,0.050000,0.050000},{0.743750,0.418750,0.025000,0.025000},{0.743750,0.418750,0.050000,0.050000},{0.756250,0.418750,0.025000,0.025000},{0.756250,0.418750,0.050000,0.050000},{0.768750,0.418750,0.025000,0.025000},{0.768750,0.418750,0.050000,0.050000},{0.781250,0.418750,0.025000,0.025000},{0.781250,0.418750,0.050000,0.050000},{0.793750,0.418750,0.025000,0.025000},{0.793750,0.418750,0.050000,0.050000},{0.806250,0.418750,0.025000,0.025000},{0.806250,0.418750,0.050000,0.050000},{0.818750,0.418750,0.025000,0.025000},{0.818750,0.418750,0.050000,0.050000},{0.831250,0.418750,0.025000,0.025000},{0.831250,0.418750,0.050000,0.050000},{0.843750,0.418750,0.025000,0.025000},{0.843750,0.418750,0.050000,0.050000},{0.856250,0.418750,0.025000,0.025000},{0.856250,0.418750,0.050000,0.050000},{0.868750,0.418750,0.025000,0.025000},{0.868750,0.418750,0.050000,0.050000},{0.881250,0.418750,0.025000,0.025000},{0.881250,0.418750,0.050000,0.050000},{0.893750,0.418750,0.025000,0.025000},{0.893750,0.418750,0.050000,0.050000},{0.906250,0.418750,0.025000,0.025000},{0.906250,0.418750,0.050000,0.050000},{0.918750,0.418750,0.025000,0.025000},{0.918750,0.418750,0.050000,0.050000},{0.931250,0.418750,0.025000,0.025000},{0.931250,0.418750,0.050000,0.050000},{0.943750,0.418750,0.025000,0.025000},{0.943750,0.418750,0.050000,0.050000},{0.956250,0.418750,0.025000,0.025000},{0.956250,0.418750,0.050000,0.050000},{0.968750,0.418750,0.025000,0.025000},{0.968750,0.418750,0.050000,0.050000},{0.981250,0.418750,0.025000,0.025000},{0.981250,0.418750,0.050000,0.050000},{0.993750,0.418750,0.025000,0.025000},{0.993750,0.418750,0.050000,0.050000},{0.006250,0.431250,0.025000,0.025000},{0.006250,0.431250,0.050000,0.050000},{0.018750,0.431250,0.025000,0.025000},{0.018750,0.431250,0.050000,0.050000},{0.031250,0.431250,0.025000,0.025000},{0.031250,0.431250,0.050000,0.050000},{0.043750,0.431250,0.025000,0.025000},{0.043750,0.431250,0.050000,0.050000},{0.056250,0.431250,0.025000,0.025000},{0.056250,0.431250,0.050000,0.050000},{0.068750,0.431250,0.025000,0.025000},{0.068750,0.431250,0.050000,0.050000},{0.081250,0.431250,0.025000,0.025000},{0.081250,0.431250,0.050000,0.050000},{0.093750,0.431250,0.025000,0.025000},{0.093750,0.431250,0.050000,0.050000},{0.106250,0.431250,0.025000,0.025000},{0.106250,0.431250,0.050000,0.050000},{0.118750,0.431250,0.025000,0.025000},{0.118750,0.431250,0.050000,0.050000},{0.131250,0.431250,0.025000,0.025000},{0.131250,0.431250,0.050000,0.050000},{0.143750,0.431250,0.025000,0.025000},{0.143750,0.431250,0.050000,0.050000},{0.156250,0.431250,0.025000,0.025000},{0.156250,0.431250,0.050000,0.050000},{0.168750,0.431250,0.025000,0.025000},{0.168750,0.431250,0.050000,0.050000},{0.181250,0.431250,0.025000,0.025000},{0.181250,0.431250,0.050000,0.050000},{0.193750,0.431250,0.025000,0.025000},{0.193750,0.431250,0.050000,0.050000},{0.206250,0.431250,0.025000,0.025000},{0.206250,0.431250,0.050000,0.050000},{0.218750,0.431250,0.025000,0.025000},{0.218750,0.431250,0.050000,0.050000},{0.231250,0.431250,0.025000,0.025000},{0.231250,0.431250,0.050000,0.050000},{0.243750,0.431250,0.025000,0.025000},{0.243750,0.431250,0.050000,0.050000},{0.256250,0.431250,0.025000,0.025000},{0.256250,0.431250,0.050000,0.050000},{0.268750,0.431250,0.025000,0.025000},{0.268750,0.431250,0.050000,0.050000},{0.281250,0.431250,0.025000,0.025000},{0.281250,0.431250,0.050000,0.050000},{0.293750,0.431250,0.025000,0.025000},{0.293750,0.431250,0.050000,0.050000},{0.306250,0.431250,0.025000,0.025000},{0.306250,0.431250,0.050000,0.050000},{0.318750,0.431250,0.025000,0.025000},{0.318750,0.431250,0.050000,0.050000},{0.331250,0.431250,0.025000,0.025000},{0.331250,0.431250,0.050000,0.050000},{0.343750,0.431250,0.025000,0.025000},{0.343750,0.431250,0.050000,0.050000},{0.356250,0.431250,0.025000,0.025000},{0.356250,0.431250,0.050000,0.050000},{0.368750,0.431250,0.025000,0.025000},{0.368750,0.431250,0.050000,0.050000},{0.381250,0.431250,0.025000,0.025000},{0.381250,0.431250,0.050000,0.050000},{0.393750,0.431250,0.025000,0.025000},{0.393750,0.431250,0.050000,0.050000},{0.406250,0.431250,0.025000,0.025000},{0.406250,0.431250,0.050000,0.050000},{0.418750,0.431250,0.025000,0.025000},{0.418750,0.431250,0.050000,0.050000},{0.431250,0.431250,0.025000,0.025000},{0.431250,0.431250,0.050000,0.050000},{0.443750,0.431250,0.025000,0.025000},{0.443750,0.431250,0.050000,0.050000},{0.456250,0.431250,0.025000,0.025000},{0.456250,0.431250,0.050000,0.050000},{0.468750,0.431250,0.025000,0.025000},{0.468750,0.431250,0.050000,0.050000},{0.481250,0.431250,0.025000,0.025000},{0.481250,0.431250,0.050000,0.050000},{0.493750,0.431250,0.025000,0.025000},{0.493750,0.431250,0.050000,0.050000},{0.506250,0.431250,0.025000,0.025000},{0.506250,0.431250,0.050000,0.050000},{0.518750,0.431250,0.025000,0.025000},{0.518750,0.431250,0.050000,0.050000},{0.531250,0.431250,0.025000,0.025000},{0.531250,0.431250,0.050000,0.050000},{0.543750,0.431250,0.025000,0.025000},{0.543750,0.431250,0.050000,0.050000},{0.556250,0.431250,0.025000,0.025000},{0.556250,0.431250,0.050000,0.050000},{0.568750,0.431250,0.025000,0.025000},{0.568750,0.431250,0.050000,0.050000},{0.581250,0.431250,0.025000,0.025000},{0.581250,0.431250,0.050000,0.050000},{0.593750,0.431250,0.025000,0.025000},{0.593750,0.431250,0.050000,0.050000},{0.606250,0.431250,0.025000,0.025000},{0.606250,0.431250,0.050000,0.050000},{0.618750,0.431250,0.025000,0.025000},{0.618750,0.431250,0.050000,0.050000},{0.631250,0.431250,0.025000,0.025000},{0.631250,0.431250,0.050000,0.050000},{0.643750,0.431250,0.025000,0.025000},{0.643750,0.431250,0.050000,0.050000},{0.656250,0.431250,0.025000,0.025000},{0.656250,0.431250,0.050000,0.050000},{0.668750,0.431250,0.025000,0.025000},{0.668750,0.431250,0.050000,0.050000},{0.681250,0.431250,0.025000,0.025000},{0.681250,0.431250,0.050000,0.050000},{0.693750,0.431250,0.025000,0.025000},{0.693750,0.431250,0.050000,0.050000},{0.706250,0.431250,0.025000,0.025000},{0.706250,0.431250,0.050000,0.050000},{0.718750,0.431250,0.025000,0.025000},{0.718750,0.431250,0.050000,0.050000},{0.731250,0.431250,0.025000,0.025000},{0.731250,0.431250,0.050000,0.050000},{0.743750,0.431250,0.025000,0.025000},{0.743750,0.431250,0.050000,0.050000},{0.756250,0.431250,0.025000,0.025000},{0.756250,0.431250,0.050000,0.050000},{0.768750,0.431250,0.025000,0.025000},{0.768750,0.431250,0.050000,0.050000},{0.781250,0.431250,0.025000,0.025000},{0.781250,0.431250,0.050000,0.050000},{0.793750,0.431250,0.025000,0.025000},{0.793750,0.431250,0.050000,0.050000},{0.806250,0.431250,0.025000,0.025000},{0.806250,0.431250,0.050000,0.050000},{0.818750,0.431250,0.025000,0.025000},{0.818750,0.431250,0.050000,0.050000},{0.831250,0.431250,0.025000,0.025000},{0.831250,0.431250,0.050000,0.050000},{0.843750,0.431250,0.025000,0.025000},{0.843750,0.431250,0.050000,0.050000},{0.856250,0.431250,0.025000,0.025000},{0.856250,0.431250,0.050000,0.050000},{0.868750,0.431250,0.025000,0.025000},{0.868750,0.431250,0.050000,0.050000},{0.881250,0.431250,0.025000,0.025000},{0.881250,0.431250,0.050000,0.050000},{0.893750,0.431250,0.025000,0.025000},{0.893750,0.431250,0.050000,0.050000},{0.906250,0.431250,0.025000,0.025000},{0.906250,0.431250,0.050000,0.050000},{0.918750,0.431250,0.025000,0.025000},{0.918750,0.431250,0.050000,0.050000},{0.931250,0.431250,0.025000,0.025000},{0.931250,0.431250,0.050000,0.050000},{0.943750,0.431250,0.025000,0.025000},{0.943750,0.431250,0.050000,0.050000},{0.956250,0.431250,0.025000,0.025000},{0.956250,0.431250,0.050000,0.050000},{0.968750,0.431250,0.025000,0.025000},{0.968750,0.431250,0.050000,0.050000},{0.981250,0.431250,0.025000,0.025000},{0.981250,0.431250,0.050000,0.050000},{0.993750,0.431250,0.025000,0.025000},{0.993750,0.431250,0.050000,0.050000},{0.006250,0.443750,0.025000,0.025000},{0.006250,0.443750,0.050000,0.050000},{0.018750,0.443750,0.025000,0.025000},{0.018750,0.443750,0.050000,0.050000},{0.031250,0.443750,0.025000,0.025000},{0.031250,0.443750,0.050000,0.050000},{0.043750,0.443750,0.025000,0.025000},{0.043750,0.443750,0.050000,0.050000},{0.056250,0.443750,0.025000,0.025000},{0.056250,0.443750,0.050000,0.050000},{0.068750,0.443750,0.025000,0.025000},{0.068750,0.443750,0.050000,0.050000},{0.081250,0.443750,0.025000,0.025000},{0.081250,0.443750,0.050000,0.050000},{0.093750,0.443750,0.025000,0.025000},{0.093750,0.443750,0.050000,0.050000},{0.106250,0.443750,0.025000,0.025000},{0.106250,0.443750,0.050000,0.050000},{0.118750,0.443750,0.025000,0.025000},{0.118750,0.443750,0.050000,0.050000},{0.131250,0.443750,0.025000,0.025000},{0.131250,0.443750,0.050000,0.050000},{0.143750,0.443750,0.025000,0.025000},{0.143750,0.443750,0.050000,0.050000},{0.156250,0.443750,0.025000,0.025000},{0.156250,0.443750,0.050000,0.050000},{0.168750,0.443750,0.025000,0.025000},{0.168750,0.443750,0.050000,0.050000},{0.181250,0.443750,0.025000,0.025000},{0.181250,0.443750,0.050000,0.050000},{0.193750,0.443750,0.025000,0.025000},{0.193750,0.443750,0.050000,0.050000},{0.206250,0.443750,0.025000,0.025000},{0.206250,0.443750,0.050000,0.050000},{0.218750,0.443750,0.025000,0.025000},{0.218750,0.443750,0.050000,0.050000},{0.231250,0.443750,0.025000,0.025000},{0.231250,0.443750,0.050000,0.050000},{0.243750,0.443750,0.025000,0.025000},{0.243750,0.443750,0.050000,0.050000},{0.256250,0.443750,0.025000,0.025000},{0.256250,0.443750,0.050000,0.050000},{0.268750,0.443750,0.025000,0.025000},{0.268750,0.443750,0.050000,0.050000},{0.281250,0.443750,0.025000,0.025000},{0.281250,0.443750,0.050000,0.050000},{0.293750,0.443750,0.025000,0.025000},{0.293750,0.443750,0.050000,0.050000},{0.306250,0.443750,0.025000,0.025000},{0.306250,0.443750,0.050000,0.050000},{0.318750,0.443750,0.025000,0.025000},{0.318750,0.443750,0.050000,0.050000},{0.331250,0.443750,0.025000,0.025000},{0.331250,0.443750,0.050000,0.050000},{0.343750,0.443750,0.025000,0.025000},{0.343750,0.443750,0.050000,0.050000},{0.356250,0.443750,0.025000,0.025000},{0.356250,0.443750,0.050000,0.050000},{0.368750,0.443750,0.025000,0.025000},{0.368750,0.443750,0.050000,0.050000},{0.381250,0.443750,0.025000,0.025000},{0.381250,0.443750,0.050000,0.050000},{0.393750,0.443750,0.025000,0.025000},{0.393750,0.443750,0.050000,0.050000},{0.406250,0.443750,0.025000,0.025000},{0.406250,0.443750,0.050000,0.050000},{0.418750,0.443750,0.025000,0.025000},{0.418750,0.443750,0.050000,0.050000},{0.431250,0.443750,0.025000,0.025000},{0.431250,0.443750,0.050000,0.050000},{0.443750,0.443750,0.025000,0.025000},{0.443750,0.443750,0.050000,0.050000},{0.456250,0.443750,0.025000,0.025000},{0.456250,0.443750,0.050000,0.050000},{0.468750,0.443750,0.025000,0.025000},{0.468750,0.443750,0.050000,0.050000},{0.481250,0.443750,0.025000,0.025000},{0.481250,0.443750,0.050000,0.050000},{0.493750,0.443750,0.025000,0.025000},{0.493750,0.443750,0.050000,0.050000},{0.506250,0.443750,0.025000,0.025000},{0.506250,0.443750,0.050000,0.050000},{0.518750,0.443750,0.025000,0.025000},{0.518750,0.443750,0.050000,0.050000},{0.531250,0.443750,0.025000,0.025000},{0.531250,0.443750,0.050000,0.050000},{0.543750,0.443750,0.025000,0.025000},{0.543750,0.443750,0.050000,0.050000},{0.556250,0.443750,0.025000,0.025000},{0.556250,0.443750,0.050000,0.050000},{0.568750,0.443750,0.025000,0.025000},{0.568750,0.443750,0.050000,0.050000},{0.581250,0.443750,0.025000,0.025000},{0.581250,0.443750,0.050000,0.050000},{0.593750,0.443750,0.025000,0.025000},{0.593750,0.443750,0.050000,0.050000},{0.606250,0.443750,0.025000,0.025000},{0.606250,0.443750,0.050000,0.050000},{0.618750,0.443750,0.025000,0.025000},{0.618750,0.443750,0.050000,0.050000},{0.631250,0.443750,0.025000,0.025000},{0.631250,0.443750,0.050000,0.050000},{0.643750,0.443750,0.025000,0.025000},{0.643750,0.443750,0.050000,0.050000},{0.656250,0.443750,0.025000,0.025000},{0.656250,0.443750,0.050000,0.050000},{0.668750,0.443750,0.025000,0.025000},{0.668750,0.443750,0.050000,0.050000},{0.681250,0.443750,0.025000,0.025000},{0.681250,0.443750,0.050000,0.050000},{0.693750,0.443750,0.025000,0.025000},{0.693750,0.443750,0.050000,0.050000},{0.706250,0.443750,0.025000,0.025000},{0.706250,0.443750,0.050000,0.050000},{0.718750,0.443750,0.025000,0.025000},{0.718750,0.443750,0.050000,0.050000},{0.731250,0.443750,0.025000,0.025000},{0.731250,0.443750,0.050000,0.050000},{0.743750,0.443750,0.025000,0.025000},{0.743750,0.443750,0.050000,0.050000},{0.756250,0.443750,0.025000,0.025000},{0.756250,0.443750,0.050000,0.050000},{0.768750,0.443750,0.025000,0.025000},{0.768750,0.443750,0.050000,0.050000},{0.781250,0.443750,0.025000,0.025000},{0.781250,0.443750,0.050000,0.050000},{0.793750,0.443750,0.025000,0.025000},{0.793750,0.443750,0.050000,0.050000},{0.806250,0.443750,0.025000,0.025000},{0.806250,0.443750,0.050000,0.050000},{0.818750,0.443750,0.025000,0.025000},{0.818750,0.443750,0.050000,0.050000},{0.831250,0.443750,0.025000,0.025000},{0.831250,0.443750,0.050000,0.050000},{0.843750,0.443750,0.025000,0.025000},{0.843750,0.443750,0.050000,0.050000},{0.856250,0.443750,0.025000,0.025000},{0.856250,0.443750,0.050000,0.050000},{0.868750,0.443750,0.025000,0.025000},{0.868750,0.443750,0.050000,0.050000},{0.881250,0.443750,0.025000,0.025000},{0.881250,0.443750,0.050000,0.050000},{0.893750,0.443750,0.025000,0.025000},{0.893750,0.443750,0.050000,0.050000},{0.906250,0.443750,0.025000,0.025000},{0.906250,0.443750,0.050000,0.050000},{0.918750,0.443750,0.025000,0.025000},{0.918750,0.443750,0.050000,0.050000},{0.931250,0.443750,0.025000,0.025000},{0.931250,0.443750,0.050000,0.050000},{0.943750,0.443750,0.025000,0.025000},{0.943750,0.443750,0.050000,0.050000},{0.956250,0.443750,0.025000,0.025000},{0.956250,0.443750,0.050000,0.050000},{0.968750,0.443750,0.025000,0.025000},{0.968750,0.443750,0.050000,0.050000},{0.981250,0.443750,0.025000,0.025000},{0.981250,0.443750,0.050000,0.050000},{0.993750,0.443750,0.025000,0.025000},{0.993750,0.443750,0.050000,0.050000},{0.006250,0.456250,0.025000,0.025000},{0.006250,0.456250,0.050000,0.050000},{0.018750,0.456250,0.025000,0.025000},{0.018750,0.456250,0.050000,0.050000},{0.031250,0.456250,0.025000,0.025000},{0.031250,0.456250,0.050000,0.050000},{0.043750,0.456250,0.025000,0.025000},{0.043750,0.456250,0.050000,0.050000},{0.056250,0.456250,0.025000,0.025000},{0.056250,0.456250,0.050000,0.050000},{0.068750,0.456250,0.025000,0.025000},{0.068750,0.456250,0.050000,0.050000},{0.081250,0.456250,0.025000,0.025000},{0.081250,0.456250,0.050000,0.050000},{0.093750,0.456250,0.025000,0.025000},{0.093750,0.456250,0.050000,0.050000},{0.106250,0.456250,0.025000,0.025000},{0.106250,0.456250,0.050000,0.050000},{0.118750,0.456250,0.025000,0.025000},{0.118750,0.456250,0.050000,0.050000},{0.131250,0.456250,0.025000,0.025000},{0.131250,0.456250,0.050000,0.050000},{0.143750,0.456250,0.025000,0.025000},{0.143750,0.456250,0.050000,0.050000},{0.156250,0.456250,0.025000,0.025000},{0.156250,0.456250,0.050000,0.050000},{0.168750,0.456250,0.025000,0.025000},{0.168750,0.456250,0.050000,0.050000},{0.181250,0.456250,0.025000,0.025000},{0.181250,0.456250,0.050000,0.050000},{0.193750,0.456250,0.025000,0.025000},{0.193750,0.456250,0.050000,0.050000},{0.206250,0.456250,0.025000,0.025000},{0.206250,0.456250,0.050000,0.050000},{0.218750,0.456250,0.025000,0.025000},{0.218750,0.456250,0.050000,0.050000},{0.231250,0.456250,0.025000,0.025000},{0.231250,0.456250,0.050000,0.050000},{0.243750,0.456250,0.025000,0.025000},{0.243750,0.456250,0.050000,0.050000},{0.256250,0.456250,0.025000,0.025000},{0.256250,0.456250,0.050000,0.050000},{0.268750,0.456250,0.025000,0.025000},{0.268750,0.456250,0.050000,0.050000},{0.281250,0.456250,0.025000,0.025000},{0.281250,0.456250,0.050000,0.050000},{0.293750,0.456250,0.025000,0.025000},{0.293750,0.456250,0.050000,0.050000},{0.306250,0.456250,0.025000,0.025000},{0.306250,0.456250,0.050000,0.050000},{0.318750,0.456250,0.025000,0.025000},{0.318750,0.456250,0.050000,0.050000},{0.331250,0.456250,0.025000,0.025000},{0.331250,0.456250,0.050000,0.050000},{0.343750,0.456250,0.025000,0.025000},{0.343750,0.456250,0.050000,0.050000},{0.356250,0.456250,0.025000,0.025000},{0.356250,0.456250,0.050000,0.050000},{0.368750,0.456250,0.025000,0.025000},{0.368750,0.456250,0.050000,0.050000},{0.381250,0.456250,0.025000,0.025000},{0.381250,0.456250,0.050000,0.050000},{0.393750,0.456250,0.025000,0.025000},{0.393750,0.456250,0.050000,0.050000},{0.406250,0.456250,0.025000,0.025000},{0.406250,0.456250,0.050000,0.050000},{0.418750,0.456250,0.025000,0.025000},{0.418750,0.456250,0.050000,0.050000},{0.431250,0.456250,0.025000,0.025000},{0.431250,0.456250,0.050000,0.050000},{0.443750,0.456250,0.025000,0.025000},{0.443750,0.456250,0.050000,0.050000},{0.456250,0.456250,0.025000,0.025000},{0.456250,0.456250,0.050000,0.050000},{0.468750,0.456250,0.025000,0.025000},{0.468750,0.456250,0.050000,0.050000},{0.481250,0.456250,0.025000,0.025000},{0.481250,0.456250,0.050000,0.050000},{0.493750,0.456250,0.025000,0.025000},{0.493750,0.456250,0.050000,0.050000},{0.506250,0.456250,0.025000,0.025000},{0.506250,0.456250,0.050000,0.050000},{0.518750,0.456250,0.025000,0.025000},{0.518750,0.456250,0.050000,0.050000},{0.531250,0.456250,0.025000,0.025000},{0.531250,0.456250,0.050000,0.050000},{0.543750,0.456250,0.025000,0.025000},{0.543750,0.456250,0.050000,0.050000},{0.556250,0.456250,0.025000,0.025000},{0.556250,0.456250,0.050000,0.050000},{0.568750,0.456250,0.025000,0.025000},{0.568750,0.456250,0.050000,0.050000},{0.581250,0.456250,0.025000,0.025000},{0.581250,0.456250,0.050000,0.050000},{0.593750,0.456250,0.025000,0.025000},{0.593750,0.456250,0.050000,0.050000},{0.606250,0.456250,0.025000,0.025000},{0.606250,0.456250,0.050000,0.050000},{0.618750,0.456250,0.025000,0.025000},{0.618750,0.456250,0.050000,0.050000},{0.631250,0.456250,0.025000,0.025000},{0.631250,0.456250,0.050000,0.050000},{0.643750,0.456250,0.025000,0.025000},{0.643750,0.456250,0.050000,0.050000},{0.656250,0.456250,0.025000,0.025000},{0.656250,0.456250,0.050000,0.050000},{0.668750,0.456250,0.025000,0.025000},{0.668750,0.456250,0.050000,0.050000},{0.681250,0.456250,0.025000,0.025000},{0.681250,0.456250,0.050000,0.050000},{0.693750,0.456250,0.025000,0.025000},{0.693750,0.456250,0.050000,0.050000},{0.706250,0.456250,0.025000,0.025000},{0.706250,0.456250,0.050000,0.050000},{0.718750,0.456250,0.025000,0.025000},{0.718750,0.456250,0.050000,0.050000},{0.731250,0.456250,0.025000,0.025000},{0.731250,0.456250,0.050000,0.050000},{0.743750,0.456250,0.025000,0.025000},{0.743750,0.456250,0.050000,0.050000},{0.756250,0.456250,0.025000,0.025000},{0.756250,0.456250,0.050000,0.050000},{0.768750,0.456250,0.025000,0.025000},{0.768750,0.456250,0.050000,0.050000},{0.781250,0.456250,0.025000,0.025000},{0.781250,0.456250,0.050000,0.050000},{0.793750,0.456250,0.025000,0.025000},{0.793750,0.456250,0.050000,0.050000},{0.806250,0.456250,0.025000,0.025000},{0.806250,0.456250,0.050000,0.050000},{0.818750,0.456250,0.025000,0.025000},{0.818750,0.456250,0.050000,0.050000},{0.831250,0.456250,0.025000,0.025000},{0.831250,0.456250,0.050000,0.050000},{0.843750,0.456250,0.025000,0.025000},{0.843750,0.456250,0.050000,0.050000},{0.856250,0.456250,0.025000,0.025000},{0.856250,0.456250,0.050000,0.050000},{0.868750,0.456250,0.025000,0.025000},{0.868750,0.456250,0.050000,0.050000},{0.881250,0.456250,0.025000,0.025000},{0.881250,0.456250,0.050000,0.050000},{0.893750,0.456250,0.025000,0.025000},{0.893750,0.456250,0.050000,0.050000},{0.906250,0.456250,0.025000,0.025000},{0.906250,0.456250,0.050000,0.050000},{0.918750,0.456250,0.025000,0.025000},{0.918750,0.456250,0.050000,0.050000},{0.931250,0.456250,0.025000,0.025000},{0.931250,0.456250,0.050000,0.050000},{0.943750,0.456250,0.025000,0.025000},{0.943750,0.456250,0.050000,0.050000},{0.956250,0.456250,0.025000,0.025000},{0.956250,0.456250,0.050000,0.050000},{0.968750,0.456250,0.025000,0.025000},{0.968750,0.456250,0.050000,0.050000},{0.981250,0.456250,0.025000,0.025000},{0.981250,0.456250,0.050000,0.050000},{0.993750,0.456250,0.025000,0.025000},{0.993750,0.456250,0.050000,0.050000},{0.006250,0.468750,0.025000,0.025000},{0.006250,0.468750,0.050000,0.050000},{0.018750,0.468750,0.025000,0.025000},{0.018750,0.468750,0.050000,0.050000},{0.031250,0.468750,0.025000,0.025000},{0.031250,0.468750,0.050000,0.050000},{0.043750,0.468750,0.025000,0.025000},{0.043750,0.468750,0.050000,0.050000},{0.056250,0.468750,0.025000,0.025000},{0.056250,0.468750,0.050000,0.050000},{0.068750,0.468750,0.025000,0.025000},{0.068750,0.468750,0.050000,0.050000},{0.081250,0.468750,0.025000,0.025000},{0.081250,0.468750,0.050000,0.050000},{0.093750,0.468750,0.025000,0.025000},{0.093750,0.468750,0.050000,0.050000},{0.106250,0.468750,0.025000,0.025000},{0.106250,0.468750,0.050000,0.050000},{0.118750,0.468750,0.025000,0.025000},{0.118750,0.468750,0.050000,0.050000},{0.131250,0.468750,0.025000,0.025000},{0.131250,0.468750,0.050000,0.050000},{0.143750,0.468750,0.025000,0.025000},{0.143750,0.468750,0.050000,0.050000},{0.156250,0.468750,0.025000,0.025000},{0.156250,0.468750,0.050000,0.050000},{0.168750,0.468750,0.025000,0.025000},{0.168750,0.468750,0.050000,0.050000},{0.181250,0.468750,0.025000,0.025000},{0.181250,0.468750,0.050000,0.050000},{0.193750,0.468750,0.025000,0.025000},{0.193750,0.468750,0.050000,0.050000},{0.206250,0.468750,0.025000,0.025000},{0.206250,0.468750,0.050000,0.050000},{0.218750,0.468750,0.025000,0.025000},{0.218750,0.468750,0.050000,0.050000},{0.231250,0.468750,0.025000,0.025000},{0.231250,0.468750,0.050000,0.050000},{0.243750,0.468750,0.025000,0.025000},{0.243750,0.468750,0.050000,0.050000},{0.256250,0.468750,0.025000,0.025000},{0.256250,0.468750,0.050000,0.050000},{0.268750,0.468750,0.025000,0.025000},{0.268750,0.468750,0.050000,0.050000},{0.281250,0.468750,0.025000,0.025000},{0.281250,0.468750,0.050000,0.050000},{0.293750,0.468750,0.025000,0.025000},{0.293750,0.468750,0.050000,0.050000},{0.306250,0.468750,0.025000,0.025000},{0.306250,0.468750,0.050000,0.050000},{0.318750,0.468750,0.025000,0.025000},{0.318750,0.468750,0.050000,0.050000},{0.331250,0.468750,0.025000,0.025000},{0.331250,0.468750,0.050000,0.050000},{0.343750,0.468750,0.025000,0.025000},{0.343750,0.468750,0.050000,0.050000},{0.356250,0.468750,0.025000,0.025000},{0.356250,0.468750,0.050000,0.050000},{0.368750,0.468750,0.025000,0.025000},{0.368750,0.468750,0.050000,0.050000},{0.381250,0.468750,0.025000,0.025000},{0.381250,0.468750,0.050000,0.050000},{0.393750,0.468750,0.025000,0.025000},{0.393750,0.468750,0.050000,0.050000},{0.406250,0.468750,0.025000,0.025000},{0.406250,0.468750,0.050000,0.050000},{0.418750,0.468750,0.025000,0.025000},{0.418750,0.468750,0.050000,0.050000},{0.431250,0.468750,0.025000,0.025000},{0.431250,0.468750,0.050000,0.050000},{0.443750,0.468750,0.025000,0.025000},{0.443750,0.468750,0.050000,0.050000},{0.456250,0.468750,0.025000,0.025000},{0.456250,0.468750,0.050000,0.050000},{0.468750,0.468750,0.025000,0.025000},{0.468750,0.468750,0.050000,0.050000},{0.481250,0.468750,0.025000,0.025000},{0.481250,0.468750,0.050000,0.050000},{0.493750,0.468750,0.025000,0.025000},{0.493750,0.468750,0.050000,0.050000},{0.506250,0.468750,0.025000,0.025000},{0.506250,0.468750,0.050000,0.050000},{0.518750,0.468750,0.025000,0.025000},{0.518750,0.468750,0.050000,0.050000},{0.531250,0.468750,0.025000,0.025000},{0.531250,0.468750,0.050000,0.050000},{0.543750,0.468750,0.025000,0.025000},{0.543750,0.468750,0.050000,0.050000},{0.556250,0.468750,0.025000,0.025000},{0.556250,0.468750,0.050000,0.050000},{0.568750,0.468750,0.025000,0.025000},{0.568750,0.468750,0.050000,0.050000},{0.581250,0.468750,0.025000,0.025000},{0.581250,0.468750,0.050000,0.050000},{0.593750,0.468750,0.025000,0.025000},{0.593750,0.468750,0.050000,0.050000},{0.606250,0.468750,0.025000,0.025000},{0.606250,0.468750,0.050000,0.050000},{0.618750,0.468750,0.025000,0.025000},{0.618750,0.468750,0.050000,0.050000},{0.631250,0.468750,0.025000,0.025000},{0.631250,0.468750,0.050000,0.050000},{0.643750,0.468750,0.025000,0.025000},{0.643750,0.468750,0.050000,0.050000},{0.656250,0.468750,0.025000,0.025000},{0.656250,0.468750,0.050000,0.050000},{0.668750,0.468750,0.025000,0.025000},{0.668750,0.468750,0.050000,0.050000},{0.681250,0.468750,0.025000,0.025000},{0.681250,0.468750,0.050000,0.050000},{0.693750,0.468750,0.025000,0.025000},{0.693750,0.468750,0.050000,0.050000},{0.706250,0.468750,0.025000,0.025000},{0.706250,0.468750,0.050000,0.050000},{0.718750,0.468750,0.025000,0.025000},{0.718750,0.468750,0.050000,0.050000},{0.731250,0.468750,0.025000,0.025000},{0.731250,0.468750,0.050000,0.050000},{0.743750,0.468750,0.025000,0.025000},{0.743750,0.468750,0.050000,0.050000},{0.756250,0.468750,0.025000,0.025000},{0.756250,0.468750,0.050000,0.050000},{0.768750,0.468750,0.025000,0.025000},{0.768750,0.468750,0.050000,0.050000},{0.781250,0.468750,0.025000,0.025000},{0.781250,0.468750,0.050000,0.050000},{0.793750,0.468750,0.025000,0.025000},{0.793750,0.468750,0.050000,0.050000},{0.806250,0.468750,0.025000,0.025000},{0.806250,0.468750,0.050000,0.050000},{0.818750,0.468750,0.025000,0.025000},{0.818750,0.468750,0.050000,0.050000},{0.831250,0.468750,0.025000,0.025000},{0.831250,0.468750,0.050000,0.050000},{0.843750,0.468750,0.025000,0.025000},{0.843750,0.468750,0.050000,0.050000},{0.856250,0.468750,0.025000,0.025000},{0.856250,0.468750,0.050000,0.050000},{0.868750,0.468750,0.025000,0.025000},{0.868750,0.468750,0.050000,0.050000},{0.881250,0.468750,0.025000,0.025000},{0.881250,0.468750,0.050000,0.050000},{0.893750,0.468750,0.025000,0.025000},{0.893750,0.468750,0.050000,0.050000},{0.906250,0.468750,0.025000,0.025000},{0.906250,0.468750,0.050000,0.050000},{0.918750,0.468750,0.025000,0.025000},{0.918750,0.468750,0.050000,0.050000},{0.931250,0.468750,0.025000,0.025000},{0.931250,0.468750,0.050000,0.050000},{0.943750,0.468750,0.025000,0.025000},{0.943750,0.468750,0.050000,0.050000},{0.956250,0.468750,0.025000,0.025000},{0.956250,0.468750,0.050000,0.050000},{0.968750,0.468750,0.025000,0.025000},{0.968750,0.468750,0.050000,0.050000},{0.981250,0.468750,0.025000,0.025000},{0.981250,0.468750,0.050000,0.050000},{0.993750,0.468750,0.025000,0.025000},{0.993750,0.468750,0.050000,0.050000},{0.006250,0.481250,0.025000,0.025000},{0.006250,0.481250,0.050000,0.050000},{0.018750,0.481250,0.025000,0.025000},{0.018750,0.481250,0.050000,0.050000},{0.031250,0.481250,0.025000,0.025000},{0.031250,0.481250,0.050000,0.050000},{0.043750,0.481250,0.025000,0.025000},{0.043750,0.481250,0.050000,0.050000},{0.056250,0.481250,0.025000,0.025000},{0.056250,0.481250,0.050000,0.050000},{0.068750,0.481250,0.025000,0.025000},{0.068750,0.481250,0.050000,0.050000},{0.081250,0.481250,0.025000,0.025000},{0.081250,0.481250,0.050000,0.050000},{0.093750,0.481250,0.025000,0.025000},{0.093750,0.481250,0.050000,0.050000},{0.106250,0.481250,0.025000,0.025000},{0.106250,0.481250,0.050000,0.050000},{0.118750,0.481250,0.025000,0.025000},{0.118750,0.481250,0.050000,0.050000},{0.131250,0.481250,0.025000,0.025000},{0.131250,0.481250,0.050000,0.050000},{0.143750,0.481250,0.025000,0.025000},{0.143750,0.481250,0.050000,0.050000},{0.156250,0.481250,0.025000,0.025000},{0.156250,0.481250,0.050000,0.050000},{0.168750,0.481250,0.025000,0.025000},{0.168750,0.481250,0.050000,0.050000},{0.181250,0.481250,0.025000,0.025000},{0.181250,0.481250,0.050000,0.050000},{0.193750,0.481250,0.025000,0.025000},{0.193750,0.481250,0.050000,0.050000},{0.206250,0.481250,0.025000,0.025000},{0.206250,0.481250,0.050000,0.050000},{0.218750,0.481250,0.025000,0.025000},{0.218750,0.481250,0.050000,0.050000},{0.231250,0.481250,0.025000,0.025000},{0.231250,0.481250,0.050000,0.050000},{0.243750,0.481250,0.025000,0.025000},{0.243750,0.481250,0.050000,0.050000},{0.256250,0.481250,0.025000,0.025000},{0.256250,0.481250,0.050000,0.050000},{0.268750,0.481250,0.025000,0.025000},{0.268750,0.481250,0.050000,0.050000},{0.281250,0.481250,0.025000,0.025000},{0.281250,0.481250,0.050000,0.050000},{0.293750,0.481250,0.025000,0.025000},{0.293750,0.481250,0.050000,0.050000},{0.306250,0.481250,0.025000,0.025000},{0.306250,0.481250,0.050000,0.050000},{0.318750,0.481250,0.025000,0.025000},{0.318750,0.481250,0.050000,0.050000},{0.331250,0.481250,0.025000,0.025000},{0.331250,0.481250,0.050000,0.050000},{0.343750,0.481250,0.025000,0.025000},{0.343750,0.481250,0.050000,0.050000},{0.356250,0.481250,0.025000,0.025000},{0.356250,0.481250,0.050000,0.050000},{0.368750,0.481250,0.025000,0.025000},{0.368750,0.481250,0.050000,0.050000},{0.381250,0.481250,0.025000,0.025000},{0.381250,0.481250,0.050000,0.050000},{0.393750,0.481250,0.025000,0.025000},{0.393750,0.481250,0.050000,0.050000},{0.406250,0.481250,0.025000,0.025000},{0.406250,0.481250,0.050000,0.050000},{0.418750,0.481250,0.025000,0.025000},{0.418750,0.481250,0.050000,0.050000},{0.431250,0.481250,0.025000,0.025000},{0.431250,0.481250,0.050000,0.050000},{0.443750,0.481250,0.025000,0.025000},{0.443750,0.481250,0.050000,0.050000},{0.456250,0.481250,0.025000,0.025000},{0.456250,0.481250,0.050000,0.050000},{0.468750,0.481250,0.025000,0.025000},{0.468750,0.481250,0.050000,0.050000},{0.481250,0.481250,0.025000,0.025000},{0.481250,0.481250,0.050000,0.050000},{0.493750,0.481250,0.025000,0.025000},{0.493750,0.481250,0.050000,0.050000},{0.506250,0.481250,0.025000,0.025000},{0.506250,0.481250,0.050000,0.050000},{0.518750,0.481250,0.025000,0.025000},{0.518750,0.481250,0.050000,0.050000},{0.531250,0.481250,0.025000,0.025000},{0.531250,0.481250,0.050000,0.050000},{0.543750,0.481250,0.025000,0.025000},{0.543750,0.481250,0.050000,0.050000},{0.556250,0.481250,0.025000,0.025000},{0.556250,0.481250,0.050000,0.050000},{0.568750,0.481250,0.025000,0.025000},{0.568750,0.481250,0.050000,0.050000},{0.581250,0.481250,0.025000,0.025000},{0.581250,0.481250,0.050000,0.050000},{0.593750,0.481250,0.025000,0.025000},{0.593750,0.481250,0.050000,0.050000},{0.606250,0.481250,0.025000,0.025000},{0.606250,0.481250,0.050000,0.050000},{0.618750,0.481250,0.025000,0.025000},{0.618750,0.481250,0.050000,0.050000},{0.631250,0.481250,0.025000,0.025000},{0.631250,0.481250,0.050000,0.050000},{0.643750,0.481250,0.025000,0.025000},{0.643750,0.481250,0.050000,0.050000},{0.656250,0.481250,0.025000,0.025000},{0.656250,0.481250,0.050000,0.050000},{0.668750,0.481250,0.025000,0.025000},{0.668750,0.481250,0.050000,0.050000},{0.681250,0.481250,0.025000,0.025000},{0.681250,0.481250,0.050000,0.050000},{0.693750,0.481250,0.025000,0.025000},{0.693750,0.481250,0.050000,0.050000},{0.706250,0.481250,0.025000,0.025000},{0.706250,0.481250,0.050000,0.050000},{0.718750,0.481250,0.025000,0.025000},{0.718750,0.481250,0.050000,0.050000},{0.731250,0.481250,0.025000,0.025000},{0.731250,0.481250,0.050000,0.050000},{0.743750,0.481250,0.025000,0.025000},{0.743750,0.481250,0.050000,0.050000},{0.756250,0.481250,0.025000,0.025000},{0.756250,0.481250,0.050000,0.050000},{0.768750,0.481250,0.025000,0.025000},{0.768750,0.481250,0.050000,0.050000},{0.781250,0.481250,0.025000,0.025000},{0.781250,0.481250,0.050000,0.050000},{0.793750,0.481250,0.025000,0.025000},{0.793750,0.481250,0.050000,0.050000},{0.806250,0.481250,0.025000,0.025000},{0.806250,0.481250,0.050000,0.050000},{0.818750,0.481250,0.025000,0.025000},{0.818750,0.481250,0.050000,0.050000},{0.831250,0.481250,0.025000,0.025000},{0.831250,0.481250,0.050000,0.050000},{0.843750,0.481250,0.025000,0.025000},{0.843750,0.481250,0.050000,0.050000},{0.856250,0.481250,0.025000,0.025000},{0.856250,0.481250,0.050000,0.050000},{0.868750,0.481250,0.025000,0.025000},{0.868750,0.481250,0.050000,0.050000},{0.881250,0.481250,0.025000,0.025000},{0.881250,0.481250,0.050000,0.050000},{0.893750,0.481250,0.025000,0.025000},{0.893750,0.481250,0.050000,0.050000},{0.906250,0.481250,0.025000,0.025000},{0.906250,0.481250,0.050000,0.050000},{0.918750,0.481250,0.025000,0.025000},{0.918750,0.481250,0.050000,0.050000},{0.931250,0.481250,0.025000,0.025000},{0.931250,0.481250,0.050000,0.050000},{0.943750,0.481250,0.025000,0.025000},{0.943750,0.481250,0.050000,0.050000},{0.956250,0.481250,0.025000,0.025000},{0.956250,0.481250,0.050000,0.050000},{0.968750,0.481250,0.025000,0.025000},{0.968750,0.481250,0.050000,0.050000},{0.981250,0.481250,0.025000,0.025000},{0.981250,0.481250,0.050000,0.050000},{0.993750,0.481250,0.025000,0.025000},{0.993750,0.481250,0.050000,0.050000},{0.006250,0.493750,0.025000,0.025000},{0.006250,0.493750,0.050000,0.050000},{0.018750,0.493750,0.025000,0.025000},{0.018750,0.493750,0.050000,0.050000},{0.031250,0.493750,0.025000,0.025000},{0.031250,0.493750,0.050000,0.050000},{0.043750,0.493750,0.025000,0.025000},{0.043750,0.493750,0.050000,0.050000},{0.056250,0.493750,0.025000,0.025000},{0.056250,0.493750,0.050000,0.050000},{0.068750,0.493750,0.025000,0.025000},{0.068750,0.493750,0.050000,0.050000},{0.081250,0.493750,0.025000,0.025000},{0.081250,0.493750,0.050000,0.050000},{0.093750,0.493750,0.025000,0.025000},{0.093750,0.493750,0.050000,0.050000},{0.106250,0.493750,0.025000,0.025000},{0.106250,0.493750,0.050000,0.050000},{0.118750,0.493750,0.025000,0.025000},{0.118750,0.493750,0.050000,0.050000},{0.131250,0.493750,0.025000,0.025000},{0.131250,0.493750,0.050000,0.050000},{0.143750,0.493750,0.025000,0.025000},{0.143750,0.493750,0.050000,0.050000},{0.156250,0.493750,0.025000,0.025000},{0.156250,0.493750,0.050000,0.050000},{0.168750,0.493750,0.025000,0.025000},{0.168750,0.493750,0.050000,0.050000},{0.181250,0.493750,0.025000,0.025000},{0.181250,0.493750,0.050000,0.050000},{0.193750,0.493750,0.025000,0.025000},{0.193750,0.493750,0.050000,0.050000},{0.206250,0.493750,0.025000,0.025000},{0.206250,0.493750,0.050000,0.050000},{0.218750,0.493750,0.025000,0.025000},{0.218750,0.493750,0.050000,0.050000},{0.231250,0.493750,0.025000,0.025000},{0.231250,0.493750,0.050000,0.050000},{0.243750,0.493750,0.025000,0.025000},{0.243750,0.493750,0.050000,0.050000},{0.256250,0.493750,0.025000,0.025000},{0.256250,0.493750,0.050000,0.050000},{0.268750,0.493750,0.025000,0.025000},{0.268750,0.493750,0.050000,0.050000},{0.281250,0.493750,0.025000,0.025000},{0.281250,0.493750,0.050000,0.050000},{0.293750,0.493750,0.025000,0.025000},{0.293750,0.493750,0.050000,0.050000},{0.306250,0.493750,0.025000,0.025000},{0.306250,0.493750,0.050000,0.050000},{0.318750,0.493750,0.025000,0.025000},{0.318750,0.493750,0.050000,0.050000},{0.331250,0.493750,0.025000,0.025000},{0.331250,0.493750,0.050000,0.050000},{0.343750,0.493750,0.025000,0.025000},{0.343750,0.493750,0.050000,0.050000},{0.356250,0.493750,0.025000,0.025000},{0.356250,0.493750,0.050000,0.050000},{0.368750,0.493750,0.025000,0.025000},{0.368750,0.493750,0.050000,0.050000},{0.381250,0.493750,0.025000,0.025000},{0.381250,0.493750,0.050000,0.050000},{0.393750,0.493750,0.025000,0.025000},{0.393750,0.493750,0.050000,0.050000},{0.406250,0.493750,0.025000,0.025000},{0.406250,0.493750,0.050000,0.050000},{0.418750,0.493750,0.025000,0.025000},{0.418750,0.493750,0.050000,0.050000},{0.431250,0.493750,0.025000,0.025000},{0.431250,0.493750,0.050000,0.050000},{0.443750,0.493750,0.025000,0.025000},{0.443750,0.493750,0.050000,0.050000},{0.456250,0.493750,0.025000,0.025000},{0.456250,0.493750,0.050000,0.050000},{0.468750,0.493750,0.025000,0.025000},{0.468750,0.493750,0.050000,0.050000},{0.481250,0.493750,0.025000,0.025000},{0.481250,0.493750,0.050000,0.050000},{0.493750,0.493750,0.025000,0.025000},{0.493750,0.493750,0.050000,0.050000},{0.506250,0.493750,0.025000,0.025000},{0.506250,0.493750,0.050000,0.050000},{0.518750,0.493750,0.025000,0.025000},{0.518750,0.493750,0.050000,0.050000},{0.531250,0.493750,0.025000,0.025000},{0.531250,0.493750,0.050000,0.050000},{0.543750,0.493750,0.025000,0.025000},{0.543750,0.493750,0.050000,0.050000},{0.556250,0.493750,0.025000,0.025000},{0.556250,0.493750,0.050000,0.050000},{0.568750,0.493750,0.025000,0.025000},{0.568750,0.493750,0.050000,0.050000},{0.581250,0.493750,0.025000,0.025000},{0.581250,0.493750,0.050000,0.050000},{0.593750,0.493750,0.025000,0.025000},{0.593750,0.493750,0.050000,0.050000},{0.606250,0.493750,0.025000,0.025000},{0.606250,0.493750,0.050000,0.050000},{0.618750,0.493750,0.025000,0.025000},{0.618750,0.493750,0.050000,0.050000},{0.631250,0.493750,0.025000,0.025000},{0.631250,0.493750,0.050000,0.050000},{0.643750,0.493750,0.025000,0.025000},{0.643750,0.493750,0.050000,0.050000},{0.656250,0.493750,0.025000,0.025000},{0.656250,0.493750,0.050000,0.050000},{0.668750,0.493750,0.025000,0.025000},{0.668750,0.493750,0.050000,0.050000},{0.681250,0.493750,0.025000,0.025000},{0.681250,0.493750,0.050000,0.050000},{0.693750,0.493750,0.025000,0.025000},{0.693750,0.493750,0.050000,0.050000},{0.706250,0.493750,0.025000,0.025000},{0.706250,0.493750,0.050000,0.050000},{0.718750,0.493750,0.025000,0.025000},{0.718750,0.493750,0.050000,0.050000},{0.731250,0.493750,0.025000,0.025000},{0.731250,0.493750,0.050000,0.050000},{0.743750,0.493750,0.025000,0.025000},{0.743750,0.493750,0.050000,0.050000},{0.756250,0.493750,0.025000,0.025000},{0.756250,0.493750,0.050000,0.050000},{0.768750,0.493750,0.025000,0.025000},{0.768750,0.493750,0.050000,0.050000},{0.781250,0.493750,0.025000,0.025000},{0.781250,0.493750,0.050000,0.050000},{0.793750,0.493750,0.025000,0.025000},{0.793750,0.493750,0.050000,0.050000},{0.806250,0.493750,0.025000,0.025000},{0.806250,0.493750,0.050000,0.050000},{0.818750,0.493750,0.025000,0.025000},{0.818750,0.493750,0.050000,0.050000},{0.831250,0.493750,0.025000,0.025000},{0.831250,0.493750,0.050000,0.050000},{0.843750,0.493750,0.025000,0.025000},{0.843750,0.493750,0.050000,0.050000},{0.856250,0.493750,0.025000,0.025000},{0.856250,0.493750,0.050000,0.050000},{0.868750,0.493750,0.025000,0.025000},{0.868750,0.493750,0.050000,0.050000},{0.881250,0.493750,0.025000,0.025000},{0.881250,0.493750,0.050000,0.050000},{0.893750,0.493750,0.025000,0.025000},{0.893750,0.493750,0.050000,0.050000},{0.906250,0.493750,0.025000,0.025000},{0.906250,0.493750,0.050000,0.050000},{0.918750,0.493750,0.025000,0.025000},{0.918750,0.493750,0.050000,0.050000},{0.931250,0.493750,0.025000,0.025000},{0.931250,0.493750,0.050000,0.050000},{0.943750,0.493750,0.025000,0.025000},{0.943750,0.493750,0.050000,0.050000},{0.956250,0.493750,0.025000,0.025000},{0.956250,0.493750,0.050000,0.050000},{0.968750,0.493750,0.025000,0.025000},{0.968750,0.493750,0.050000,0.050000},{0.981250,0.493750,0.025000,0.025000},{0.981250,0.493750,0.050000,0.050000},{0.993750,0.493750,0.025000,0.025000},{0.993750,0.493750,0.050000,0.050000},{0.006250,0.506250,0.025000,0.025000},{0.006250,0.506250,0.050000,0.050000},{0.018750,0.506250,0.025000,0.025000},{0.018750,0.506250,0.050000,0.050000},{0.031250,0.506250,0.025000,0.025000},{0.031250,0.506250,0.050000,0.050000},{0.043750,0.506250,0.025000,0.025000},{0.043750,0.506250,0.050000,0.050000},{0.056250,0.506250,0.025000,0.025000},{0.056250,0.506250,0.050000,0.050000},{0.068750,0.506250,0.025000,0.025000},{0.068750,0.506250,0.050000,0.050000},{0.081250,0.506250,0.025000,0.025000},{0.081250,0.506250,0.050000,0.050000},{0.093750,0.506250,0.025000,0.025000},{0.093750,0.506250,0.050000,0.050000},{0.106250,0.506250,0.025000,0.025000},{0.106250,0.506250,0.050000,0.050000},{0.118750,0.506250,0.025000,0.025000},{0.118750,0.506250,0.050000,0.050000},{0.131250,0.506250,0.025000,0.025000},{0.131250,0.506250,0.050000,0.050000},{0.143750,0.506250,0.025000,0.025000},{0.143750,0.506250,0.050000,0.050000},{0.156250,0.506250,0.025000,0.025000},{0.156250,0.506250,0.050000,0.050000},{0.168750,0.506250,0.025000,0.025000},{0.168750,0.506250,0.050000,0.050000},{0.181250,0.506250,0.025000,0.025000},{0.181250,0.506250,0.050000,0.050000},{0.193750,0.506250,0.025000,0.025000},{0.193750,0.506250,0.050000,0.050000},{0.206250,0.506250,0.025000,0.025000},{0.206250,0.506250,0.050000,0.050000},{0.218750,0.506250,0.025000,0.025000},{0.218750,0.506250,0.050000,0.050000},{0.231250,0.506250,0.025000,0.025000},{0.231250,0.506250,0.050000,0.050000},{0.243750,0.506250,0.025000,0.025000},{0.243750,0.506250,0.050000,0.050000},{0.256250,0.506250,0.025000,0.025000},{0.256250,0.506250,0.050000,0.050000},{0.268750,0.506250,0.025000,0.025000},{0.268750,0.506250,0.050000,0.050000},{0.281250,0.506250,0.025000,0.025000},{0.281250,0.506250,0.050000,0.050000},{0.293750,0.506250,0.025000,0.025000},{0.293750,0.506250,0.050000,0.050000},{0.306250,0.506250,0.025000,0.025000},{0.306250,0.506250,0.050000,0.050000},{0.318750,0.506250,0.025000,0.025000},{0.318750,0.506250,0.050000,0.050000},{0.331250,0.506250,0.025000,0.025000},{0.331250,0.506250,0.050000,0.050000},{0.343750,0.506250,0.025000,0.025000},{0.343750,0.506250,0.050000,0.050000},{0.356250,0.506250,0.025000,0.025000},{0.356250,0.506250,0.050000,0.050000},{0.368750,0.506250,0.025000,0.025000},{0.368750,0.506250,0.050000,0.050000},{0.381250,0.506250,0.025000,0.025000},{0.381250,0.506250,0.050000,0.050000},{0.393750,0.506250,0.025000,0.025000},{0.393750,0.506250,0.050000,0.050000},{0.406250,0.506250,0.025000,0.025000},{0.406250,0.506250,0.050000,0.050000},{0.418750,0.506250,0.025000,0.025000},{0.418750,0.506250,0.050000,0.050000},{0.431250,0.506250,0.025000,0.025000},{0.431250,0.506250,0.050000,0.050000},{0.443750,0.506250,0.025000,0.025000},{0.443750,0.506250,0.050000,0.050000},{0.456250,0.506250,0.025000,0.025000},{0.456250,0.506250,0.050000,0.050000},{0.468750,0.506250,0.025000,0.025000},{0.468750,0.506250,0.050000,0.050000},{0.481250,0.506250,0.025000,0.025000},{0.481250,0.506250,0.050000,0.050000},{0.493750,0.506250,0.025000,0.025000},{0.493750,0.506250,0.050000,0.050000},{0.506250,0.506250,0.025000,0.025000},{0.506250,0.506250,0.050000,0.050000},{0.518750,0.506250,0.025000,0.025000},{0.518750,0.506250,0.050000,0.050000},{0.531250,0.506250,0.025000,0.025000},{0.531250,0.506250,0.050000,0.050000},{0.543750,0.506250,0.025000,0.025000},{0.543750,0.506250,0.050000,0.050000},{0.556250,0.506250,0.025000,0.025000},{0.556250,0.506250,0.050000,0.050000},{0.568750,0.506250,0.025000,0.025000},{0.568750,0.506250,0.050000,0.050000},{0.581250,0.506250,0.025000,0.025000},{0.581250,0.506250,0.050000,0.050000},{0.593750,0.506250,0.025000,0.025000},{0.593750,0.506250,0.050000,0.050000},{0.606250,0.506250,0.025000,0.025000},{0.606250,0.506250,0.050000,0.050000},{0.618750,0.506250,0.025000,0.025000},{0.618750,0.506250,0.050000,0.050000},{0.631250,0.506250,0.025000,0.025000},{0.631250,0.506250,0.050000,0.050000},{0.643750,0.506250,0.025000,0.025000},{0.643750,0.506250,0.050000,0.050000},{0.656250,0.506250,0.025000,0.025000},{0.656250,0.506250,0.050000,0.050000},{0.668750,0.506250,0.025000,0.025000},{0.668750,0.506250,0.050000,0.050000},{0.681250,0.506250,0.025000,0.025000},{0.681250,0.506250,0.050000,0.050000},{0.693750,0.506250,0.025000,0.025000},{0.693750,0.506250,0.050000,0.050000},{0.706250,0.506250,0.025000,0.025000},{0.706250,0.506250,0.050000,0.050000},{0.718750,0.506250,0.025000,0.025000},{0.718750,0.506250,0.050000,0.050000},{0.731250,0.506250,0.025000,0.025000},{0.731250,0.506250,0.050000,0.050000},{0.743750,0.506250,0.025000,0.025000},{0.743750,0.506250,0.050000,0.050000},{0.756250,0.506250,0.025000,0.025000},{0.756250,0.506250,0.050000,0.050000},{0.768750,0.506250,0.025000,0.025000},{0.768750,0.506250,0.050000,0.050000},{0.781250,0.506250,0.025000,0.025000},{0.781250,0.506250,0.050000,0.050000},{0.793750,0.506250,0.025000,0.025000},{0.793750,0.506250,0.050000,0.050000},{0.806250,0.506250,0.025000,0.025000},{0.806250,0.506250,0.050000,0.050000},{0.818750,0.506250,0.025000,0.025000},{0.818750,0.506250,0.050000,0.050000},{0.831250,0.506250,0.025000,0.025000},{0.831250,0.506250,0.050000,0.050000},{0.843750,0.506250,0.025000,0.025000},{0.843750,0.506250,0.050000,0.050000},{0.856250,0.506250,0.025000,0.025000},{0.856250,0.506250,0.050000,0.050000},{0.868750,0.506250,0.025000,0.025000},{0.868750,0.506250,0.050000,0.050000},{0.881250,0.506250,0.025000,0.025000},{0.881250,0.506250,0.050000,0.050000},{0.893750,0.506250,0.025000,0.025000},{0.893750,0.506250,0.050000,0.050000},{0.906250,0.506250,0.025000,0.025000},{0.906250,0.506250,0.050000,0.050000},{0.918750,0.506250,0.025000,0.025000},{0.918750,0.506250,0.050000,0.050000},{0.931250,0.506250,0.025000,0.025000},{0.931250,0.506250,0.050000,0.050000},{0.943750,0.506250,0.025000,0.025000},{0.943750,0.506250,0.050000,0.050000},{0.956250,0.506250,0.025000,0.025000},{0.956250,0.506250,0.050000,0.050000},{0.968750,0.506250,0.025000,0.025000},{0.968750,0.506250,0.050000,0.050000},{0.981250,0.506250,0.025000,0.025000},{0.981250,0.506250,0.050000,0.050000},{0.993750,0.506250,0.025000,0.025000},{0.993750,0.506250,0.050000,0.050000},{0.006250,0.518750,0.025000,0.025000},{0.006250,0.518750,0.050000,0.050000},{0.018750,0.518750,0.025000,0.025000},{0.018750,0.518750,0.050000,0.050000},{0.031250,0.518750,0.025000,0.025000},{0.031250,0.518750,0.050000,0.050000},{0.043750,0.518750,0.025000,0.025000},{0.043750,0.518750,0.050000,0.050000},{0.056250,0.518750,0.025000,0.025000},{0.056250,0.518750,0.050000,0.050000},{0.068750,0.518750,0.025000,0.025000},{0.068750,0.518750,0.050000,0.050000},{0.081250,0.518750,0.025000,0.025000},{0.081250,0.518750,0.050000,0.050000},{0.093750,0.518750,0.025000,0.025000},{0.093750,0.518750,0.050000,0.050000},{0.106250,0.518750,0.025000,0.025000},{0.106250,0.518750,0.050000,0.050000},{0.118750,0.518750,0.025000,0.025000},{0.118750,0.518750,0.050000,0.050000},{0.131250,0.518750,0.025000,0.025000},{0.131250,0.518750,0.050000,0.050000},{0.143750,0.518750,0.025000,0.025000},{0.143750,0.518750,0.050000,0.050000},{0.156250,0.518750,0.025000,0.025000},{0.156250,0.518750,0.050000,0.050000},{0.168750,0.518750,0.025000,0.025000},{0.168750,0.518750,0.050000,0.050000},{0.181250,0.518750,0.025000,0.025000},{0.181250,0.518750,0.050000,0.050000},{0.193750,0.518750,0.025000,0.025000},{0.193750,0.518750,0.050000,0.050000},{0.206250,0.518750,0.025000,0.025000},{0.206250,0.518750,0.050000,0.050000},{0.218750,0.518750,0.025000,0.025000},{0.218750,0.518750,0.050000,0.050000},{0.231250,0.518750,0.025000,0.025000},{0.231250,0.518750,0.050000,0.050000},{0.243750,0.518750,0.025000,0.025000},{0.243750,0.518750,0.050000,0.050000},{0.256250,0.518750,0.025000,0.025000},{0.256250,0.518750,0.050000,0.050000},{0.268750,0.518750,0.025000,0.025000},{0.268750,0.518750,0.050000,0.050000},{0.281250,0.518750,0.025000,0.025000},{0.281250,0.518750,0.050000,0.050000},{0.293750,0.518750,0.025000,0.025000},{0.293750,0.518750,0.050000,0.050000},{0.306250,0.518750,0.025000,0.025000},{0.306250,0.518750,0.050000,0.050000},{0.318750,0.518750,0.025000,0.025000},{0.318750,0.518750,0.050000,0.050000},{0.331250,0.518750,0.025000,0.025000},{0.331250,0.518750,0.050000,0.050000},{0.343750,0.518750,0.025000,0.025000},{0.343750,0.518750,0.050000,0.050000},{0.356250,0.518750,0.025000,0.025000},{0.356250,0.518750,0.050000,0.050000},{0.368750,0.518750,0.025000,0.025000},{0.368750,0.518750,0.050000,0.050000},{0.381250,0.518750,0.025000,0.025000},{0.381250,0.518750,0.050000,0.050000},{0.393750,0.518750,0.025000,0.025000},{0.393750,0.518750,0.050000,0.050000},{0.406250,0.518750,0.025000,0.025000},{0.406250,0.518750,0.050000,0.050000},{0.418750,0.518750,0.025000,0.025000},{0.418750,0.518750,0.050000,0.050000},{0.431250,0.518750,0.025000,0.025000},{0.431250,0.518750,0.050000,0.050000},{0.443750,0.518750,0.025000,0.025000},{0.443750,0.518750,0.050000,0.050000},{0.456250,0.518750,0.025000,0.025000},{0.456250,0.518750,0.050000,0.050000},{0.468750,0.518750,0.025000,0.025000},{0.468750,0.518750,0.050000,0.050000},{0.481250,0.518750,0.025000,0.025000},{0.481250,0.518750,0.050000,0.050000},{0.493750,0.518750,0.025000,0.025000},{0.493750,0.518750,0.050000,0.050000},{0.506250,0.518750,0.025000,0.025000},{0.506250,0.518750,0.050000,0.050000},{0.518750,0.518750,0.025000,0.025000},{0.518750,0.518750,0.050000,0.050000},{0.531250,0.518750,0.025000,0.025000},{0.531250,0.518750,0.050000,0.050000},{0.543750,0.518750,0.025000,0.025000},{0.543750,0.518750,0.050000,0.050000},{0.556250,0.518750,0.025000,0.025000},{0.556250,0.518750,0.050000,0.050000},{0.568750,0.518750,0.025000,0.025000},{0.568750,0.518750,0.050000,0.050000},{0.581250,0.518750,0.025000,0.025000},{0.581250,0.518750,0.050000,0.050000},{0.593750,0.518750,0.025000,0.025000},{0.593750,0.518750,0.050000,0.050000},{0.606250,0.518750,0.025000,0.025000},{0.606250,0.518750,0.050000,0.050000},{0.618750,0.518750,0.025000,0.025000},{0.618750,0.518750,0.050000,0.050000},{0.631250,0.518750,0.025000,0.025000},{0.631250,0.518750,0.050000,0.050000},{0.643750,0.518750,0.025000,0.025000},{0.643750,0.518750,0.050000,0.050000},{0.656250,0.518750,0.025000,0.025000},{0.656250,0.518750,0.050000,0.050000},{0.668750,0.518750,0.025000,0.025000},{0.668750,0.518750,0.050000,0.050000},{0.681250,0.518750,0.025000,0.025000},{0.681250,0.518750,0.050000,0.050000},{0.693750,0.518750,0.025000,0.025000},{0.693750,0.518750,0.050000,0.050000},{0.706250,0.518750,0.025000,0.025000},{0.706250,0.518750,0.050000,0.050000},{0.718750,0.518750,0.025000,0.025000},{0.718750,0.518750,0.050000,0.050000},{0.731250,0.518750,0.025000,0.025000},{0.731250,0.518750,0.050000,0.050000},{0.743750,0.518750,0.025000,0.025000},{0.743750,0.518750,0.050000,0.050000},{0.756250,0.518750,0.025000,0.025000},{0.756250,0.518750,0.050000,0.050000},{0.768750,0.518750,0.025000,0.025000},{0.768750,0.518750,0.050000,0.050000},{0.781250,0.518750,0.025000,0.025000},{0.781250,0.518750,0.050000,0.050000},{0.793750,0.518750,0.025000,0.025000},{0.793750,0.518750,0.050000,0.050000},{0.806250,0.518750,0.025000,0.025000},{0.806250,0.518750,0.050000,0.050000},{0.818750,0.518750,0.025000,0.025000},{0.818750,0.518750,0.050000,0.050000},{0.831250,0.518750,0.025000,0.025000},{0.831250,0.518750,0.050000,0.050000},{0.843750,0.518750,0.025000,0.025000},{0.843750,0.518750,0.050000,0.050000},{0.856250,0.518750,0.025000,0.025000},{0.856250,0.518750,0.050000,0.050000},{0.868750,0.518750,0.025000,0.025000},{0.868750,0.518750,0.050000,0.050000},{0.881250,0.518750,0.025000,0.025000},{0.881250,0.518750,0.050000,0.050000},{0.893750,0.518750,0.025000,0.025000},{0.893750,0.518750,0.050000,0.050000},{0.906250,0.518750,0.025000,0.025000},{0.906250,0.518750,0.050000,0.050000},{0.918750,0.518750,0.025000,0.025000},{0.918750,0.518750,0.050000,0.050000},{0.931250,0.518750,0.025000,0.025000},{0.931250,0.518750,0.050000,0.050000},{0.943750,0.518750,0.025000,0.025000},{0.943750,0.518750,0.050000,0.050000},{0.956250,0.518750,0.025000,0.025000},{0.956250,0.518750,0.050000,0.050000},{0.968750,0.518750,0.025000,0.025000},{0.968750,0.518750,0.050000,0.050000},{0.981250,0.518750,0.025000,0.025000},{0.981250,0.518750,0.050000,0.050000},{0.993750,0.518750,0.025000,0.025000},{0.993750,0.518750,0.050000,0.050000},{0.006250,0.531250,0.025000,0.025000},{0.006250,0.531250,0.050000,0.050000},{0.018750,0.531250,0.025000,0.025000},{0.018750,0.531250,0.050000,0.050000},{0.031250,0.531250,0.025000,0.025000},{0.031250,0.531250,0.050000,0.050000},{0.043750,0.531250,0.025000,0.025000},{0.043750,0.531250,0.050000,0.050000},{0.056250,0.531250,0.025000,0.025000},{0.056250,0.531250,0.050000,0.050000},{0.068750,0.531250,0.025000,0.025000},{0.068750,0.531250,0.050000,0.050000},{0.081250,0.531250,0.025000,0.025000},{0.081250,0.531250,0.050000,0.050000},{0.093750,0.531250,0.025000,0.025000},{0.093750,0.531250,0.050000,0.050000},{0.106250,0.531250,0.025000,0.025000},{0.106250,0.531250,0.050000,0.050000},{0.118750,0.531250,0.025000,0.025000},{0.118750,0.531250,0.050000,0.050000},{0.131250,0.531250,0.025000,0.025000},{0.131250,0.531250,0.050000,0.050000},{0.143750,0.531250,0.025000,0.025000},{0.143750,0.531250,0.050000,0.050000},{0.156250,0.531250,0.025000,0.025000},{0.156250,0.531250,0.050000,0.050000},{0.168750,0.531250,0.025000,0.025000},{0.168750,0.531250,0.050000,0.050000},{0.181250,0.531250,0.025000,0.025000},{0.181250,0.531250,0.050000,0.050000},{0.193750,0.531250,0.025000,0.025000},{0.193750,0.531250,0.050000,0.050000},{0.206250,0.531250,0.025000,0.025000},{0.206250,0.531250,0.050000,0.050000},{0.218750,0.531250,0.025000,0.025000},{0.218750,0.531250,0.050000,0.050000},{0.231250,0.531250,0.025000,0.025000},{0.231250,0.531250,0.050000,0.050000},{0.243750,0.531250,0.025000,0.025000},{0.243750,0.531250,0.050000,0.050000},{0.256250,0.531250,0.025000,0.025000},{0.256250,0.531250,0.050000,0.050000},{0.268750,0.531250,0.025000,0.025000},{0.268750,0.531250,0.050000,0.050000},{0.281250,0.531250,0.025000,0.025000},{0.281250,0.531250,0.050000,0.050000},{0.293750,0.531250,0.025000,0.025000},{0.293750,0.531250,0.050000,0.050000},{0.306250,0.531250,0.025000,0.025000},{0.306250,0.531250,0.050000,0.050000},{0.318750,0.531250,0.025000,0.025000},{0.318750,0.531250,0.050000,0.050000},{0.331250,0.531250,0.025000,0.025000},{0.331250,0.531250,0.050000,0.050000},{0.343750,0.531250,0.025000,0.025000},{0.343750,0.531250,0.050000,0.050000},{0.356250,0.531250,0.025000,0.025000},{0.356250,0.531250,0.050000,0.050000},{0.368750,0.531250,0.025000,0.025000},{0.368750,0.531250,0.050000,0.050000},{0.381250,0.531250,0.025000,0.025000},{0.381250,0.531250,0.050000,0.050000},{0.393750,0.531250,0.025000,0.025000},{0.393750,0.531250,0.050000,0.050000},{0.406250,0.531250,0.025000,0.025000},{0.406250,0.531250,0.050000,0.050000},{0.418750,0.531250,0.025000,0.025000},{0.418750,0.531250,0.050000,0.050000},{0.431250,0.531250,0.025000,0.025000},{0.431250,0.531250,0.050000,0.050000},{0.443750,0.531250,0.025000,0.025000},{0.443750,0.531250,0.050000,0.050000},{0.456250,0.531250,0.025000,0.025000},{0.456250,0.531250,0.050000,0.050000},{0.468750,0.531250,0.025000,0.025000},{0.468750,0.531250,0.050000,0.050000},{0.481250,0.531250,0.025000,0.025000},{0.481250,0.531250,0.050000,0.050000},{0.493750,0.531250,0.025000,0.025000},{0.493750,0.531250,0.050000,0.050000},{0.506250,0.531250,0.025000,0.025000},{0.506250,0.531250,0.050000,0.050000},{0.518750,0.531250,0.025000,0.025000},{0.518750,0.531250,0.050000,0.050000},{0.531250,0.531250,0.025000,0.025000},{0.531250,0.531250,0.050000,0.050000},{0.543750,0.531250,0.025000,0.025000},{0.543750,0.531250,0.050000,0.050000},{0.556250,0.531250,0.025000,0.025000},{0.556250,0.531250,0.050000,0.050000},{0.568750,0.531250,0.025000,0.025000},{0.568750,0.531250,0.050000,0.050000},{0.581250,0.531250,0.025000,0.025000},{0.581250,0.531250,0.050000,0.050000},{0.593750,0.531250,0.025000,0.025000},{0.593750,0.531250,0.050000,0.050000},{0.606250,0.531250,0.025000,0.025000},{0.606250,0.531250,0.050000,0.050000},{0.618750,0.531250,0.025000,0.025000},{0.618750,0.531250,0.050000,0.050000},{0.631250,0.531250,0.025000,0.025000},{0.631250,0.531250,0.050000,0.050000},{0.643750,0.531250,0.025000,0.025000},{0.643750,0.531250,0.050000,0.050000},{0.656250,0.531250,0.025000,0.025000},{0.656250,0.531250,0.050000,0.050000},{0.668750,0.531250,0.025000,0.025000},{0.668750,0.531250,0.050000,0.050000},{0.681250,0.531250,0.025000,0.025000},{0.681250,0.531250,0.050000,0.050000},{0.693750,0.531250,0.025000,0.025000},{0.693750,0.531250,0.050000,0.050000},{0.706250,0.531250,0.025000,0.025000},{0.706250,0.531250,0.050000,0.050000},{0.718750,0.531250,0.025000,0.025000},{0.718750,0.531250,0.050000,0.050000},{0.731250,0.531250,0.025000,0.025000},{0.731250,0.531250,0.050000,0.050000},{0.743750,0.531250,0.025000,0.025000},{0.743750,0.531250,0.050000,0.050000},{0.756250,0.531250,0.025000,0.025000},{0.756250,0.531250,0.050000,0.050000},{0.768750,0.531250,0.025000,0.025000},{0.768750,0.531250,0.050000,0.050000},{0.781250,0.531250,0.025000,0.025000},{0.781250,0.531250,0.050000,0.050000},{0.793750,0.531250,0.025000,0.025000},{0.793750,0.531250,0.050000,0.050000},{0.806250,0.531250,0.025000,0.025000},{0.806250,0.531250,0.050000,0.050000},{0.818750,0.531250,0.025000,0.025000},{0.818750,0.531250,0.050000,0.050000},{0.831250,0.531250,0.025000,0.025000},{0.831250,0.531250,0.050000,0.050000},{0.843750,0.531250,0.025000,0.025000},{0.843750,0.531250,0.050000,0.050000},{0.856250,0.531250,0.025000,0.025000},{0.856250,0.531250,0.050000,0.050000},{0.868750,0.531250,0.025000,0.025000},{0.868750,0.531250,0.050000,0.050000},{0.881250,0.531250,0.025000,0.025000},{0.881250,0.531250,0.050000,0.050000},{0.893750,0.531250,0.025000,0.025000},{0.893750,0.531250,0.050000,0.050000},{0.906250,0.531250,0.025000,0.025000},{0.906250,0.531250,0.050000,0.050000},{0.918750,0.531250,0.025000,0.025000},{0.918750,0.531250,0.050000,0.050000},{0.931250,0.531250,0.025000,0.025000},{0.931250,0.531250,0.050000,0.050000},{0.943750,0.531250,0.025000,0.025000},{0.943750,0.531250,0.050000,0.050000},{0.956250,0.531250,0.025000,0.025000},{0.956250,0.531250,0.050000,0.050000},{0.968750,0.531250,0.025000,0.025000},{0.968750,0.531250,0.050000,0.050000},{0.981250,0.531250,0.025000,0.025000},{0.981250,0.531250,0.050000,0.050000},{0.993750,0.531250,0.025000,0.025000},{0.993750,0.531250,0.050000,0.050000},{0.006250,0.543750,0.025000,0.025000},{0.006250,0.543750,0.050000,0.050000},{0.018750,0.543750,0.025000,0.025000},{0.018750,0.543750,0.050000,0.050000},{0.031250,0.543750,0.025000,0.025000},{0.031250,0.543750,0.050000,0.050000},{0.043750,0.543750,0.025000,0.025000},{0.043750,0.543750,0.050000,0.050000},{0.056250,0.543750,0.025000,0.025000},{0.056250,0.543750,0.050000,0.050000},{0.068750,0.543750,0.025000,0.025000},{0.068750,0.543750,0.050000,0.050000},{0.081250,0.543750,0.025000,0.025000},{0.081250,0.543750,0.050000,0.050000},{0.093750,0.543750,0.025000,0.025000},{0.093750,0.543750,0.050000,0.050000},{0.106250,0.543750,0.025000,0.025000},{0.106250,0.543750,0.050000,0.050000},{0.118750,0.543750,0.025000,0.025000},{0.118750,0.543750,0.050000,0.050000},{0.131250,0.543750,0.025000,0.025000},{0.131250,0.543750,0.050000,0.050000},{0.143750,0.543750,0.025000,0.025000},{0.143750,0.543750,0.050000,0.050000},{0.156250,0.543750,0.025000,0.025000},{0.156250,0.543750,0.050000,0.050000},{0.168750,0.543750,0.025000,0.025000},{0.168750,0.543750,0.050000,0.050000},{0.181250,0.543750,0.025000,0.025000},{0.181250,0.543750,0.050000,0.050000},{0.193750,0.543750,0.025000,0.025000},{0.193750,0.543750,0.050000,0.050000},{0.206250,0.543750,0.025000,0.025000},{0.206250,0.543750,0.050000,0.050000},{0.218750,0.543750,0.025000,0.025000},{0.218750,0.543750,0.050000,0.050000},{0.231250,0.543750,0.025000,0.025000},{0.231250,0.543750,0.050000,0.050000},{0.243750,0.543750,0.025000,0.025000},{0.243750,0.543750,0.050000,0.050000},{0.256250,0.543750,0.025000,0.025000},{0.256250,0.543750,0.050000,0.050000},{0.268750,0.543750,0.025000,0.025000},{0.268750,0.543750,0.050000,0.050000},{0.281250,0.543750,0.025000,0.025000},{0.281250,0.543750,0.050000,0.050000},{0.293750,0.543750,0.025000,0.025000},{0.293750,0.543750,0.050000,0.050000},{0.306250,0.543750,0.025000,0.025000},{0.306250,0.543750,0.050000,0.050000},{0.318750,0.543750,0.025000,0.025000},{0.318750,0.543750,0.050000,0.050000},{0.331250,0.543750,0.025000,0.025000},{0.331250,0.543750,0.050000,0.050000},{0.343750,0.543750,0.025000,0.025000},{0.343750,0.543750,0.050000,0.050000},{0.356250,0.543750,0.025000,0.025000},{0.356250,0.543750,0.050000,0.050000},{0.368750,0.543750,0.025000,0.025000},{0.368750,0.543750,0.050000,0.050000},{0.381250,0.543750,0.025000,0.025000},{0.381250,0.543750,0.050000,0.050000},{0.393750,0.543750,0.025000,0.025000},{0.393750,0.543750,0.050000,0.050000},{0.406250,0.543750,0.025000,0.025000},{0.406250,0.543750,0.050000,0.050000},{0.418750,0.543750,0.025000,0.025000},{0.418750,0.543750,0.050000,0.050000},{0.431250,0.543750,0.025000,0.025000},{0.431250,0.543750,0.050000,0.050000},{0.443750,0.543750,0.025000,0.025000},{0.443750,0.543750,0.050000,0.050000},{0.456250,0.543750,0.025000,0.025000},{0.456250,0.543750,0.050000,0.050000},{0.468750,0.543750,0.025000,0.025000},{0.468750,0.543750,0.050000,0.050000},{0.481250,0.543750,0.025000,0.025000},{0.481250,0.543750,0.050000,0.050000},{0.493750,0.543750,0.025000,0.025000},{0.493750,0.543750,0.050000,0.050000},{0.506250,0.543750,0.025000,0.025000},{0.506250,0.543750,0.050000,0.050000},{0.518750,0.543750,0.025000,0.025000},{0.518750,0.543750,0.050000,0.050000},{0.531250,0.543750,0.025000,0.025000},{0.531250,0.543750,0.050000,0.050000},{0.543750,0.543750,0.025000,0.025000},{0.543750,0.543750,0.050000,0.050000},{0.556250,0.543750,0.025000,0.025000},{0.556250,0.543750,0.050000,0.050000},{0.568750,0.543750,0.025000,0.025000},{0.568750,0.543750,0.050000,0.050000},{0.581250,0.543750,0.025000,0.025000},{0.581250,0.543750,0.050000,0.050000},{0.593750,0.543750,0.025000,0.025000},{0.593750,0.543750,0.050000,0.050000},{0.606250,0.543750,0.025000,0.025000},{0.606250,0.543750,0.050000,0.050000},{0.618750,0.543750,0.025000,0.025000},{0.618750,0.543750,0.050000,0.050000},{0.631250,0.543750,0.025000,0.025000},{0.631250,0.543750,0.050000,0.050000},{0.643750,0.543750,0.025000,0.025000},{0.643750,0.543750,0.050000,0.050000},{0.656250,0.543750,0.025000,0.025000},{0.656250,0.543750,0.050000,0.050000},{0.668750,0.543750,0.025000,0.025000},{0.668750,0.543750,0.050000,0.050000},{0.681250,0.543750,0.025000,0.025000},{0.681250,0.543750,0.050000,0.050000},{0.693750,0.543750,0.025000,0.025000},{0.693750,0.543750,0.050000,0.050000},{0.706250,0.543750,0.025000,0.025000},{0.706250,0.543750,0.050000,0.050000},{0.718750,0.543750,0.025000,0.025000},{0.718750,0.543750,0.050000,0.050000},{0.731250,0.543750,0.025000,0.025000},{0.731250,0.543750,0.050000,0.050000},{0.743750,0.543750,0.025000,0.025000},{0.743750,0.543750,0.050000,0.050000},{0.756250,0.543750,0.025000,0.025000},{0.756250,0.543750,0.050000,0.050000},{0.768750,0.543750,0.025000,0.025000},{0.768750,0.543750,0.050000,0.050000},{0.781250,0.543750,0.025000,0.025000},{0.781250,0.543750,0.050000,0.050000},{0.793750,0.543750,0.025000,0.025000},{0.793750,0.543750,0.050000,0.050000},{0.806250,0.543750,0.025000,0.025000},{0.806250,0.543750,0.050000,0.050000},{0.818750,0.543750,0.025000,0.025000},{0.818750,0.543750,0.050000,0.050000},{0.831250,0.543750,0.025000,0.025000},{0.831250,0.543750,0.050000,0.050000},{0.843750,0.543750,0.025000,0.025000},{0.843750,0.543750,0.050000,0.050000},{0.856250,0.543750,0.025000,0.025000},{0.856250,0.543750,0.050000,0.050000},{0.868750,0.543750,0.025000,0.025000},{0.868750,0.543750,0.050000,0.050000},{0.881250,0.543750,0.025000,0.025000},{0.881250,0.543750,0.050000,0.050000},{0.893750,0.543750,0.025000,0.025000},{0.893750,0.543750,0.050000,0.050000},{0.906250,0.543750,0.025000,0.025000},{0.906250,0.543750,0.050000,0.050000},{0.918750,0.543750,0.025000,0.025000},{0.918750,0.543750,0.050000,0.050000},{0.931250,0.543750,0.025000,0.025000},{0.931250,0.543750,0.050000,0.050000},{0.943750,0.543750,0.025000,0.025000},{0.943750,0.543750,0.050000,0.050000},{0.956250,0.543750,0.025000,0.025000},{0.956250,0.543750,0.050000,0.050000},{0.968750,0.543750,0.025000,0.025000},{0.968750,0.543750,0.050000,0.050000},{0.981250,0.543750,0.025000,0.025000},{0.981250,0.543750,0.050000,0.050000},{0.993750,0.543750,0.025000,0.025000},{0.993750,0.543750,0.050000,0.050000},{0.006250,0.556250,0.025000,0.025000},{0.006250,0.556250,0.050000,0.050000},{0.018750,0.556250,0.025000,0.025000},{0.018750,0.556250,0.050000,0.050000},{0.031250,0.556250,0.025000,0.025000},{0.031250,0.556250,0.050000,0.050000},{0.043750,0.556250,0.025000,0.025000},{0.043750,0.556250,0.050000,0.050000},{0.056250,0.556250,0.025000,0.025000},{0.056250,0.556250,0.050000,0.050000},{0.068750,0.556250,0.025000,0.025000},{0.068750,0.556250,0.050000,0.050000},{0.081250,0.556250,0.025000,0.025000},{0.081250,0.556250,0.050000,0.050000},{0.093750,0.556250,0.025000,0.025000},{0.093750,0.556250,0.050000,0.050000},{0.106250,0.556250,0.025000,0.025000},{0.106250,0.556250,0.050000,0.050000},{0.118750,0.556250,0.025000,0.025000},{0.118750,0.556250,0.050000,0.050000},{0.131250,0.556250,0.025000,0.025000},{0.131250,0.556250,0.050000,0.050000},{0.143750,0.556250,0.025000,0.025000},{0.143750,0.556250,0.050000,0.050000},{0.156250,0.556250,0.025000,0.025000},{0.156250,0.556250,0.050000,0.050000},{0.168750,0.556250,0.025000,0.025000},{0.168750,0.556250,0.050000,0.050000},{0.181250,0.556250,0.025000,0.025000},{0.181250,0.556250,0.050000,0.050000},{0.193750,0.556250,0.025000,0.025000},{0.193750,0.556250,0.050000,0.050000},{0.206250,0.556250,0.025000,0.025000},{0.206250,0.556250,0.050000,0.050000},{0.218750,0.556250,0.025000,0.025000},{0.218750,0.556250,0.050000,0.050000},{0.231250,0.556250,0.025000,0.025000},{0.231250,0.556250,0.050000,0.050000},{0.243750,0.556250,0.025000,0.025000},{0.243750,0.556250,0.050000,0.050000},{0.256250,0.556250,0.025000,0.025000},{0.256250,0.556250,0.050000,0.050000},{0.268750,0.556250,0.025000,0.025000},{0.268750,0.556250,0.050000,0.050000},{0.281250,0.556250,0.025000,0.025000},{0.281250,0.556250,0.050000,0.050000},{0.293750,0.556250,0.025000,0.025000},{0.293750,0.556250,0.050000,0.050000},{0.306250,0.556250,0.025000,0.025000},{0.306250,0.556250,0.050000,0.050000},{0.318750,0.556250,0.025000,0.025000},{0.318750,0.556250,0.050000,0.050000},{0.331250,0.556250,0.025000,0.025000},{0.331250,0.556250,0.050000,0.050000},{0.343750,0.556250,0.025000,0.025000},{0.343750,0.556250,0.050000,0.050000},{0.356250,0.556250,0.025000,0.025000},{0.356250,0.556250,0.050000,0.050000},{0.368750,0.556250,0.025000,0.025000},{0.368750,0.556250,0.050000,0.050000},{0.381250,0.556250,0.025000,0.025000},{0.381250,0.556250,0.050000,0.050000},{0.393750,0.556250,0.025000,0.025000},{0.393750,0.556250,0.050000,0.050000},{0.406250,0.556250,0.025000,0.025000},{0.406250,0.556250,0.050000,0.050000},{0.418750,0.556250,0.025000,0.025000},{0.418750,0.556250,0.050000,0.050000},{0.431250,0.556250,0.025000,0.025000},{0.431250,0.556250,0.050000,0.050000},{0.443750,0.556250,0.025000,0.025000},{0.443750,0.556250,0.050000,0.050000},{0.456250,0.556250,0.025000,0.025000},{0.456250,0.556250,0.050000,0.050000},{0.468750,0.556250,0.025000,0.025000},{0.468750,0.556250,0.050000,0.050000},{0.481250,0.556250,0.025000,0.025000},{0.481250,0.556250,0.050000,0.050000},{0.493750,0.556250,0.025000,0.025000},{0.493750,0.556250,0.050000,0.050000},{0.506250,0.556250,0.025000,0.025000},{0.506250,0.556250,0.050000,0.050000},{0.518750,0.556250,0.025000,0.025000},{0.518750,0.556250,0.050000,0.050000},{0.531250,0.556250,0.025000,0.025000},{0.531250,0.556250,0.050000,0.050000},{0.543750,0.556250,0.025000,0.025000},{0.543750,0.556250,0.050000,0.050000},{0.556250,0.556250,0.025000,0.025000},{0.556250,0.556250,0.050000,0.050000},{0.568750,0.556250,0.025000,0.025000},{0.568750,0.556250,0.050000,0.050000},{0.581250,0.556250,0.025000,0.025000},{0.581250,0.556250,0.050000,0.050000},{0.593750,0.556250,0.025000,0.025000},{0.593750,0.556250,0.050000,0.050000},{0.606250,0.556250,0.025000,0.025000},{0.606250,0.556250,0.050000,0.050000},{0.618750,0.556250,0.025000,0.025000},{0.618750,0.556250,0.050000,0.050000},{0.631250,0.556250,0.025000,0.025000},{0.631250,0.556250,0.050000,0.050000},{0.643750,0.556250,0.025000,0.025000},{0.643750,0.556250,0.050000,0.050000},{0.656250,0.556250,0.025000,0.025000},{0.656250,0.556250,0.050000,0.050000},{0.668750,0.556250,0.025000,0.025000},{0.668750,0.556250,0.050000,0.050000},{0.681250,0.556250,0.025000,0.025000},{0.681250,0.556250,0.050000,0.050000},{0.693750,0.556250,0.025000,0.025000},{0.693750,0.556250,0.050000,0.050000},{0.706250,0.556250,0.025000,0.025000},{0.706250,0.556250,0.050000,0.050000},{0.718750,0.556250,0.025000,0.025000},{0.718750,0.556250,0.050000,0.050000},{0.731250,0.556250,0.025000,0.025000},{0.731250,0.556250,0.050000,0.050000},{0.743750,0.556250,0.025000,0.025000},{0.743750,0.556250,0.050000,0.050000},{0.756250,0.556250,0.025000,0.025000},{0.756250,0.556250,0.050000,0.050000},{0.768750,0.556250,0.025000,0.025000},{0.768750,0.556250,0.050000,0.050000},{0.781250,0.556250,0.025000,0.025000},{0.781250,0.556250,0.050000,0.050000},{0.793750,0.556250,0.025000,0.025000},{0.793750,0.556250,0.050000,0.050000},{0.806250,0.556250,0.025000,0.025000},{0.806250,0.556250,0.050000,0.050000},{0.818750,0.556250,0.025000,0.025000},{0.818750,0.556250,0.050000,0.050000},{0.831250,0.556250,0.025000,0.025000},{0.831250,0.556250,0.050000,0.050000},{0.843750,0.556250,0.025000,0.025000},{0.843750,0.556250,0.050000,0.050000},{0.856250,0.556250,0.025000,0.025000},{0.856250,0.556250,0.050000,0.050000},{0.868750,0.556250,0.025000,0.025000},{0.868750,0.556250,0.050000,0.050000},{0.881250,0.556250,0.025000,0.025000},{0.881250,0.556250,0.050000,0.050000},{0.893750,0.556250,0.025000,0.025000},{0.893750,0.556250,0.050000,0.050000},{0.906250,0.556250,0.025000,0.025000},{0.906250,0.556250,0.050000,0.050000},{0.918750,0.556250,0.025000,0.025000},{0.918750,0.556250,0.050000,0.050000},{0.931250,0.556250,0.025000,0.025000},{0.931250,0.556250,0.050000,0.050000},{0.943750,0.556250,0.025000,0.025000},{0.943750,0.556250,0.050000,0.050000},{0.956250,0.556250,0.025000,0.025000},{0.956250,0.556250,0.050000,0.050000},{0.968750,0.556250,0.025000,0.025000},{0.968750,0.556250,0.050000,0.050000},{0.981250,0.556250,0.025000,0.025000},{0.981250,0.556250,0.050000,0.050000},{0.993750,0.556250,0.025000,0.025000},{0.993750,0.556250,0.050000,0.050000},{0.006250,0.568750,0.025000,0.025000},{0.006250,0.568750,0.050000,0.050000},{0.018750,0.568750,0.025000,0.025000},{0.018750,0.568750,0.050000,0.050000},{0.031250,0.568750,0.025000,0.025000},{0.031250,0.568750,0.050000,0.050000},{0.043750,0.568750,0.025000,0.025000},{0.043750,0.568750,0.050000,0.050000},{0.056250,0.568750,0.025000,0.025000},{0.056250,0.568750,0.050000,0.050000},{0.068750,0.568750,0.025000,0.025000},{0.068750,0.568750,0.050000,0.050000},{0.081250,0.568750,0.025000,0.025000},{0.081250,0.568750,0.050000,0.050000},{0.093750,0.568750,0.025000,0.025000},{0.093750,0.568750,0.050000,0.050000},{0.106250,0.568750,0.025000,0.025000},{0.106250,0.568750,0.050000,0.050000},{0.118750,0.568750,0.025000,0.025000},{0.118750,0.568750,0.050000,0.050000},{0.131250,0.568750,0.025000,0.025000},{0.131250,0.568750,0.050000,0.050000},{0.143750,0.568750,0.025000,0.025000},{0.143750,0.568750,0.050000,0.050000},{0.156250,0.568750,0.025000,0.025000},{0.156250,0.568750,0.050000,0.050000},{0.168750,0.568750,0.025000,0.025000},{0.168750,0.568750,0.050000,0.050000},{0.181250,0.568750,0.025000,0.025000},{0.181250,0.568750,0.050000,0.050000},{0.193750,0.568750,0.025000,0.025000},{0.193750,0.568750,0.050000,0.050000},{0.206250,0.568750,0.025000,0.025000},{0.206250,0.568750,0.050000,0.050000},{0.218750,0.568750,0.025000,0.025000},{0.218750,0.568750,0.050000,0.050000},{0.231250,0.568750,0.025000,0.025000},{0.231250,0.568750,0.050000,0.050000},{0.243750,0.568750,0.025000,0.025000},{0.243750,0.568750,0.050000,0.050000},{0.256250,0.568750,0.025000,0.025000},{0.256250,0.568750,0.050000,0.050000},{0.268750,0.568750,0.025000,0.025000},{0.268750,0.568750,0.050000,0.050000},{0.281250,0.568750,0.025000,0.025000},{0.281250,0.568750,0.050000,0.050000},{0.293750,0.568750,0.025000,0.025000},{0.293750,0.568750,0.050000,0.050000},{0.306250,0.568750,0.025000,0.025000},{0.306250,0.568750,0.050000,0.050000},{0.318750,0.568750,0.025000,0.025000},{0.318750,0.568750,0.050000,0.050000},{0.331250,0.568750,0.025000,0.025000},{0.331250,0.568750,0.050000,0.050000},{0.343750,0.568750,0.025000,0.025000},{0.343750,0.568750,0.050000,0.050000},{0.356250,0.568750,0.025000,0.025000},{0.356250,0.568750,0.050000,0.050000},{0.368750,0.568750,0.025000,0.025000},{0.368750,0.568750,0.050000,0.050000},{0.381250,0.568750,0.025000,0.025000},{0.381250,0.568750,0.050000,0.050000},{0.393750,0.568750,0.025000,0.025000},{0.393750,0.568750,0.050000,0.050000},{0.406250,0.568750,0.025000,0.025000},{0.406250,0.568750,0.050000,0.050000},{0.418750,0.568750,0.025000,0.025000},{0.418750,0.568750,0.050000,0.050000},{0.431250,0.568750,0.025000,0.025000},{0.431250,0.568750,0.050000,0.050000},{0.443750,0.568750,0.025000,0.025000},{0.443750,0.568750,0.050000,0.050000},{0.456250,0.568750,0.025000,0.025000},{0.456250,0.568750,0.050000,0.050000},{0.468750,0.568750,0.025000,0.025000},{0.468750,0.568750,0.050000,0.050000},{0.481250,0.568750,0.025000,0.025000},{0.481250,0.568750,0.050000,0.050000},{0.493750,0.568750,0.025000,0.025000},{0.493750,0.568750,0.050000,0.050000},{0.506250,0.568750,0.025000,0.025000},{0.506250,0.568750,0.050000,0.050000},{0.518750,0.568750,0.025000,0.025000},{0.518750,0.568750,0.050000,0.050000},{0.531250,0.568750,0.025000,0.025000},{0.531250,0.568750,0.050000,0.050000},{0.543750,0.568750,0.025000,0.025000},{0.543750,0.568750,0.050000,0.050000},{0.556250,0.568750,0.025000,0.025000},{0.556250,0.568750,0.050000,0.050000},{0.568750,0.568750,0.025000,0.025000},{0.568750,0.568750,0.050000,0.050000},{0.581250,0.568750,0.025000,0.025000},{0.581250,0.568750,0.050000,0.050000},{0.593750,0.568750,0.025000,0.025000},{0.593750,0.568750,0.050000,0.050000},{0.606250,0.568750,0.025000,0.025000},{0.606250,0.568750,0.050000,0.050000},{0.618750,0.568750,0.025000,0.025000},{0.618750,0.568750,0.050000,0.050000},{0.631250,0.568750,0.025000,0.025000},{0.631250,0.568750,0.050000,0.050000},{0.643750,0.568750,0.025000,0.025000},{0.643750,0.568750,0.050000,0.050000},{0.656250,0.568750,0.025000,0.025000},{0.656250,0.568750,0.050000,0.050000},{0.668750,0.568750,0.025000,0.025000},{0.668750,0.568750,0.050000,0.050000},{0.681250,0.568750,0.025000,0.025000},{0.681250,0.568750,0.050000,0.050000},{0.693750,0.568750,0.025000,0.025000},{0.693750,0.568750,0.050000,0.050000},{0.706250,0.568750,0.025000,0.025000},{0.706250,0.568750,0.050000,0.050000},{0.718750,0.568750,0.025000,0.025000},{0.718750,0.568750,0.050000,0.050000},{0.731250,0.568750,0.025000,0.025000},{0.731250,0.568750,0.050000,0.050000},{0.743750,0.568750,0.025000,0.025000},{0.743750,0.568750,0.050000,0.050000},{0.756250,0.568750,0.025000,0.025000},{0.756250,0.568750,0.050000,0.050000},{0.768750,0.568750,0.025000,0.025000},{0.768750,0.568750,0.050000,0.050000},{0.781250,0.568750,0.025000,0.025000},{0.781250,0.568750,0.050000,0.050000},{0.793750,0.568750,0.025000,0.025000},{0.793750,0.568750,0.050000,0.050000},{0.806250,0.568750,0.025000,0.025000},{0.806250,0.568750,0.050000,0.050000},{0.818750,0.568750,0.025000,0.025000},{0.818750,0.568750,0.050000,0.050000},{0.831250,0.568750,0.025000,0.025000},{0.831250,0.568750,0.050000,0.050000},{0.843750,0.568750,0.025000,0.025000},{0.843750,0.568750,0.050000,0.050000},{0.856250,0.568750,0.025000,0.025000},{0.856250,0.568750,0.050000,0.050000},{0.868750,0.568750,0.025000,0.025000},{0.868750,0.568750,0.050000,0.050000},{0.881250,0.568750,0.025000,0.025000},{0.881250,0.568750,0.050000,0.050000},{0.893750,0.568750,0.025000,0.025000},{0.893750,0.568750,0.050000,0.050000},{0.906250,0.568750,0.025000,0.025000},{0.906250,0.568750,0.050000,0.050000},{0.918750,0.568750,0.025000,0.025000},{0.918750,0.568750,0.050000,0.050000},{0.931250,0.568750,0.025000,0.025000},{0.931250,0.568750,0.050000,0.050000},{0.943750,0.568750,0.025000,0.025000},{0.943750,0.568750,0.050000,0.050000},{0.956250,0.568750,0.025000,0.025000},{0.956250,0.568750,0.050000,0.050000},{0.968750,0.568750,0.025000,0.025000},{0.968750,0.568750,0.050000,0.050000},{0.981250,0.568750,0.025000,0.025000},{0.981250,0.568750,0.050000,0.050000},{0.993750,0.568750,0.025000,0.025000},{0.993750,0.568750,0.050000,0.050000},{0.006250,0.581250,0.025000,0.025000},{0.006250,0.581250,0.050000,0.050000},{0.018750,0.581250,0.025000,0.025000},{0.018750,0.581250,0.050000,0.050000},{0.031250,0.581250,0.025000,0.025000},{0.031250,0.581250,0.050000,0.050000},{0.043750,0.581250,0.025000,0.025000},{0.043750,0.581250,0.050000,0.050000},{0.056250,0.581250,0.025000,0.025000},{0.056250,0.581250,0.050000,0.050000},{0.068750,0.581250,0.025000,0.025000},{0.068750,0.581250,0.050000,0.050000},{0.081250,0.581250,0.025000,0.025000},{0.081250,0.581250,0.050000,0.050000},{0.093750,0.581250,0.025000,0.025000},{0.093750,0.581250,0.050000,0.050000},{0.106250,0.581250,0.025000,0.025000},{0.106250,0.581250,0.050000,0.050000},{0.118750,0.581250,0.025000,0.025000},{0.118750,0.581250,0.050000,0.050000},{0.131250,0.581250,0.025000,0.025000},{0.131250,0.581250,0.050000,0.050000},{0.143750,0.581250,0.025000,0.025000},{0.143750,0.581250,0.050000,0.050000},{0.156250,0.581250,0.025000,0.025000},{0.156250,0.581250,0.050000,0.050000},{0.168750,0.581250,0.025000,0.025000},{0.168750,0.581250,0.050000,0.050000},{0.181250,0.581250,0.025000,0.025000},{0.181250,0.581250,0.050000,0.050000},{0.193750,0.581250,0.025000,0.025000},{0.193750,0.581250,0.050000,0.050000},{0.206250,0.581250,0.025000,0.025000},{0.206250,0.581250,0.050000,0.050000},{0.218750,0.581250,0.025000,0.025000},{0.218750,0.581250,0.050000,0.050000},{0.231250,0.581250,0.025000,0.025000},{0.231250,0.581250,0.050000,0.050000},{0.243750,0.581250,0.025000,0.025000},{0.243750,0.581250,0.050000,0.050000},{0.256250,0.581250,0.025000,0.025000},{0.256250,0.581250,0.050000,0.050000},{0.268750,0.581250,0.025000,0.025000},{0.268750,0.581250,0.050000,0.050000},{0.281250,0.581250,0.025000,0.025000},{0.281250,0.581250,0.050000,0.050000},{0.293750,0.581250,0.025000,0.025000},{0.293750,0.581250,0.050000,0.050000},{0.306250,0.581250,0.025000,0.025000},{0.306250,0.581250,0.050000,0.050000},{0.318750,0.581250,0.025000,0.025000},{0.318750,0.581250,0.050000,0.050000},{0.331250,0.581250,0.025000,0.025000},{0.331250,0.581250,0.050000,0.050000},{0.343750,0.581250,0.025000,0.025000},{0.343750,0.581250,0.050000,0.050000},{0.356250,0.581250,0.025000,0.025000},{0.356250,0.581250,0.050000,0.050000},{0.368750,0.581250,0.025000,0.025000},{0.368750,0.581250,0.050000,0.050000},{0.381250,0.581250,0.025000,0.025000},{0.381250,0.581250,0.050000,0.050000},{0.393750,0.581250,0.025000,0.025000},{0.393750,0.581250,0.050000,0.050000},{0.406250,0.581250,0.025000,0.025000},{0.406250,0.581250,0.050000,0.050000},{0.418750,0.581250,0.025000,0.025000},{0.418750,0.581250,0.050000,0.050000},{0.431250,0.581250,0.025000,0.025000},{0.431250,0.581250,0.050000,0.050000},{0.443750,0.581250,0.025000,0.025000},{0.443750,0.581250,0.050000,0.050000},{0.456250,0.581250,0.025000,0.025000},{0.456250,0.581250,0.050000,0.050000},{0.468750,0.581250,0.025000,0.025000},{0.468750,0.581250,0.050000,0.050000},{0.481250,0.581250,0.025000,0.025000},{0.481250,0.581250,0.050000,0.050000},{0.493750,0.581250,0.025000,0.025000},{0.493750,0.581250,0.050000,0.050000},{0.506250,0.581250,0.025000,0.025000},{0.506250,0.581250,0.050000,0.050000},{0.518750,0.581250,0.025000,0.025000},{0.518750,0.581250,0.050000,0.050000},{0.531250,0.581250,0.025000,0.025000},{0.531250,0.581250,0.050000,0.050000},{0.543750,0.581250,0.025000,0.025000},{0.543750,0.581250,0.050000,0.050000},{0.556250,0.581250,0.025000,0.025000},{0.556250,0.581250,0.050000,0.050000},{0.568750,0.581250,0.025000,0.025000},{0.568750,0.581250,0.050000,0.050000},{0.581250,0.581250,0.025000,0.025000},{0.581250,0.581250,0.050000,0.050000},{0.593750,0.581250,0.025000,0.025000},{0.593750,0.581250,0.050000,0.050000},{0.606250,0.581250,0.025000,0.025000},{0.606250,0.581250,0.050000,0.050000},{0.618750,0.581250,0.025000,0.025000},{0.618750,0.581250,0.050000,0.050000},{0.631250,0.581250,0.025000,0.025000},{0.631250,0.581250,0.050000,0.050000},{0.643750,0.581250,0.025000,0.025000},{0.643750,0.581250,0.050000,0.050000},{0.656250,0.581250,0.025000,0.025000},{0.656250,0.581250,0.050000,0.050000},{0.668750,0.581250,0.025000,0.025000},{0.668750,0.581250,0.050000,0.050000},{0.681250,0.581250,0.025000,0.025000},{0.681250,0.581250,0.050000,0.050000},{0.693750,0.581250,0.025000,0.025000},{0.693750,0.581250,0.050000,0.050000},{0.706250,0.581250,0.025000,0.025000},{0.706250,0.581250,0.050000,0.050000},{0.718750,0.581250,0.025000,0.025000},{0.718750,0.581250,0.050000,0.050000},{0.731250,0.581250,0.025000,0.025000},{0.731250,0.581250,0.050000,0.050000},{0.743750,0.581250,0.025000,0.025000},{0.743750,0.581250,0.050000,0.050000},{0.756250,0.581250,0.025000,0.025000},{0.756250,0.581250,0.050000,0.050000},{0.768750,0.581250,0.025000,0.025000},{0.768750,0.581250,0.050000,0.050000},{0.781250,0.581250,0.025000,0.025000},{0.781250,0.581250,0.050000,0.050000},{0.793750,0.581250,0.025000,0.025000},{0.793750,0.581250,0.050000,0.050000},{0.806250,0.581250,0.025000,0.025000},{0.806250,0.581250,0.050000,0.050000},{0.818750,0.581250,0.025000,0.025000},{0.818750,0.581250,0.050000,0.050000},{0.831250,0.581250,0.025000,0.025000},{0.831250,0.581250,0.050000,0.050000},{0.843750,0.581250,0.025000,0.025000},{0.843750,0.581250,0.050000,0.050000},{0.856250,0.581250,0.025000,0.025000},{0.856250,0.581250,0.050000,0.050000},{0.868750,0.581250,0.025000,0.025000},{0.868750,0.581250,0.050000,0.050000},{0.881250,0.581250,0.025000,0.025000},{0.881250,0.581250,0.050000,0.050000},{0.893750,0.581250,0.025000,0.025000},{0.893750,0.581250,0.050000,0.050000},{0.906250,0.581250,0.025000,0.025000},{0.906250,0.581250,0.050000,0.050000},{0.918750,0.581250,0.025000,0.025000},{0.918750,0.581250,0.050000,0.050000},{0.931250,0.581250,0.025000,0.025000},{0.931250,0.581250,0.050000,0.050000},{0.943750,0.581250,0.025000,0.025000},{0.943750,0.581250,0.050000,0.050000},{0.956250,0.581250,0.025000,0.025000},{0.956250,0.581250,0.050000,0.050000},{0.968750,0.581250,0.025000,0.025000},{0.968750,0.581250,0.050000,0.050000},{0.981250,0.581250,0.025000,0.025000},{0.981250,0.581250,0.050000,0.050000},{0.993750,0.581250,0.025000,0.025000},{0.993750,0.581250,0.050000,0.050000},{0.006250,0.593750,0.025000,0.025000},{0.006250,0.593750,0.050000,0.050000},{0.018750,0.593750,0.025000,0.025000},{0.018750,0.593750,0.050000,0.050000},{0.031250,0.593750,0.025000,0.025000},{0.031250,0.593750,0.050000,0.050000},{0.043750,0.593750,0.025000,0.025000},{0.043750,0.593750,0.050000,0.050000},{0.056250,0.593750,0.025000,0.025000},{0.056250,0.593750,0.050000,0.050000},{0.068750,0.593750,0.025000,0.025000},{0.068750,0.593750,0.050000,0.050000},{0.081250,0.593750,0.025000,0.025000},{0.081250,0.593750,0.050000,0.050000},{0.093750,0.593750,0.025000,0.025000},{0.093750,0.593750,0.050000,0.050000},{0.106250,0.593750,0.025000,0.025000},{0.106250,0.593750,0.050000,0.050000},{0.118750,0.593750,0.025000,0.025000},{0.118750,0.593750,0.050000,0.050000},{0.131250,0.593750,0.025000,0.025000},{0.131250,0.593750,0.050000,0.050000},{0.143750,0.593750,0.025000,0.025000},{0.143750,0.593750,0.050000,0.050000},{0.156250,0.593750,0.025000,0.025000},{0.156250,0.593750,0.050000,0.050000},{0.168750,0.593750,0.025000,0.025000},{0.168750,0.593750,0.050000,0.050000},{0.181250,0.593750,0.025000,0.025000},{0.181250,0.593750,0.050000,0.050000},{0.193750,0.593750,0.025000,0.025000},{0.193750,0.593750,0.050000,0.050000},{0.206250,0.593750,0.025000,0.025000},{0.206250,0.593750,0.050000,0.050000},{0.218750,0.593750,0.025000,0.025000},{0.218750,0.593750,0.050000,0.050000},{0.231250,0.593750,0.025000,0.025000},{0.231250,0.593750,0.050000,0.050000},{0.243750,0.593750,0.025000,0.025000},{0.243750,0.593750,0.050000,0.050000},{0.256250,0.593750,0.025000,0.025000},{0.256250,0.593750,0.050000,0.050000},{0.268750,0.593750,0.025000,0.025000},{0.268750,0.593750,0.050000,0.050000},{0.281250,0.593750,0.025000,0.025000},{0.281250,0.593750,0.050000,0.050000},{0.293750,0.593750,0.025000,0.025000},{0.293750,0.593750,0.050000,0.050000},{0.306250,0.593750,0.025000,0.025000},{0.306250,0.593750,0.050000,0.050000},{0.318750,0.593750,0.025000,0.025000},{0.318750,0.593750,0.050000,0.050000},{0.331250,0.593750,0.025000,0.025000},{0.331250,0.593750,0.050000,0.050000},{0.343750,0.593750,0.025000,0.025000},{0.343750,0.593750,0.050000,0.050000},{0.356250,0.593750,0.025000,0.025000},{0.356250,0.593750,0.050000,0.050000},{0.368750,0.593750,0.025000,0.025000},{0.368750,0.593750,0.050000,0.050000},{0.381250,0.593750,0.025000,0.025000},{0.381250,0.593750,0.050000,0.050000},{0.393750,0.593750,0.025000,0.025000},{0.393750,0.593750,0.050000,0.050000},{0.406250,0.593750,0.025000,0.025000},{0.406250,0.593750,0.050000,0.050000},{0.418750,0.593750,0.025000,0.025000},{0.418750,0.593750,0.050000,0.050000},{0.431250,0.593750,0.025000,0.025000},{0.431250,0.593750,0.050000,0.050000},{0.443750,0.593750,0.025000,0.025000},{0.443750,0.593750,0.050000,0.050000},{0.456250,0.593750,0.025000,0.025000},{0.456250,0.593750,0.050000,0.050000},{0.468750,0.593750,0.025000,0.025000},{0.468750,0.593750,0.050000,0.050000},{0.481250,0.593750,0.025000,0.025000},{0.481250,0.593750,0.050000,0.050000},{0.493750,0.593750,0.025000,0.025000},{0.493750,0.593750,0.050000,0.050000},{0.506250,0.593750,0.025000,0.025000},{0.506250,0.593750,0.050000,0.050000},{0.518750,0.593750,0.025000,0.025000},{0.518750,0.593750,0.050000,0.050000},{0.531250,0.593750,0.025000,0.025000},{0.531250,0.593750,0.050000,0.050000},{0.543750,0.593750,0.025000,0.025000},{0.543750,0.593750,0.050000,0.050000},{0.556250,0.593750,0.025000,0.025000},{0.556250,0.593750,0.050000,0.050000},{0.568750,0.593750,0.025000,0.025000},{0.568750,0.593750,0.050000,0.050000},{0.581250,0.593750,0.025000,0.025000},{0.581250,0.593750,0.050000,0.050000},{0.593750,0.593750,0.025000,0.025000},{0.593750,0.593750,0.050000,0.050000},{0.606250,0.593750,0.025000,0.025000},{0.606250,0.593750,0.050000,0.050000},{0.618750,0.593750,0.025000,0.025000},{0.618750,0.593750,0.050000,0.050000},{0.631250,0.593750,0.025000,0.025000},{0.631250,0.593750,0.050000,0.050000},{0.643750,0.593750,0.025000,0.025000},{0.643750,0.593750,0.050000,0.050000},{0.656250,0.593750,0.025000,0.025000},{0.656250,0.593750,0.050000,0.050000},{0.668750,0.593750,0.025000,0.025000},{0.668750,0.593750,0.050000,0.050000},{0.681250,0.593750,0.025000,0.025000},{0.681250,0.593750,0.050000,0.050000},{0.693750,0.593750,0.025000,0.025000},{0.693750,0.593750,0.050000,0.050000},{0.706250,0.593750,0.025000,0.025000},{0.706250,0.593750,0.050000,0.050000},{0.718750,0.593750,0.025000,0.025000},{0.718750,0.593750,0.050000,0.050000},{0.731250,0.593750,0.025000,0.025000},{0.731250,0.593750,0.050000,0.050000},{0.743750,0.593750,0.025000,0.025000},{0.743750,0.593750,0.050000,0.050000},{0.756250,0.593750,0.025000,0.025000},{0.756250,0.593750,0.050000,0.050000},{0.768750,0.593750,0.025000,0.025000},{0.768750,0.593750,0.050000,0.050000},{0.781250,0.593750,0.025000,0.025000},{0.781250,0.593750,0.050000,0.050000},{0.793750,0.593750,0.025000,0.025000},{0.793750,0.593750,0.050000,0.050000},{0.806250,0.593750,0.025000,0.025000},{0.806250,0.593750,0.050000,0.050000},{0.818750,0.593750,0.025000,0.025000},{0.818750,0.593750,0.050000,0.050000},{0.831250,0.593750,0.025000,0.025000},{0.831250,0.593750,0.050000,0.050000},{0.843750,0.593750,0.025000,0.025000},{0.843750,0.593750,0.050000,0.050000},{0.856250,0.593750,0.025000,0.025000},{0.856250,0.593750,0.050000,0.050000},{0.868750,0.593750,0.025000,0.025000},{0.868750,0.593750,0.050000,0.050000},{0.881250,0.593750,0.025000,0.025000},{0.881250,0.593750,0.050000,0.050000},{0.893750,0.593750,0.025000,0.025000},{0.893750,0.593750,0.050000,0.050000},{0.906250,0.593750,0.025000,0.025000},{0.906250,0.593750,0.050000,0.050000},{0.918750,0.593750,0.025000,0.025000},{0.918750,0.593750,0.050000,0.050000},{0.931250,0.593750,0.025000,0.025000},{0.931250,0.593750,0.050000,0.050000},{0.943750,0.593750,0.025000,0.025000},{0.943750,0.593750,0.050000,0.050000},{0.956250,0.593750,0.025000,0.025000},{0.956250,0.593750,0.050000,0.050000},{0.968750,0.593750,0.025000,0.025000},{0.968750,0.593750,0.050000,0.050000},{0.981250,0.593750,0.025000,0.025000},{0.981250,0.593750,0.050000,0.050000},{0.993750,0.593750,0.025000,0.025000},{0.993750,0.593750,0.050000,0.050000},{0.006250,0.606250,0.025000,0.025000},{0.006250,0.606250,0.050000,0.050000},{0.018750,0.606250,0.025000,0.025000},{0.018750,0.606250,0.050000,0.050000},{0.031250,0.606250,0.025000,0.025000},{0.031250,0.606250,0.050000,0.050000},{0.043750,0.606250,0.025000,0.025000},{0.043750,0.606250,0.050000,0.050000},{0.056250,0.606250,0.025000,0.025000},{0.056250,0.606250,0.050000,0.050000},{0.068750,0.606250,0.025000,0.025000},{0.068750,0.606250,0.050000,0.050000},{0.081250,0.606250,0.025000,0.025000},{0.081250,0.606250,0.050000,0.050000},{0.093750,0.606250,0.025000,0.025000},{0.093750,0.606250,0.050000,0.050000},{0.106250,0.606250,0.025000,0.025000},{0.106250,0.606250,0.050000,0.050000},{0.118750,0.606250,0.025000,0.025000},{0.118750,0.606250,0.050000,0.050000},{0.131250,0.606250,0.025000,0.025000},{0.131250,0.606250,0.050000,0.050000},{0.143750,0.606250,0.025000,0.025000},{0.143750,0.606250,0.050000,0.050000},{0.156250,0.606250,0.025000,0.025000},{0.156250,0.606250,0.050000,0.050000},{0.168750,0.606250,0.025000,0.025000},{0.168750,0.606250,0.050000,0.050000},{0.181250,0.606250,0.025000,0.025000},{0.181250,0.606250,0.050000,0.050000},{0.193750,0.606250,0.025000,0.025000},{0.193750,0.606250,0.050000,0.050000},{0.206250,0.606250,0.025000,0.025000},{0.206250,0.606250,0.050000,0.050000},{0.218750,0.606250,0.025000,0.025000},{0.218750,0.606250,0.050000,0.050000},{0.231250,0.606250,0.025000,0.025000},{0.231250,0.606250,0.050000,0.050000},{0.243750,0.606250,0.025000,0.025000},{0.243750,0.606250,0.050000,0.050000},{0.256250,0.606250,0.025000,0.025000},{0.256250,0.606250,0.050000,0.050000},{0.268750,0.606250,0.025000,0.025000},{0.268750,0.606250,0.050000,0.050000},{0.281250,0.606250,0.025000,0.025000},{0.281250,0.606250,0.050000,0.050000},{0.293750,0.606250,0.025000,0.025000},{0.293750,0.606250,0.050000,0.050000},{0.306250,0.606250,0.025000,0.025000},{0.306250,0.606250,0.050000,0.050000},{0.318750,0.606250,0.025000,0.025000},{0.318750,0.606250,0.050000,0.050000},{0.331250,0.606250,0.025000,0.025000},{0.331250,0.606250,0.050000,0.050000},{0.343750,0.606250,0.025000,0.025000},{0.343750,0.606250,0.050000,0.050000},{0.356250,0.606250,0.025000,0.025000},{0.356250,0.606250,0.050000,0.050000},{0.368750,0.606250,0.025000,0.025000},{0.368750,0.606250,0.050000,0.050000},{0.381250,0.606250,0.025000,0.025000},{0.381250,0.606250,0.050000,0.050000},{0.393750,0.606250,0.025000,0.025000},{0.393750,0.606250,0.050000,0.050000},{0.406250,0.606250,0.025000,0.025000},{0.406250,0.606250,0.050000,0.050000},{0.418750,0.606250,0.025000,0.025000},{0.418750,0.606250,0.050000,0.050000},{0.431250,0.606250,0.025000,0.025000},{0.431250,0.606250,0.050000,0.050000},{0.443750,0.606250,0.025000,0.025000},{0.443750,0.606250,0.050000,0.050000},{0.456250,0.606250,0.025000,0.025000},{0.456250,0.606250,0.050000,0.050000},{0.468750,0.606250,0.025000,0.025000},{0.468750,0.606250,0.050000,0.050000},{0.481250,0.606250,0.025000,0.025000},{0.481250,0.606250,0.050000,0.050000},{0.493750,0.606250,0.025000,0.025000},{0.493750,0.606250,0.050000,0.050000},{0.506250,0.606250,0.025000,0.025000},{0.506250,0.606250,0.050000,0.050000},{0.518750,0.606250,0.025000,0.025000},{0.518750,0.606250,0.050000,0.050000},{0.531250,0.606250,0.025000,0.025000},{0.531250,0.606250,0.050000,0.050000},{0.543750,0.606250,0.025000,0.025000},{0.543750,0.606250,0.050000,0.050000},{0.556250,0.606250,0.025000,0.025000},{0.556250,0.606250,0.050000,0.050000},{0.568750,0.606250,0.025000,0.025000},{0.568750,0.606250,0.050000,0.050000},{0.581250,0.606250,0.025000,0.025000},{0.581250,0.606250,0.050000,0.050000},{0.593750,0.606250,0.025000,0.025000},{0.593750,0.606250,0.050000,0.050000},{0.606250,0.606250,0.025000,0.025000},{0.606250,0.606250,0.050000,0.050000},{0.618750,0.606250,0.025000,0.025000},{0.618750,0.606250,0.050000,0.050000},{0.631250,0.606250,0.025000,0.025000},{0.631250,0.606250,0.050000,0.050000},{0.643750,0.606250,0.025000,0.025000},{0.643750,0.606250,0.050000,0.050000},{0.656250,0.606250,0.025000,0.025000},{0.656250,0.606250,0.050000,0.050000},{0.668750,0.606250,0.025000,0.025000},{0.668750,0.606250,0.050000,0.050000},{0.681250,0.606250,0.025000,0.025000},{0.681250,0.606250,0.050000,0.050000},{0.693750,0.606250,0.025000,0.025000},{0.693750,0.606250,0.050000,0.050000},{0.706250,0.606250,0.025000,0.025000},{0.706250,0.606250,0.050000,0.050000},{0.718750,0.606250,0.025000,0.025000},{0.718750,0.606250,0.050000,0.050000},{0.731250,0.606250,0.025000,0.025000},{0.731250,0.606250,0.050000,0.050000},{0.743750,0.606250,0.025000,0.025000},{0.743750,0.606250,0.050000,0.050000},{0.756250,0.606250,0.025000,0.025000},{0.756250,0.606250,0.050000,0.050000},{0.768750,0.606250,0.025000,0.025000},{0.768750,0.606250,0.050000,0.050000},{0.781250,0.606250,0.025000,0.025000},{0.781250,0.606250,0.050000,0.050000},{0.793750,0.606250,0.025000,0.025000},{0.793750,0.606250,0.050000,0.050000},{0.806250,0.606250,0.025000,0.025000},{0.806250,0.606250,0.050000,0.050000},{0.818750,0.606250,0.025000,0.025000},{0.818750,0.606250,0.050000,0.050000},{0.831250,0.606250,0.025000,0.025000},{0.831250,0.606250,0.050000,0.050000},{0.843750,0.606250,0.025000,0.025000},{0.843750,0.606250,0.050000,0.050000},{0.856250,0.606250,0.025000,0.025000},{0.856250,0.606250,0.050000,0.050000},{0.868750,0.606250,0.025000,0.025000},{0.868750,0.606250,0.050000,0.050000},{0.881250,0.606250,0.025000,0.025000},{0.881250,0.606250,0.050000,0.050000},{0.893750,0.606250,0.025000,0.025000},{0.893750,0.606250,0.050000,0.050000},{0.906250,0.606250,0.025000,0.025000},{0.906250,0.606250,0.050000,0.050000},{0.918750,0.606250,0.025000,0.025000},{0.918750,0.606250,0.050000,0.050000},{0.931250,0.606250,0.025000,0.025000},{0.931250,0.606250,0.050000,0.050000},{0.943750,0.606250,0.025000,0.025000},{0.943750,0.606250,0.050000,0.050000},{0.956250,0.606250,0.025000,0.025000},{0.956250,0.606250,0.050000,0.050000},{0.968750,0.606250,0.025000,0.025000},{0.968750,0.606250,0.050000,0.050000},{0.981250,0.606250,0.025000,0.025000},{0.981250,0.606250,0.050000,0.050000},{0.993750,0.606250,0.025000,0.025000},{0.993750,0.606250,0.050000,0.050000},{0.006250,0.618750,0.025000,0.025000},{0.006250,0.618750,0.050000,0.050000},{0.018750,0.618750,0.025000,0.025000},{0.018750,0.618750,0.050000,0.050000},{0.031250,0.618750,0.025000,0.025000},{0.031250,0.618750,0.050000,0.050000},{0.043750,0.618750,0.025000,0.025000},{0.043750,0.618750,0.050000,0.050000},{0.056250,0.618750,0.025000,0.025000},{0.056250,0.618750,0.050000,0.050000},{0.068750,0.618750,0.025000,0.025000},{0.068750,0.618750,0.050000,0.050000},{0.081250,0.618750,0.025000,0.025000},{0.081250,0.618750,0.050000,0.050000},{0.093750,0.618750,0.025000,0.025000},{0.093750,0.618750,0.050000,0.050000},{0.106250,0.618750,0.025000,0.025000},{0.106250,0.618750,0.050000,0.050000},{0.118750,0.618750,0.025000,0.025000},{0.118750,0.618750,0.050000,0.050000},{0.131250,0.618750,0.025000,0.025000},{0.131250,0.618750,0.050000,0.050000},{0.143750,0.618750,0.025000,0.025000},{0.143750,0.618750,0.050000,0.050000},{0.156250,0.618750,0.025000,0.025000},{0.156250,0.618750,0.050000,0.050000},{0.168750,0.618750,0.025000,0.025000},{0.168750,0.618750,0.050000,0.050000},{0.181250,0.618750,0.025000,0.025000},{0.181250,0.618750,0.050000,0.050000},{0.193750,0.618750,0.025000,0.025000},{0.193750,0.618750,0.050000,0.050000},{0.206250,0.618750,0.025000,0.025000},{0.206250,0.618750,0.050000,0.050000},{0.218750,0.618750,0.025000,0.025000},{0.218750,0.618750,0.050000,0.050000},{0.231250,0.618750,0.025000,0.025000},{0.231250,0.618750,0.050000,0.050000},{0.243750,0.618750,0.025000,0.025000},{0.243750,0.618750,0.050000,0.050000},{0.256250,0.618750,0.025000,0.025000},{0.256250,0.618750,0.050000,0.050000},{0.268750,0.618750,0.025000,0.025000},{0.268750,0.618750,0.050000,0.050000},{0.281250,0.618750,0.025000,0.025000},{0.281250,0.618750,0.050000,0.050000},{0.293750,0.618750,0.025000,0.025000},{0.293750,0.618750,0.050000,0.050000},{0.306250,0.618750,0.025000,0.025000},{0.306250,0.618750,0.050000,0.050000},{0.318750,0.618750,0.025000,0.025000},{0.318750,0.618750,0.050000,0.050000},{0.331250,0.618750,0.025000,0.025000},{0.331250,0.618750,0.050000,0.050000},{0.343750,0.618750,0.025000,0.025000},{0.343750,0.618750,0.050000,0.050000},{0.356250,0.618750,0.025000,0.025000},{0.356250,0.618750,0.050000,0.050000},{0.368750,0.618750,0.025000,0.025000},{0.368750,0.618750,0.050000,0.050000},{0.381250,0.618750,0.025000,0.025000},{0.381250,0.618750,0.050000,0.050000},{0.393750,0.618750,0.025000,0.025000},{0.393750,0.618750,0.050000,0.050000},{0.406250,0.618750,0.025000,0.025000},{0.406250,0.618750,0.050000,0.050000},{0.418750,0.618750,0.025000,0.025000},{0.418750,0.618750,0.050000,0.050000},{0.431250,0.618750,0.025000,0.025000},{0.431250,0.618750,0.050000,0.050000},{0.443750,0.618750,0.025000,0.025000},{0.443750,0.618750,0.050000,0.050000},{0.456250,0.618750,0.025000,0.025000},{0.456250,0.618750,0.050000,0.050000},{0.468750,0.618750,0.025000,0.025000},{0.468750,0.618750,0.050000,0.050000},{0.481250,0.618750,0.025000,0.025000},{0.481250,0.618750,0.050000,0.050000},{0.493750,0.618750,0.025000,0.025000},{0.493750,0.618750,0.050000,0.050000},{0.506250,0.618750,0.025000,0.025000},{0.506250,0.618750,0.050000,0.050000},{0.518750,0.618750,0.025000,0.025000},{0.518750,0.618750,0.050000,0.050000},{0.531250,0.618750,0.025000,0.025000},{0.531250,0.618750,0.050000,0.050000},{0.543750,0.618750,0.025000,0.025000},{0.543750,0.618750,0.050000,0.050000},{0.556250,0.618750,0.025000,0.025000},{0.556250,0.618750,0.050000,0.050000},{0.568750,0.618750,0.025000,0.025000},{0.568750,0.618750,0.050000,0.050000},{0.581250,0.618750,0.025000,0.025000},{0.581250,0.618750,0.050000,0.050000},{0.593750,0.618750,0.025000,0.025000},{0.593750,0.618750,0.050000,0.050000},{0.606250,0.618750,0.025000,0.025000},{0.606250,0.618750,0.050000,0.050000},{0.618750,0.618750,0.025000,0.025000},{0.618750,0.618750,0.050000,0.050000},{0.631250,0.618750,0.025000,0.025000},{0.631250,0.618750,0.050000,0.050000},{0.643750,0.618750,0.025000,0.025000},{0.643750,0.618750,0.050000,0.050000},{0.656250,0.618750,0.025000,0.025000},{0.656250,0.618750,0.050000,0.050000},{0.668750,0.618750,0.025000,0.025000},{0.668750,0.618750,0.050000,0.050000},{0.681250,0.618750,0.025000,0.025000},{0.681250,0.618750,0.050000,0.050000},{0.693750,0.618750,0.025000,0.025000},{0.693750,0.618750,0.050000,0.050000},{0.706250,0.618750,0.025000,0.025000},{0.706250,0.618750,0.050000,0.050000},{0.718750,0.618750,0.025000,0.025000},{0.718750,0.618750,0.050000,0.050000},{0.731250,0.618750,0.025000,0.025000},{0.731250,0.618750,0.050000,0.050000},{0.743750,0.618750,0.025000,0.025000},{0.743750,0.618750,0.050000,0.050000},{0.756250,0.618750,0.025000,0.025000},{0.756250,0.618750,0.050000,0.050000},{0.768750,0.618750,0.025000,0.025000},{0.768750,0.618750,0.050000,0.050000},{0.781250,0.618750,0.025000,0.025000},{0.781250,0.618750,0.050000,0.050000},{0.793750,0.618750,0.025000,0.025000},{0.793750,0.618750,0.050000,0.050000},{0.806250,0.618750,0.025000,0.025000},{0.806250,0.618750,0.050000,0.050000},{0.818750,0.618750,0.025000,0.025000},{0.818750,0.618750,0.050000,0.050000},{0.831250,0.618750,0.025000,0.025000},{0.831250,0.618750,0.050000,0.050000},{0.843750,0.618750,0.025000,0.025000},{0.843750,0.618750,0.050000,0.050000},{0.856250,0.618750,0.025000,0.025000},{0.856250,0.618750,0.050000,0.050000},{0.868750,0.618750,0.025000,0.025000},{0.868750,0.618750,0.050000,0.050000},{0.881250,0.618750,0.025000,0.025000},{0.881250,0.618750,0.050000,0.050000},{0.893750,0.618750,0.025000,0.025000},{0.893750,0.618750,0.050000,0.050000},{0.906250,0.618750,0.025000,0.025000},{0.906250,0.618750,0.050000,0.050000},{0.918750,0.618750,0.025000,0.025000},{0.918750,0.618750,0.050000,0.050000},{0.931250,0.618750,0.025000,0.025000},{0.931250,0.618750,0.050000,0.050000},{0.943750,0.618750,0.025000,0.025000},{0.943750,0.618750,0.050000,0.050000},{0.956250,0.618750,0.025000,0.025000},{0.956250,0.618750,0.050000,0.050000},{0.968750,0.618750,0.025000,0.025000},{0.968750,0.618750,0.050000,0.050000},{0.981250,0.618750,0.025000,0.025000},{0.981250,0.618750,0.050000,0.050000},{0.993750,0.618750,0.025000,0.025000},{0.993750,0.618750,0.050000,0.050000},{0.006250,0.631250,0.025000,0.025000},{0.006250,0.631250,0.050000,0.050000},{0.018750,0.631250,0.025000,0.025000},{0.018750,0.631250,0.050000,0.050000},{0.031250,0.631250,0.025000,0.025000},{0.031250,0.631250,0.050000,0.050000},{0.043750,0.631250,0.025000,0.025000},{0.043750,0.631250,0.050000,0.050000},{0.056250,0.631250,0.025000,0.025000},{0.056250,0.631250,0.050000,0.050000},{0.068750,0.631250,0.025000,0.025000},{0.068750,0.631250,0.050000,0.050000},{0.081250,0.631250,0.025000,0.025000},{0.081250,0.631250,0.050000,0.050000},{0.093750,0.631250,0.025000,0.025000},{0.093750,0.631250,0.050000,0.050000},{0.106250,0.631250,0.025000,0.025000},{0.106250,0.631250,0.050000,0.050000},{0.118750,0.631250,0.025000,0.025000},{0.118750,0.631250,0.050000,0.050000},{0.131250,0.631250,0.025000,0.025000},{0.131250,0.631250,0.050000,0.050000},{0.143750,0.631250,0.025000,0.025000},{0.143750,0.631250,0.050000,0.050000},{0.156250,0.631250,0.025000,0.025000},{0.156250,0.631250,0.050000,0.050000},{0.168750,0.631250,0.025000,0.025000},{0.168750,0.631250,0.050000,0.050000},{0.181250,0.631250,0.025000,0.025000},{0.181250,0.631250,0.050000,0.050000},{0.193750,0.631250,0.025000,0.025000},{0.193750,0.631250,0.050000,0.050000},{0.206250,0.631250,0.025000,0.025000},{0.206250,0.631250,0.050000,0.050000},{0.218750,0.631250,0.025000,0.025000},{0.218750,0.631250,0.050000,0.050000},{0.231250,0.631250,0.025000,0.025000},{0.231250,0.631250,0.050000,0.050000},{0.243750,0.631250,0.025000,0.025000},{0.243750,0.631250,0.050000,0.050000},{0.256250,0.631250,0.025000,0.025000},{0.256250,0.631250,0.050000,0.050000},{0.268750,0.631250,0.025000,0.025000},{0.268750,0.631250,0.050000,0.050000},{0.281250,0.631250,0.025000,0.025000},{0.281250,0.631250,0.050000,0.050000},{0.293750,0.631250,0.025000,0.025000},{0.293750,0.631250,0.050000,0.050000},{0.306250,0.631250,0.025000,0.025000},{0.306250,0.631250,0.050000,0.050000},{0.318750,0.631250,0.025000,0.025000},{0.318750,0.631250,0.050000,0.050000},{0.331250,0.631250,0.025000,0.025000},{0.331250,0.631250,0.050000,0.050000},{0.343750,0.631250,0.025000,0.025000},{0.343750,0.631250,0.050000,0.050000},{0.356250,0.631250,0.025000,0.025000},{0.356250,0.631250,0.050000,0.050000},{0.368750,0.631250,0.025000,0.025000},{0.368750,0.631250,0.050000,0.050000},{0.381250,0.631250,0.025000,0.025000},{0.381250,0.631250,0.050000,0.050000},{0.393750,0.631250,0.025000,0.025000},{0.393750,0.631250,0.050000,0.050000},{0.406250,0.631250,0.025000,0.025000},{0.406250,0.631250,0.050000,0.050000},{0.418750,0.631250,0.025000,0.025000},{0.418750,0.631250,0.050000,0.050000},{0.431250,0.631250,0.025000,0.025000},{0.431250,0.631250,0.050000,0.050000},{0.443750,0.631250,0.025000,0.025000},{0.443750,0.631250,0.050000,0.050000},{0.456250,0.631250,0.025000,0.025000},{0.456250,0.631250,0.050000,0.050000},{0.468750,0.631250,0.025000,0.025000},{0.468750,0.631250,0.050000,0.050000},{0.481250,0.631250,0.025000,0.025000},{0.481250,0.631250,0.050000,0.050000},{0.493750,0.631250,0.025000,0.025000},{0.493750,0.631250,0.050000,0.050000},{0.506250,0.631250,0.025000,0.025000},{0.506250,0.631250,0.050000,0.050000},{0.518750,0.631250,0.025000,0.025000},{0.518750,0.631250,0.050000,0.050000},{0.531250,0.631250,0.025000,0.025000},{0.531250,0.631250,0.050000,0.050000},{0.543750,0.631250,0.025000,0.025000},{0.543750,0.631250,0.050000,0.050000},{0.556250,0.631250,0.025000,0.025000},{0.556250,0.631250,0.050000,0.050000},{0.568750,0.631250,0.025000,0.025000},{0.568750,0.631250,0.050000,0.050000},{0.581250,0.631250,0.025000,0.025000},{0.581250,0.631250,0.050000,0.050000},{0.593750,0.631250,0.025000,0.025000},{0.593750,0.631250,0.050000,0.050000},{0.606250,0.631250,0.025000,0.025000},{0.606250,0.631250,0.050000,0.050000},{0.618750,0.631250,0.025000,0.025000},{0.618750,0.631250,0.050000,0.050000},{0.631250,0.631250,0.025000,0.025000},{0.631250,0.631250,0.050000,0.050000},{0.643750,0.631250,0.025000,0.025000},{0.643750,0.631250,0.050000,0.050000},{0.656250,0.631250,0.025000,0.025000},{0.656250,0.631250,0.050000,0.050000},{0.668750,0.631250,0.025000,0.025000},{0.668750,0.631250,0.050000,0.050000},{0.681250,0.631250,0.025000,0.025000},{0.681250,0.631250,0.050000,0.050000},{0.693750,0.631250,0.025000,0.025000},{0.693750,0.631250,0.050000,0.050000},{0.706250,0.631250,0.025000,0.025000},{0.706250,0.631250,0.050000,0.050000},{0.718750,0.631250,0.025000,0.025000},{0.718750,0.631250,0.050000,0.050000},{0.731250,0.631250,0.025000,0.025000},{0.731250,0.631250,0.050000,0.050000},{0.743750,0.631250,0.025000,0.025000},{0.743750,0.631250,0.050000,0.050000},{0.756250,0.631250,0.025000,0.025000},{0.756250,0.631250,0.050000,0.050000},{0.768750,0.631250,0.025000,0.025000},{0.768750,0.631250,0.050000,0.050000},{0.781250,0.631250,0.025000,0.025000},{0.781250,0.631250,0.050000,0.050000},{0.793750,0.631250,0.025000,0.025000},{0.793750,0.631250,0.050000,0.050000},{0.806250,0.631250,0.025000,0.025000},{0.806250,0.631250,0.050000,0.050000},{0.818750,0.631250,0.025000,0.025000},{0.818750,0.631250,0.050000,0.050000},{0.831250,0.631250,0.025000,0.025000},{0.831250,0.631250,0.050000,0.050000},{0.843750,0.631250,0.025000,0.025000},{0.843750,0.631250,0.050000,0.050000},{0.856250,0.631250,0.025000,0.025000},{0.856250,0.631250,0.050000,0.050000},{0.868750,0.631250,0.025000,0.025000},{0.868750,0.631250,0.050000,0.050000},{0.881250,0.631250,0.025000,0.025000},{0.881250,0.631250,0.050000,0.050000},{0.893750,0.631250,0.025000,0.025000},{0.893750,0.631250,0.050000,0.050000},{0.906250,0.631250,0.025000,0.025000},{0.906250,0.631250,0.050000,0.050000},{0.918750,0.631250,0.025000,0.025000},{0.918750,0.631250,0.050000,0.050000},{0.931250,0.631250,0.025000,0.025000},{0.931250,0.631250,0.050000,0.050000},{0.943750,0.631250,0.025000,0.025000},{0.943750,0.631250,0.050000,0.050000},{0.956250,0.631250,0.025000,0.025000},{0.956250,0.631250,0.050000,0.050000},{0.968750,0.631250,0.025000,0.025000},{0.968750,0.631250,0.050000,0.050000},{0.981250,0.631250,0.025000,0.025000},{0.981250,0.631250,0.050000,0.050000},{0.993750,0.631250,0.025000,0.025000},{0.993750,0.631250,0.050000,0.050000},{0.006250,0.643750,0.025000,0.025000},{0.006250,0.643750,0.050000,0.050000},{0.018750,0.643750,0.025000,0.025000},{0.018750,0.643750,0.050000,0.050000},{0.031250,0.643750,0.025000,0.025000},{0.031250,0.643750,0.050000,0.050000},{0.043750,0.643750,0.025000,0.025000},{0.043750,0.643750,0.050000,0.050000},{0.056250,0.643750,0.025000,0.025000},{0.056250,0.643750,0.050000,0.050000},{0.068750,0.643750,0.025000,0.025000},{0.068750,0.643750,0.050000,0.050000},{0.081250,0.643750,0.025000,0.025000},{0.081250,0.643750,0.050000,0.050000},{0.093750,0.643750,0.025000,0.025000},{0.093750,0.643750,0.050000,0.050000},{0.106250,0.643750,0.025000,0.025000},{0.106250,0.643750,0.050000,0.050000},{0.118750,0.643750,0.025000,0.025000},{0.118750,0.643750,0.050000,0.050000},{0.131250,0.643750,0.025000,0.025000},{0.131250,0.643750,0.050000,0.050000},{0.143750,0.643750,0.025000,0.025000},{0.143750,0.643750,0.050000,0.050000},{0.156250,0.643750,0.025000,0.025000},{0.156250,0.643750,0.050000,0.050000},{0.168750,0.643750,0.025000,0.025000},{0.168750,0.643750,0.050000,0.050000},{0.181250,0.643750,0.025000,0.025000},{0.181250,0.643750,0.050000,0.050000},{0.193750,0.643750,0.025000,0.025000},{0.193750,0.643750,0.050000,0.050000},{0.206250,0.643750,0.025000,0.025000},{0.206250,0.643750,0.050000,0.050000},{0.218750,0.643750,0.025000,0.025000},{0.218750,0.643750,0.050000,0.050000},{0.231250,0.643750,0.025000,0.025000},{0.231250,0.643750,0.050000,0.050000},{0.243750,0.643750,0.025000,0.025000},{0.243750,0.643750,0.050000,0.050000},{0.256250,0.643750,0.025000,0.025000},{0.256250,0.643750,0.050000,0.050000},{0.268750,0.643750,0.025000,0.025000},{0.268750,0.643750,0.050000,0.050000},{0.281250,0.643750,0.025000,0.025000},{0.281250,0.643750,0.050000,0.050000},{0.293750,0.643750,0.025000,0.025000},{0.293750,0.643750,0.050000,0.050000},{0.306250,0.643750,0.025000,0.025000},{0.306250,0.643750,0.050000,0.050000},{0.318750,0.643750,0.025000,0.025000},{0.318750,0.643750,0.050000,0.050000},{0.331250,0.643750,0.025000,0.025000},{0.331250,0.643750,0.050000,0.050000},{0.343750,0.643750,0.025000,0.025000},{0.343750,0.643750,0.050000,0.050000},{0.356250,0.643750,0.025000,0.025000},{0.356250,0.643750,0.050000,0.050000},{0.368750,0.643750,0.025000,0.025000},{0.368750,0.643750,0.050000,0.050000},{0.381250,0.643750,0.025000,0.025000},{0.381250,0.643750,0.050000,0.050000},{0.393750,0.643750,0.025000,0.025000},{0.393750,0.643750,0.050000,0.050000},{0.406250,0.643750,0.025000,0.025000},{0.406250,0.643750,0.050000,0.050000},{0.418750,0.643750,0.025000,0.025000},{0.418750,0.643750,0.050000,0.050000},{0.431250,0.643750,0.025000,0.025000},{0.431250,0.643750,0.050000,0.050000},{0.443750,0.643750,0.025000,0.025000},{0.443750,0.643750,0.050000,0.050000},{0.456250,0.643750,0.025000,0.025000},{0.456250,0.643750,0.050000,0.050000},{0.468750,0.643750,0.025000,0.025000},{0.468750,0.643750,0.050000,0.050000},{0.481250,0.643750,0.025000,0.025000},{0.481250,0.643750,0.050000,0.050000},{0.493750,0.643750,0.025000,0.025000},{0.493750,0.643750,0.050000,0.050000},{0.506250,0.643750,0.025000,0.025000},{0.506250,0.643750,0.050000,0.050000},{0.518750,0.643750,0.025000,0.025000},{0.518750,0.643750,0.050000,0.050000},{0.531250,0.643750,0.025000,0.025000},{0.531250,0.643750,0.050000,0.050000},{0.543750,0.643750,0.025000,0.025000},{0.543750,0.643750,0.050000,0.050000},{0.556250,0.643750,0.025000,0.025000},{0.556250,0.643750,0.050000,0.050000},{0.568750,0.643750,0.025000,0.025000},{0.568750,0.643750,0.050000,0.050000},{0.581250,0.643750,0.025000,0.025000},{0.581250,0.643750,0.050000,0.050000},{0.593750,0.643750,0.025000,0.025000},{0.593750,0.643750,0.050000,0.050000},{0.606250,0.643750,0.025000,0.025000},{0.606250,0.643750,0.050000,0.050000},{0.618750,0.643750,0.025000,0.025000},{0.618750,0.643750,0.050000,0.050000},{0.631250,0.643750,0.025000,0.025000},{0.631250,0.643750,0.050000,0.050000},{0.643750,0.643750,0.025000,0.025000},{0.643750,0.643750,0.050000,0.050000},{0.656250,0.643750,0.025000,0.025000},{0.656250,0.643750,0.050000,0.050000},{0.668750,0.643750,0.025000,0.025000},{0.668750,0.643750,0.050000,0.050000},{0.681250,0.643750,0.025000,0.025000},{0.681250,0.643750,0.050000,0.050000},{0.693750,0.643750,0.025000,0.025000},{0.693750,0.643750,0.050000,0.050000},{0.706250,0.643750,0.025000,0.025000},{0.706250,0.643750,0.050000,0.050000},{0.718750,0.643750,0.025000,0.025000},{0.718750,0.643750,0.050000,0.050000},{0.731250,0.643750,0.025000,0.025000},{0.731250,0.643750,0.050000,0.050000},{0.743750,0.643750,0.025000,0.025000},{0.743750,0.643750,0.050000,0.050000},{0.756250,0.643750,0.025000,0.025000},{0.756250,0.643750,0.050000,0.050000},{0.768750,0.643750,0.025000,0.025000},{0.768750,0.643750,0.050000,0.050000},{0.781250,0.643750,0.025000,0.025000},{0.781250,0.643750,0.050000,0.050000},{0.793750,0.643750,0.025000,0.025000},{0.793750,0.643750,0.050000,0.050000},{0.806250,0.643750,0.025000,0.025000},{0.806250,0.643750,0.050000,0.050000},{0.818750,0.643750,0.025000,0.025000},{0.818750,0.643750,0.050000,0.050000},{0.831250,0.643750,0.025000,0.025000},{0.831250,0.643750,0.050000,0.050000},{0.843750,0.643750,0.025000,0.025000},{0.843750,0.643750,0.050000,0.050000},{0.856250,0.643750,0.025000,0.025000},{0.856250,0.643750,0.050000,0.050000},{0.868750,0.643750,0.025000,0.025000},{0.868750,0.643750,0.050000,0.050000},{0.881250,0.643750,0.025000,0.025000},{0.881250,0.643750,0.050000,0.050000},{0.893750,0.643750,0.025000,0.025000},{0.893750,0.643750,0.050000,0.050000},{0.906250,0.643750,0.025000,0.025000},{0.906250,0.643750,0.050000,0.050000},{0.918750,0.643750,0.025000,0.025000},{0.918750,0.643750,0.050000,0.050000},{0.931250,0.643750,0.025000,0.025000},{0.931250,0.643750,0.050000,0.050000},{0.943750,0.643750,0.025000,0.025000},{0.943750,0.643750,0.050000,0.050000},{0.956250,0.643750,0.025000,0.025000},{0.956250,0.643750,0.050000,0.050000},{0.968750,0.643750,0.025000,0.025000},{0.968750,0.643750,0.050000,0.050000},{0.981250,0.643750,0.025000,0.025000},{0.981250,0.643750,0.050000,0.050000},{0.993750,0.643750,0.025000,0.025000},{0.993750,0.643750,0.050000,0.050000},{0.006250,0.656250,0.025000,0.025000},{0.006250,0.656250,0.050000,0.050000},{0.018750,0.656250,0.025000,0.025000},{0.018750,0.656250,0.050000,0.050000},{0.031250,0.656250,0.025000,0.025000},{0.031250,0.656250,0.050000,0.050000},{0.043750,0.656250,0.025000,0.025000},{0.043750,0.656250,0.050000,0.050000},{0.056250,0.656250,0.025000,0.025000},{0.056250,0.656250,0.050000,0.050000},{0.068750,0.656250,0.025000,0.025000},{0.068750,0.656250,0.050000,0.050000},{0.081250,0.656250,0.025000,0.025000},{0.081250,0.656250,0.050000,0.050000},{0.093750,0.656250,0.025000,0.025000},{0.093750,0.656250,0.050000,0.050000},{0.106250,0.656250,0.025000,0.025000},{0.106250,0.656250,0.050000,0.050000},{0.118750,0.656250,0.025000,0.025000},{0.118750,0.656250,0.050000,0.050000},{0.131250,0.656250,0.025000,0.025000},{0.131250,0.656250,0.050000,0.050000},{0.143750,0.656250,0.025000,0.025000},{0.143750,0.656250,0.050000,0.050000},{0.156250,0.656250,0.025000,0.025000},{0.156250,0.656250,0.050000,0.050000},{0.168750,0.656250,0.025000,0.025000},{0.168750,0.656250,0.050000,0.050000},{0.181250,0.656250,0.025000,0.025000},{0.181250,0.656250,0.050000,0.050000},{0.193750,0.656250,0.025000,0.025000},{0.193750,0.656250,0.050000,0.050000},{0.206250,0.656250,0.025000,0.025000},{0.206250,0.656250,0.050000,0.050000},{0.218750,0.656250,0.025000,0.025000},{0.218750,0.656250,0.050000,0.050000},{0.231250,0.656250,0.025000,0.025000},{0.231250,0.656250,0.050000,0.050000},{0.243750,0.656250,0.025000,0.025000},{0.243750,0.656250,0.050000,0.050000},{0.256250,0.656250,0.025000,0.025000},{0.256250,0.656250,0.050000,0.050000},{0.268750,0.656250,0.025000,0.025000},{0.268750,0.656250,0.050000,0.050000},{0.281250,0.656250,0.025000,0.025000},{0.281250,0.656250,0.050000,0.050000},{0.293750,0.656250,0.025000,0.025000},{0.293750,0.656250,0.050000,0.050000},{0.306250,0.656250,0.025000,0.025000},{0.306250,0.656250,0.050000,0.050000},{0.318750,0.656250,0.025000,0.025000},{0.318750,0.656250,0.050000,0.050000},{0.331250,0.656250,0.025000,0.025000},{0.331250,0.656250,0.050000,0.050000},{0.343750,0.656250,0.025000,0.025000},{0.343750,0.656250,0.050000,0.050000},{0.356250,0.656250,0.025000,0.025000},{0.356250,0.656250,0.050000,0.050000},{0.368750,0.656250,0.025000,0.025000},{0.368750,0.656250,0.050000,0.050000},{0.381250,0.656250,0.025000,0.025000},{0.381250,0.656250,0.050000,0.050000},{0.393750,0.656250,0.025000,0.025000},{0.393750,0.656250,0.050000,0.050000},{0.406250,0.656250,0.025000,0.025000},{0.406250,0.656250,0.050000,0.050000},{0.418750,0.656250,0.025000,0.025000},{0.418750,0.656250,0.050000,0.050000},{0.431250,0.656250,0.025000,0.025000},{0.431250,0.656250,0.050000,0.050000},{0.443750,0.656250,0.025000,0.025000},{0.443750,0.656250,0.050000,0.050000},{0.456250,0.656250,0.025000,0.025000},{0.456250,0.656250,0.050000,0.050000},{0.468750,0.656250,0.025000,0.025000},{0.468750,0.656250,0.050000,0.050000},{0.481250,0.656250,0.025000,0.025000},{0.481250,0.656250,0.050000,0.050000},{0.493750,0.656250,0.025000,0.025000},{0.493750,0.656250,0.050000,0.050000},{0.506250,0.656250,0.025000,0.025000},{0.506250,0.656250,0.050000,0.050000},{0.518750,0.656250,0.025000,0.025000},{0.518750,0.656250,0.050000,0.050000},{0.531250,0.656250,0.025000,0.025000},{0.531250,0.656250,0.050000,0.050000},{0.543750,0.656250,0.025000,0.025000},{0.543750,0.656250,0.050000,0.050000},{0.556250,0.656250,0.025000,0.025000},{0.556250,0.656250,0.050000,0.050000},{0.568750,0.656250,0.025000,0.025000},{0.568750,0.656250,0.050000,0.050000},{0.581250,0.656250,0.025000,0.025000},{0.581250,0.656250,0.050000,0.050000},{0.593750,0.656250,0.025000,0.025000},{0.593750,0.656250,0.050000,0.050000},{0.606250,0.656250,0.025000,0.025000},{0.606250,0.656250,0.050000,0.050000},{0.618750,0.656250,0.025000,0.025000},{0.618750,0.656250,0.050000,0.050000},{0.631250,0.656250,0.025000,0.025000},{0.631250,0.656250,0.050000,0.050000},{0.643750,0.656250,0.025000,0.025000},{0.643750,0.656250,0.050000,0.050000},{0.656250,0.656250,0.025000,0.025000},{0.656250,0.656250,0.050000,0.050000},{0.668750,0.656250,0.025000,0.025000},{0.668750,0.656250,0.050000,0.050000},{0.681250,0.656250,0.025000,0.025000},{0.681250,0.656250,0.050000,0.050000},{0.693750,0.656250,0.025000,0.025000},{0.693750,0.656250,0.050000,0.050000},{0.706250,0.656250,0.025000,0.025000},{0.706250,0.656250,0.050000,0.050000},{0.718750,0.656250,0.025000,0.025000},{0.718750,0.656250,0.050000,0.050000},{0.731250,0.656250,0.025000,0.025000},{0.731250,0.656250,0.050000,0.050000},{0.743750,0.656250,0.025000,0.025000},{0.743750,0.656250,0.050000,0.050000},{0.756250,0.656250,0.025000,0.025000},{0.756250,0.656250,0.050000,0.050000},{0.768750,0.656250,0.025000,0.025000},{0.768750,0.656250,0.050000,0.050000},{0.781250,0.656250,0.025000,0.025000},{0.781250,0.656250,0.050000,0.050000},{0.793750,0.656250,0.025000,0.025000},{0.793750,0.656250,0.050000,0.050000},{0.806250,0.656250,0.025000,0.025000},{0.806250,0.656250,0.050000,0.050000},{0.818750,0.656250,0.025000,0.025000},{0.818750,0.656250,0.050000,0.050000},{0.831250,0.656250,0.025000,0.025000},{0.831250,0.656250,0.050000,0.050000},{0.843750,0.656250,0.025000,0.025000},{0.843750,0.656250,0.050000,0.050000},{0.856250,0.656250,0.025000,0.025000},{0.856250,0.656250,0.050000,0.050000},{0.868750,0.656250,0.025000,0.025000},{0.868750,0.656250,0.050000,0.050000},{0.881250,0.656250,0.025000,0.025000},{0.881250,0.656250,0.050000,0.050000},{0.893750,0.656250,0.025000,0.025000},{0.893750,0.656250,0.050000,0.050000},{0.906250,0.656250,0.025000,0.025000},{0.906250,0.656250,0.050000,0.050000},{0.918750,0.656250,0.025000,0.025000},{0.918750,0.656250,0.050000,0.050000},{0.931250,0.656250,0.025000,0.025000},{0.931250,0.656250,0.050000,0.050000},{0.943750,0.656250,0.025000,0.025000},{0.943750,0.656250,0.050000,0.050000},{0.956250,0.656250,0.025000,0.025000},{0.956250,0.656250,0.050000,0.050000},{0.968750,0.656250,0.025000,0.025000},{0.968750,0.656250,0.050000,0.050000},{0.981250,0.656250,0.025000,0.025000},{0.981250,0.656250,0.050000,0.050000},{0.993750,0.656250,0.025000,0.025000},{0.993750,0.656250,0.050000,0.050000},{0.006250,0.668750,0.025000,0.025000},{0.006250,0.668750,0.050000,0.050000},{0.018750,0.668750,0.025000,0.025000},{0.018750,0.668750,0.050000,0.050000},{0.031250,0.668750,0.025000,0.025000},{0.031250,0.668750,0.050000,0.050000},{0.043750,0.668750,0.025000,0.025000},{0.043750,0.668750,0.050000,0.050000},{0.056250,0.668750,0.025000,0.025000},{0.056250,0.668750,0.050000,0.050000},{0.068750,0.668750,0.025000,0.025000},{0.068750,0.668750,0.050000,0.050000},{0.081250,0.668750,0.025000,0.025000},{0.081250,0.668750,0.050000,0.050000},{0.093750,0.668750,0.025000,0.025000},{0.093750,0.668750,0.050000,0.050000},{0.106250,0.668750,0.025000,0.025000},{0.106250,0.668750,0.050000,0.050000},{0.118750,0.668750,0.025000,0.025000},{0.118750,0.668750,0.050000,0.050000},{0.131250,0.668750,0.025000,0.025000},{0.131250,0.668750,0.050000,0.050000},{0.143750,0.668750,0.025000,0.025000},{0.143750,0.668750,0.050000,0.050000},{0.156250,0.668750,0.025000,0.025000},{0.156250,0.668750,0.050000,0.050000},{0.168750,0.668750,0.025000,0.025000},{0.168750,0.668750,0.050000,0.050000},{0.181250,0.668750,0.025000,0.025000},{0.181250,0.668750,0.050000,0.050000},{0.193750,0.668750,0.025000,0.025000},{0.193750,0.668750,0.050000,0.050000},{0.206250,0.668750,0.025000,0.025000},{0.206250,0.668750,0.050000,0.050000},{0.218750,0.668750,0.025000,0.025000},{0.218750,0.668750,0.050000,0.050000},{0.231250,0.668750,0.025000,0.025000},{0.231250,0.668750,0.050000,0.050000},{0.243750,0.668750,0.025000,0.025000},{0.243750,0.668750,0.050000,0.050000},{0.256250,0.668750,0.025000,0.025000},{0.256250,0.668750,0.050000,0.050000},{0.268750,0.668750,0.025000,0.025000},{0.268750,0.668750,0.050000,0.050000},{0.281250,0.668750,0.025000,0.025000},{0.281250,0.668750,0.050000,0.050000},{0.293750,0.668750,0.025000,0.025000},{0.293750,0.668750,0.050000,0.050000},{0.306250,0.668750,0.025000,0.025000},{0.306250,0.668750,0.050000,0.050000},{0.318750,0.668750,0.025000,0.025000},{0.318750,0.668750,0.050000,0.050000},{0.331250,0.668750,0.025000,0.025000},{0.331250,0.668750,0.050000,0.050000},{0.343750,0.668750,0.025000,0.025000},{0.343750,0.668750,0.050000,0.050000},{0.356250,0.668750,0.025000,0.025000},{0.356250,0.668750,0.050000,0.050000},{0.368750,0.668750,0.025000,0.025000},{0.368750,0.668750,0.050000,0.050000},{0.381250,0.668750,0.025000,0.025000},{0.381250,0.668750,0.050000,0.050000},{0.393750,0.668750,0.025000,0.025000},{0.393750,0.668750,0.050000,0.050000},{0.406250,0.668750,0.025000,0.025000},{0.406250,0.668750,0.050000,0.050000},{0.418750,0.668750,0.025000,0.025000},{0.418750,0.668750,0.050000,0.050000},{0.431250,0.668750,0.025000,0.025000},{0.431250,0.668750,0.050000,0.050000},{0.443750,0.668750,0.025000,0.025000},{0.443750,0.668750,0.050000,0.050000},{0.456250,0.668750,0.025000,0.025000},{0.456250,0.668750,0.050000,0.050000},{0.468750,0.668750,0.025000,0.025000},{0.468750,0.668750,0.050000,0.050000},{0.481250,0.668750,0.025000,0.025000},{0.481250,0.668750,0.050000,0.050000},{0.493750,0.668750,0.025000,0.025000},{0.493750,0.668750,0.050000,0.050000},{0.506250,0.668750,0.025000,0.025000},{0.506250,0.668750,0.050000,0.050000},{0.518750,0.668750,0.025000,0.025000},{0.518750,0.668750,0.050000,0.050000},{0.531250,0.668750,0.025000,0.025000},{0.531250,0.668750,0.050000,0.050000},{0.543750,0.668750,0.025000,0.025000},{0.543750,0.668750,0.050000,0.050000},{0.556250,0.668750,0.025000,0.025000},{0.556250,0.668750,0.050000,0.050000},{0.568750,0.668750,0.025000,0.025000},{0.568750,0.668750,0.050000,0.050000},{0.581250,0.668750,0.025000,0.025000},{0.581250,0.668750,0.050000,0.050000},{0.593750,0.668750,0.025000,0.025000},{0.593750,0.668750,0.050000,0.050000},{0.606250,0.668750,0.025000,0.025000},{0.606250,0.668750,0.050000,0.050000},{0.618750,0.668750,0.025000,0.025000},{0.618750,0.668750,0.050000,0.050000},{0.631250,0.668750,0.025000,0.025000},{0.631250,0.668750,0.050000,0.050000},{0.643750,0.668750,0.025000,0.025000},{0.643750,0.668750,0.050000,0.050000},{0.656250,0.668750,0.025000,0.025000},{0.656250,0.668750,0.050000,0.050000},{0.668750,0.668750,0.025000,0.025000},{0.668750,0.668750,0.050000,0.050000},{0.681250,0.668750,0.025000,0.025000},{0.681250,0.668750,0.050000,0.050000},{0.693750,0.668750,0.025000,0.025000},{0.693750,0.668750,0.050000,0.050000},{0.706250,0.668750,0.025000,0.025000},{0.706250,0.668750,0.050000,0.050000},{0.718750,0.668750,0.025000,0.025000},{0.718750,0.668750,0.050000,0.050000},{0.731250,0.668750,0.025000,0.025000},{0.731250,0.668750,0.050000,0.050000},{0.743750,0.668750,0.025000,0.025000},{0.743750,0.668750,0.050000,0.050000},{0.756250,0.668750,0.025000,0.025000},{0.756250,0.668750,0.050000,0.050000},{0.768750,0.668750,0.025000,0.025000},{0.768750,0.668750,0.050000,0.050000},{0.781250,0.668750,0.025000,0.025000},{0.781250,0.668750,0.050000,0.050000},{0.793750,0.668750,0.025000,0.025000},{0.793750,0.668750,0.050000,0.050000},{0.806250,0.668750,0.025000,0.025000},{0.806250,0.668750,0.050000,0.050000},{0.818750,0.668750,0.025000,0.025000},{0.818750,0.668750,0.050000,0.050000},{0.831250,0.668750,0.025000,0.025000},{0.831250,0.668750,0.050000,0.050000},{0.843750,0.668750,0.025000,0.025000},{0.843750,0.668750,0.050000,0.050000},{0.856250,0.668750,0.025000,0.025000},{0.856250,0.668750,0.050000,0.050000},{0.868750,0.668750,0.025000,0.025000},{0.868750,0.668750,0.050000,0.050000},{0.881250,0.668750,0.025000,0.025000},{0.881250,0.668750,0.050000,0.050000},{0.893750,0.668750,0.025000,0.025000},{0.893750,0.668750,0.050000,0.050000},{0.906250,0.668750,0.025000,0.025000},{0.906250,0.668750,0.050000,0.050000},{0.918750,0.668750,0.025000,0.025000},{0.918750,0.668750,0.050000,0.050000},{0.931250,0.668750,0.025000,0.025000},{0.931250,0.668750,0.050000,0.050000},{0.943750,0.668750,0.025000,0.025000},{0.943750,0.668750,0.050000,0.050000},{0.956250,0.668750,0.025000,0.025000},{0.956250,0.668750,0.050000,0.050000},{0.968750,0.668750,0.025000,0.025000},{0.968750,0.668750,0.050000,0.050000},{0.981250,0.668750,0.025000,0.025000},{0.981250,0.668750,0.050000,0.050000},{0.993750,0.668750,0.025000,0.025000},{0.993750,0.668750,0.050000,0.050000},{0.006250,0.681250,0.025000,0.025000},{0.006250,0.681250,0.050000,0.050000},{0.018750,0.681250,0.025000,0.025000},{0.018750,0.681250,0.050000,0.050000},{0.031250,0.681250,0.025000,0.025000},{0.031250,0.681250,0.050000,0.050000},{0.043750,0.681250,0.025000,0.025000},{0.043750,0.681250,0.050000,0.050000},{0.056250,0.681250,0.025000,0.025000},{0.056250,0.681250,0.050000,0.050000},{0.068750,0.681250,0.025000,0.025000},{0.068750,0.681250,0.050000,0.050000},{0.081250,0.681250,0.025000,0.025000},{0.081250,0.681250,0.050000,0.050000},{0.093750,0.681250,0.025000,0.025000},{0.093750,0.681250,0.050000,0.050000},{0.106250,0.681250,0.025000,0.025000},{0.106250,0.681250,0.050000,0.050000},{0.118750,0.681250,0.025000,0.025000},{0.118750,0.681250,0.050000,0.050000},{0.131250,0.681250,0.025000,0.025000},{0.131250,0.681250,0.050000,0.050000},{0.143750,0.681250,0.025000,0.025000},{0.143750,0.681250,0.050000,0.050000},{0.156250,0.681250,0.025000,0.025000},{0.156250,0.681250,0.050000,0.050000},{0.168750,0.681250,0.025000,0.025000},{0.168750,0.681250,0.050000,0.050000},{0.181250,0.681250,0.025000,0.025000},{0.181250,0.681250,0.050000,0.050000},{0.193750,0.681250,0.025000,0.025000},{0.193750,0.681250,0.050000,0.050000},{0.206250,0.681250,0.025000,0.025000},{0.206250,0.681250,0.050000,0.050000},{0.218750,0.681250,0.025000,0.025000},{0.218750,0.681250,0.050000,0.050000},{0.231250,0.681250,0.025000,0.025000},{0.231250,0.681250,0.050000,0.050000},{0.243750,0.681250,0.025000,0.025000},{0.243750,0.681250,0.050000,0.050000},{0.256250,0.681250,0.025000,0.025000},{0.256250,0.681250,0.050000,0.050000},{0.268750,0.681250,0.025000,0.025000},{0.268750,0.681250,0.050000,0.050000},{0.281250,0.681250,0.025000,0.025000},{0.281250,0.681250,0.050000,0.050000},{0.293750,0.681250,0.025000,0.025000},{0.293750,0.681250,0.050000,0.050000},{0.306250,0.681250,0.025000,0.025000},{0.306250,0.681250,0.050000,0.050000},{0.318750,0.681250,0.025000,0.025000},{0.318750,0.681250,0.050000,0.050000},{0.331250,0.681250,0.025000,0.025000},{0.331250,0.681250,0.050000,0.050000},{0.343750,0.681250,0.025000,0.025000},{0.343750,0.681250,0.050000,0.050000},{0.356250,0.681250,0.025000,0.025000},{0.356250,0.681250,0.050000,0.050000},{0.368750,0.681250,0.025000,0.025000},{0.368750,0.681250,0.050000,0.050000},{0.381250,0.681250,0.025000,0.025000},{0.381250,0.681250,0.050000,0.050000},{0.393750,0.681250,0.025000,0.025000},{0.393750,0.681250,0.050000,0.050000},{0.406250,0.681250,0.025000,0.025000},{0.406250,0.681250,0.050000,0.050000},{0.418750,0.681250,0.025000,0.025000},{0.418750,0.681250,0.050000,0.050000},{0.431250,0.681250,0.025000,0.025000},{0.431250,0.681250,0.050000,0.050000},{0.443750,0.681250,0.025000,0.025000},{0.443750,0.681250,0.050000,0.050000},{0.456250,0.681250,0.025000,0.025000},{0.456250,0.681250,0.050000,0.050000},{0.468750,0.681250,0.025000,0.025000},{0.468750,0.681250,0.050000,0.050000},{0.481250,0.681250,0.025000,0.025000},{0.481250,0.681250,0.050000,0.050000},{0.493750,0.681250,0.025000,0.025000},{0.493750,0.681250,0.050000,0.050000},{0.506250,0.681250,0.025000,0.025000},{0.506250,0.681250,0.050000,0.050000},{0.518750,0.681250,0.025000,0.025000},{0.518750,0.681250,0.050000,0.050000},{0.531250,0.681250,0.025000,0.025000},{0.531250,0.681250,0.050000,0.050000},{0.543750,0.681250,0.025000,0.025000},{0.543750,0.681250,0.050000,0.050000},{0.556250,0.681250,0.025000,0.025000},{0.556250,0.681250,0.050000,0.050000},{0.568750,0.681250,0.025000,0.025000},{0.568750,0.681250,0.050000,0.050000},{0.581250,0.681250,0.025000,0.025000},{0.581250,0.681250,0.050000,0.050000},{0.593750,0.681250,0.025000,0.025000},{0.593750,0.681250,0.050000,0.050000},{0.606250,0.681250,0.025000,0.025000},{0.606250,0.681250,0.050000,0.050000},{0.618750,0.681250,0.025000,0.025000},{0.618750,0.681250,0.050000,0.050000},{0.631250,0.681250,0.025000,0.025000},{0.631250,0.681250,0.050000,0.050000},{0.643750,0.681250,0.025000,0.025000},{0.643750,0.681250,0.050000,0.050000},{0.656250,0.681250,0.025000,0.025000},{0.656250,0.681250,0.050000,0.050000},{0.668750,0.681250,0.025000,0.025000},{0.668750,0.681250,0.050000,0.050000},{0.681250,0.681250,0.025000,0.025000},{0.681250,0.681250,0.050000,0.050000},{0.693750,0.681250,0.025000,0.025000},{0.693750,0.681250,0.050000,0.050000},{0.706250,0.681250,0.025000,0.025000},{0.706250,0.681250,0.050000,0.050000},{0.718750,0.681250,0.025000,0.025000},{0.718750,0.681250,0.050000,0.050000},{0.731250,0.681250,0.025000,0.025000},{0.731250,0.681250,0.050000,0.050000},{0.743750,0.681250,0.025000,0.025000},{0.743750,0.681250,0.050000,0.050000},{0.756250,0.681250,0.025000,0.025000},{0.756250,0.681250,0.050000,0.050000},{0.768750,0.681250,0.025000,0.025000},{0.768750,0.681250,0.050000,0.050000},{0.781250,0.681250,0.025000,0.025000},{0.781250,0.681250,0.050000,0.050000},{0.793750,0.681250,0.025000,0.025000},{0.793750,0.681250,0.050000,0.050000},{0.806250,0.681250,0.025000,0.025000},{0.806250,0.681250,0.050000,0.050000},{0.818750,0.681250,0.025000,0.025000},{0.818750,0.681250,0.050000,0.050000},{0.831250,0.681250,0.025000,0.025000},{0.831250,0.681250,0.050000,0.050000},{0.843750,0.681250,0.025000,0.025000},{0.843750,0.681250,0.050000,0.050000},{0.856250,0.681250,0.025000,0.025000},{0.856250,0.681250,0.050000,0.050000},{0.868750,0.681250,0.025000,0.025000},{0.868750,0.681250,0.050000,0.050000},{0.881250,0.681250,0.025000,0.025000},{0.881250,0.681250,0.050000,0.050000},{0.893750,0.681250,0.025000,0.025000},{0.893750,0.681250,0.050000,0.050000},{0.906250,0.681250,0.025000,0.025000},{0.906250,0.681250,0.050000,0.050000},{0.918750,0.681250,0.025000,0.025000},{0.918750,0.681250,0.050000,0.050000},{0.931250,0.681250,0.025000,0.025000},{0.931250,0.681250,0.050000,0.050000},{0.943750,0.681250,0.025000,0.025000},{0.943750,0.681250,0.050000,0.050000},{0.956250,0.681250,0.025000,0.025000},{0.956250,0.681250,0.050000,0.050000},{0.968750,0.681250,0.025000,0.025000},{0.968750,0.681250,0.050000,0.050000},{0.981250,0.681250,0.025000,0.025000},{0.981250,0.681250,0.050000,0.050000},{0.993750,0.681250,0.025000,0.025000},{0.993750,0.681250,0.050000,0.050000},{0.006250,0.693750,0.025000,0.025000},{0.006250,0.693750,0.050000,0.050000},{0.018750,0.693750,0.025000,0.025000},{0.018750,0.693750,0.050000,0.050000},{0.031250,0.693750,0.025000,0.025000},{0.031250,0.693750,0.050000,0.050000},{0.043750,0.693750,0.025000,0.025000},{0.043750,0.693750,0.050000,0.050000},{0.056250,0.693750,0.025000,0.025000},{0.056250,0.693750,0.050000,0.050000},{0.068750,0.693750,0.025000,0.025000},{0.068750,0.693750,0.050000,0.050000},{0.081250,0.693750,0.025000,0.025000},{0.081250,0.693750,0.050000,0.050000},{0.093750,0.693750,0.025000,0.025000},{0.093750,0.693750,0.050000,0.050000},{0.106250,0.693750,0.025000,0.025000},{0.106250,0.693750,0.050000,0.050000},{0.118750,0.693750,0.025000,0.025000},{0.118750,0.693750,0.050000,0.050000},{0.131250,0.693750,0.025000,0.025000},{0.131250,0.693750,0.050000,0.050000},{0.143750,0.693750,0.025000,0.025000},{0.143750,0.693750,0.050000,0.050000},{0.156250,0.693750,0.025000,0.025000},{0.156250,0.693750,0.050000,0.050000},{0.168750,0.693750,0.025000,0.025000},{0.168750,0.693750,0.050000,0.050000},{0.181250,0.693750,0.025000,0.025000},{0.181250,0.693750,0.050000,0.050000},{0.193750,0.693750,0.025000,0.025000},{0.193750,0.693750,0.050000,0.050000},{0.206250,0.693750,0.025000,0.025000},{0.206250,0.693750,0.050000,0.050000},{0.218750,0.693750,0.025000,0.025000},{0.218750,0.693750,0.050000,0.050000},{0.231250,0.693750,0.025000,0.025000},{0.231250,0.693750,0.050000,0.050000},{0.243750,0.693750,0.025000,0.025000},{0.243750,0.693750,0.050000,0.050000},{0.256250,0.693750,0.025000,0.025000},{0.256250,0.693750,0.050000,0.050000},{0.268750,0.693750,0.025000,0.025000},{0.268750,0.693750,0.050000,0.050000},{0.281250,0.693750,0.025000,0.025000},{0.281250,0.693750,0.050000,0.050000},{0.293750,0.693750,0.025000,0.025000},{0.293750,0.693750,0.050000,0.050000},{0.306250,0.693750,0.025000,0.025000},{0.306250,0.693750,0.050000,0.050000},{0.318750,0.693750,0.025000,0.025000},{0.318750,0.693750,0.050000,0.050000},{0.331250,0.693750,0.025000,0.025000},{0.331250,0.693750,0.050000,0.050000},{0.343750,0.693750,0.025000,0.025000},{0.343750,0.693750,0.050000,0.050000},{0.356250,0.693750,0.025000,0.025000},{0.356250,0.693750,0.050000,0.050000},{0.368750,0.693750,0.025000,0.025000},{0.368750,0.693750,0.050000,0.050000},{0.381250,0.693750,0.025000,0.025000},{0.381250,0.693750,0.050000,0.050000},{0.393750,0.693750,0.025000,0.025000},{0.393750,0.693750,0.050000,0.050000},{0.406250,0.693750,0.025000,0.025000},{0.406250,0.693750,0.050000,0.050000},{0.418750,0.693750,0.025000,0.025000},{0.418750,0.693750,0.050000,0.050000},{0.431250,0.693750,0.025000,0.025000},{0.431250,0.693750,0.050000,0.050000},{0.443750,0.693750,0.025000,0.025000},{0.443750,0.693750,0.050000,0.050000},{0.456250,0.693750,0.025000,0.025000},{0.456250,0.693750,0.050000,0.050000},{0.468750,0.693750,0.025000,0.025000},{0.468750,0.693750,0.050000,0.050000},{0.481250,0.693750,0.025000,0.025000},{0.481250,0.693750,0.050000,0.050000},{0.493750,0.693750,0.025000,0.025000},{0.493750,0.693750,0.050000,0.050000},{0.506250,0.693750,0.025000,0.025000},{0.506250,0.693750,0.050000,0.050000},{0.518750,0.693750,0.025000,0.025000},{0.518750,0.693750,0.050000,0.050000},{0.531250,0.693750,0.025000,0.025000},{0.531250,0.693750,0.050000,0.050000},{0.543750,0.693750,0.025000,0.025000},{0.543750,0.693750,0.050000,0.050000},{0.556250,0.693750,0.025000,0.025000},{0.556250,0.693750,0.050000,0.050000},{0.568750,0.693750,0.025000,0.025000},{0.568750,0.693750,0.050000,0.050000},{0.581250,0.693750,0.025000,0.025000},{0.581250,0.693750,0.050000,0.050000},{0.593750,0.693750,0.025000,0.025000},{0.593750,0.693750,0.050000,0.050000},{0.606250,0.693750,0.025000,0.025000},{0.606250,0.693750,0.050000,0.050000},{0.618750,0.693750,0.025000,0.025000},{0.618750,0.693750,0.050000,0.050000},{0.631250,0.693750,0.025000,0.025000},{0.631250,0.693750,0.050000,0.050000},{0.643750,0.693750,0.025000,0.025000},{0.643750,0.693750,0.050000,0.050000},{0.656250,0.693750,0.025000,0.025000},{0.656250,0.693750,0.050000,0.050000},{0.668750,0.693750,0.025000,0.025000},{0.668750,0.693750,0.050000,0.050000},{0.681250,0.693750,0.025000,0.025000},{0.681250,0.693750,0.050000,0.050000},{0.693750,0.693750,0.025000,0.025000},{0.693750,0.693750,0.050000,0.050000},{0.706250,0.693750,0.025000,0.025000},{0.706250,0.693750,0.050000,0.050000},{0.718750,0.693750,0.025000,0.025000},{0.718750,0.693750,0.050000,0.050000},{0.731250,0.693750,0.025000,0.025000},{0.731250,0.693750,0.050000,0.050000},{0.743750,0.693750,0.025000,0.025000},{0.743750,0.693750,0.050000,0.050000},{0.756250,0.693750,0.025000,0.025000},{0.756250,0.693750,0.050000,0.050000},{0.768750,0.693750,0.025000,0.025000},{0.768750,0.693750,0.050000,0.050000},{0.781250,0.693750,0.025000,0.025000},{0.781250,0.693750,0.050000,0.050000},{0.793750,0.693750,0.025000,0.025000},{0.793750,0.693750,0.050000,0.050000},{0.806250,0.693750,0.025000,0.025000},{0.806250,0.693750,0.050000,0.050000},{0.818750,0.693750,0.025000,0.025000},{0.818750,0.693750,0.050000,0.050000},{0.831250,0.693750,0.025000,0.025000},{0.831250,0.693750,0.050000,0.050000},{0.843750,0.693750,0.025000,0.025000},{0.843750,0.693750,0.050000,0.050000},{0.856250,0.693750,0.025000,0.025000},{0.856250,0.693750,0.050000,0.050000},{0.868750,0.693750,0.025000,0.025000},{0.868750,0.693750,0.050000,0.050000},{0.881250,0.693750,0.025000,0.025000},{0.881250,0.693750,0.050000,0.050000},{0.893750,0.693750,0.025000,0.025000},{0.893750,0.693750,0.050000,0.050000},{0.906250,0.693750,0.025000,0.025000},{0.906250,0.693750,0.050000,0.050000},{0.918750,0.693750,0.025000,0.025000},{0.918750,0.693750,0.050000,0.050000},{0.931250,0.693750,0.025000,0.025000},{0.931250,0.693750,0.050000,0.050000},{0.943750,0.693750,0.025000,0.025000},{0.943750,0.693750,0.050000,0.050000},{0.956250,0.693750,0.025000,0.025000},{0.956250,0.693750,0.050000,0.050000},{0.968750,0.693750,0.025000,0.025000},{0.968750,0.693750,0.050000,0.050000},{0.981250,0.693750,0.025000,0.025000},{0.981250,0.693750,0.050000,0.050000},{0.993750,0.693750,0.025000,0.025000},{0.993750,0.693750,0.050000,0.050000},{0.006250,0.706250,0.025000,0.025000},{0.006250,0.706250,0.050000,0.050000},{0.018750,0.706250,0.025000,0.025000},{0.018750,0.706250,0.050000,0.050000},{0.031250,0.706250,0.025000,0.025000},{0.031250,0.706250,0.050000,0.050000},{0.043750,0.706250,0.025000,0.025000},{0.043750,0.706250,0.050000,0.050000},{0.056250,0.706250,0.025000,0.025000},{0.056250,0.706250,0.050000,0.050000},{0.068750,0.706250,0.025000,0.025000},{0.068750,0.706250,0.050000,0.050000},{0.081250,0.706250,0.025000,0.025000},{0.081250,0.706250,0.050000,0.050000},{0.093750,0.706250,0.025000,0.025000},{0.093750,0.706250,0.050000,0.050000},{0.106250,0.706250,0.025000,0.025000},{0.106250,0.706250,0.050000,0.050000},{0.118750,0.706250,0.025000,0.025000},{0.118750,0.706250,0.050000,0.050000},{0.131250,0.706250,0.025000,0.025000},{0.131250,0.706250,0.050000,0.050000},{0.143750,0.706250,0.025000,0.025000},{0.143750,0.706250,0.050000,0.050000},{0.156250,0.706250,0.025000,0.025000},{0.156250,0.706250,0.050000,0.050000},{0.168750,0.706250,0.025000,0.025000},{0.168750,0.706250,0.050000,0.050000},{0.181250,0.706250,0.025000,0.025000},{0.181250,0.706250,0.050000,0.050000},{0.193750,0.706250,0.025000,0.025000},{0.193750,0.706250,0.050000,0.050000},{0.206250,0.706250,0.025000,0.025000},{0.206250,0.706250,0.050000,0.050000},{0.218750,0.706250,0.025000,0.025000},{0.218750,0.706250,0.050000,0.050000},{0.231250,0.706250,0.025000,0.025000},{0.231250,0.706250,0.050000,0.050000},{0.243750,0.706250,0.025000,0.025000},{0.243750,0.706250,0.050000,0.050000},{0.256250,0.706250,0.025000,0.025000},{0.256250,0.706250,0.050000,0.050000},{0.268750,0.706250,0.025000,0.025000},{0.268750,0.706250,0.050000,0.050000},{0.281250,0.706250,0.025000,0.025000},{0.281250,0.706250,0.050000,0.050000},{0.293750,0.706250,0.025000,0.025000},{0.293750,0.706250,0.050000,0.050000},{0.306250,0.706250,0.025000,0.025000},{0.306250,0.706250,0.050000,0.050000},{0.318750,0.706250,0.025000,0.025000},{0.318750,0.706250,0.050000,0.050000},{0.331250,0.706250,0.025000,0.025000},{0.331250,0.706250,0.050000,0.050000},{0.343750,0.706250,0.025000,0.025000},{0.343750,0.706250,0.050000,0.050000},{0.356250,0.706250,0.025000,0.025000},{0.356250,0.706250,0.050000,0.050000},{0.368750,0.706250,0.025000,0.025000},{0.368750,0.706250,0.050000,0.050000},{0.381250,0.706250,0.025000,0.025000},{0.381250,0.706250,0.050000,0.050000},{0.393750,0.706250,0.025000,0.025000},{0.393750,0.706250,0.050000,0.050000},{0.406250,0.706250,0.025000,0.025000},{0.406250,0.706250,0.050000,0.050000},{0.418750,0.706250,0.025000,0.025000},{0.418750,0.706250,0.050000,0.050000},{0.431250,0.706250,0.025000,0.025000},{0.431250,0.706250,0.050000,0.050000},{0.443750,0.706250,0.025000,0.025000},{0.443750,0.706250,0.050000,0.050000},{0.456250,0.706250,0.025000,0.025000},{0.456250,0.706250,0.050000,0.050000},{0.468750,0.706250,0.025000,0.025000},{0.468750,0.706250,0.050000,0.050000},{0.481250,0.706250,0.025000,0.025000},{0.481250,0.706250,0.050000,0.050000},{0.493750,0.706250,0.025000,0.025000},{0.493750,0.706250,0.050000,0.050000},{0.506250,0.706250,0.025000,0.025000},{0.506250,0.706250,0.050000,0.050000},{0.518750,0.706250,0.025000,0.025000},{0.518750,0.706250,0.050000,0.050000},{0.531250,0.706250,0.025000,0.025000},{0.531250,0.706250,0.050000,0.050000},{0.543750,0.706250,0.025000,0.025000},{0.543750,0.706250,0.050000,0.050000},{0.556250,0.706250,0.025000,0.025000},{0.556250,0.706250,0.050000,0.050000},{0.568750,0.706250,0.025000,0.025000},{0.568750,0.706250,0.050000,0.050000},{0.581250,0.706250,0.025000,0.025000},{0.581250,0.706250,0.050000,0.050000},{0.593750,0.706250,0.025000,0.025000},{0.593750,0.706250,0.050000,0.050000},{0.606250,0.706250,0.025000,0.025000},{0.606250,0.706250,0.050000,0.050000},{0.618750,0.706250,0.025000,0.025000},{0.618750,0.706250,0.050000,0.050000},{0.631250,0.706250,0.025000,0.025000},{0.631250,0.706250,0.050000,0.050000},{0.643750,0.706250,0.025000,0.025000},{0.643750,0.706250,0.050000,0.050000},{0.656250,0.706250,0.025000,0.025000},{0.656250,0.706250,0.050000,0.050000},{0.668750,0.706250,0.025000,0.025000},{0.668750,0.706250,0.050000,0.050000},{0.681250,0.706250,0.025000,0.025000},{0.681250,0.706250,0.050000,0.050000},{0.693750,0.706250,0.025000,0.025000},{0.693750,0.706250,0.050000,0.050000},{0.706250,0.706250,0.025000,0.025000},{0.706250,0.706250,0.050000,0.050000},{0.718750,0.706250,0.025000,0.025000},{0.718750,0.706250,0.050000,0.050000},{0.731250,0.706250,0.025000,0.025000},{0.731250,0.706250,0.050000,0.050000},{0.743750,0.706250,0.025000,0.025000},{0.743750,0.706250,0.050000,0.050000},{0.756250,0.706250,0.025000,0.025000},{0.756250,0.706250,0.050000,0.050000},{0.768750,0.706250,0.025000,0.025000},{0.768750,0.706250,0.050000,0.050000},{0.781250,0.706250,0.025000,0.025000},{0.781250,0.706250,0.050000,0.050000},{0.793750,0.706250,0.025000,0.025000},{0.793750,0.706250,0.050000,0.050000},{0.806250,0.706250,0.025000,0.025000},{0.806250,0.706250,0.050000,0.050000},{0.818750,0.706250,0.025000,0.025000},{0.818750,0.706250,0.050000,0.050000},{0.831250,0.706250,0.025000,0.025000},{0.831250,0.706250,0.050000,0.050000},{0.843750,0.706250,0.025000,0.025000},{0.843750,0.706250,0.050000,0.050000},{0.856250,0.706250,0.025000,0.025000},{0.856250,0.706250,0.050000,0.050000},{0.868750,0.706250,0.025000,0.025000},{0.868750,0.706250,0.050000,0.050000},{0.881250,0.706250,0.025000,0.025000},{0.881250,0.706250,0.050000,0.050000},{0.893750,0.706250,0.025000,0.025000},{0.893750,0.706250,0.050000,0.050000},{0.906250,0.706250,0.025000,0.025000},{0.906250,0.706250,0.050000,0.050000},{0.918750,0.706250,0.025000,0.025000},{0.918750,0.706250,0.050000,0.050000},{0.931250,0.706250,0.025000,0.025000},{0.931250,0.706250,0.050000,0.050000},{0.943750,0.706250,0.025000,0.025000},{0.943750,0.706250,0.050000,0.050000},{0.956250,0.706250,0.025000,0.025000},{0.956250,0.706250,0.050000,0.050000},{0.968750,0.706250,0.025000,0.025000},{0.968750,0.706250,0.050000,0.050000},{0.981250,0.706250,0.025000,0.025000},{0.981250,0.706250,0.050000,0.050000},{0.993750,0.706250,0.025000,0.025000},{0.993750,0.706250,0.050000,0.050000},{0.006250,0.718750,0.025000,0.025000},{0.006250,0.718750,0.050000,0.050000},{0.018750,0.718750,0.025000,0.025000},{0.018750,0.718750,0.050000,0.050000},{0.031250,0.718750,0.025000,0.025000},{0.031250,0.718750,0.050000,0.050000},{0.043750,0.718750,0.025000,0.025000},{0.043750,0.718750,0.050000,0.050000},{0.056250,0.718750,0.025000,0.025000},{0.056250,0.718750,0.050000,0.050000},{0.068750,0.718750,0.025000,0.025000},{0.068750,0.718750,0.050000,0.050000},{0.081250,0.718750,0.025000,0.025000},{0.081250,0.718750,0.050000,0.050000},{0.093750,0.718750,0.025000,0.025000},{0.093750,0.718750,0.050000,0.050000},{0.106250,0.718750,0.025000,0.025000},{0.106250,0.718750,0.050000,0.050000},{0.118750,0.718750,0.025000,0.025000},{0.118750,0.718750,0.050000,0.050000},{0.131250,0.718750,0.025000,0.025000},{0.131250,0.718750,0.050000,0.050000},{0.143750,0.718750,0.025000,0.025000},{0.143750,0.718750,0.050000,0.050000},{0.156250,0.718750,0.025000,0.025000},{0.156250,0.718750,0.050000,0.050000},{0.168750,0.718750,0.025000,0.025000},{0.168750,0.718750,0.050000,0.050000},{0.181250,0.718750,0.025000,0.025000},{0.181250,0.718750,0.050000,0.050000},{0.193750,0.718750,0.025000,0.025000},{0.193750,0.718750,0.050000,0.050000},{0.206250,0.718750,0.025000,0.025000},{0.206250,0.718750,0.050000,0.050000},{0.218750,0.718750,0.025000,0.025000},{0.218750,0.718750,0.050000,0.050000},{0.231250,0.718750,0.025000,0.025000},{0.231250,0.718750,0.050000,0.050000},{0.243750,0.718750,0.025000,0.025000},{0.243750,0.718750,0.050000,0.050000},{0.256250,0.718750,0.025000,0.025000},{0.256250,0.718750,0.050000,0.050000},{0.268750,0.718750,0.025000,0.025000},{0.268750,0.718750,0.050000,0.050000},{0.281250,0.718750,0.025000,0.025000},{0.281250,0.718750,0.050000,0.050000},{0.293750,0.718750,0.025000,0.025000},{0.293750,0.718750,0.050000,0.050000},{0.306250,0.718750,0.025000,0.025000},{0.306250,0.718750,0.050000,0.050000},{0.318750,0.718750,0.025000,0.025000},{0.318750,0.718750,0.050000,0.050000},{0.331250,0.718750,0.025000,0.025000},{0.331250,0.718750,0.050000,0.050000},{0.343750,0.718750,0.025000,0.025000},{0.343750,0.718750,0.050000,0.050000},{0.356250,0.718750,0.025000,0.025000},{0.356250,0.718750,0.050000,0.050000},{0.368750,0.718750,0.025000,0.025000},{0.368750,0.718750,0.050000,0.050000},{0.381250,0.718750,0.025000,0.025000},{0.381250,0.718750,0.050000,0.050000},{0.393750,0.718750,0.025000,0.025000},{0.393750,0.718750,0.050000,0.050000},{0.406250,0.718750,0.025000,0.025000},{0.406250,0.718750,0.050000,0.050000},{0.418750,0.718750,0.025000,0.025000},{0.418750,0.718750,0.050000,0.050000},{0.431250,0.718750,0.025000,0.025000},{0.431250,0.718750,0.050000,0.050000},{0.443750,0.718750,0.025000,0.025000},{0.443750,0.718750,0.050000,0.050000},{0.456250,0.718750,0.025000,0.025000},{0.456250,0.718750,0.050000,0.050000},{0.468750,0.718750,0.025000,0.025000},{0.468750,0.718750,0.050000,0.050000},{0.481250,0.718750,0.025000,0.025000},{0.481250,0.718750,0.050000,0.050000},{0.493750,0.718750,0.025000,0.025000},{0.493750,0.718750,0.050000,0.050000},{0.506250,0.718750,0.025000,0.025000},{0.506250,0.718750,0.050000,0.050000},{0.518750,0.718750,0.025000,0.025000},{0.518750,0.718750,0.050000,0.050000},{0.531250,0.718750,0.025000,0.025000},{0.531250,0.718750,0.050000,0.050000},{0.543750,0.718750,0.025000,0.025000},{0.543750,0.718750,0.050000,0.050000},{0.556250,0.718750,0.025000,0.025000},{0.556250,0.718750,0.050000,0.050000},{0.568750,0.718750,0.025000,0.025000},{0.568750,0.718750,0.050000,0.050000},{0.581250,0.718750,0.025000,0.025000},{0.581250,0.718750,0.050000,0.050000},{0.593750,0.718750,0.025000,0.025000},{0.593750,0.718750,0.050000,0.050000},{0.606250,0.718750,0.025000,0.025000},{0.606250,0.718750,0.050000,0.050000},{0.618750,0.718750,0.025000,0.025000},{0.618750,0.718750,0.050000,0.050000},{0.631250,0.718750,0.025000,0.025000},{0.631250,0.718750,0.050000,0.050000},{0.643750,0.718750,0.025000,0.025000},{0.643750,0.718750,0.050000,0.050000},{0.656250,0.718750,0.025000,0.025000},{0.656250,0.718750,0.050000,0.050000},{0.668750,0.718750,0.025000,0.025000},{0.668750,0.718750,0.050000,0.050000},{0.681250,0.718750,0.025000,0.025000},{0.681250,0.718750,0.050000,0.050000},{0.693750,0.718750,0.025000,0.025000},{0.693750,0.718750,0.050000,0.050000},{0.706250,0.718750,0.025000,0.025000},{0.706250,0.718750,0.050000,0.050000},{0.718750,0.718750,0.025000,0.025000},{0.718750,0.718750,0.050000,0.050000},{0.731250,0.718750,0.025000,0.025000},{0.731250,0.718750,0.050000,0.050000},{0.743750,0.718750,0.025000,0.025000},{0.743750,0.718750,0.050000,0.050000},{0.756250,0.718750,0.025000,0.025000},{0.756250,0.718750,0.050000,0.050000},{0.768750,0.718750,0.025000,0.025000},{0.768750,0.718750,0.050000,0.050000},{0.781250,0.718750,0.025000,0.025000},{0.781250,0.718750,0.050000,0.050000},{0.793750,0.718750,0.025000,0.025000},{0.793750,0.718750,0.050000,0.050000},{0.806250,0.718750,0.025000,0.025000},{0.806250,0.718750,0.050000,0.050000},{0.818750,0.718750,0.025000,0.025000},{0.818750,0.718750,0.050000,0.050000},{0.831250,0.718750,0.025000,0.025000},{0.831250,0.718750,0.050000,0.050000},{0.843750,0.718750,0.025000,0.025000},{0.843750,0.718750,0.050000,0.050000},{0.856250,0.718750,0.025000,0.025000},{0.856250,0.718750,0.050000,0.050000},{0.868750,0.718750,0.025000,0.025000},{0.868750,0.718750,0.050000,0.050000},{0.881250,0.718750,0.025000,0.025000},{0.881250,0.718750,0.050000,0.050000},{0.893750,0.718750,0.025000,0.025000},{0.893750,0.718750,0.050000,0.050000},{0.906250,0.718750,0.025000,0.025000},{0.906250,0.718750,0.050000,0.050000},{0.918750,0.718750,0.025000,0.025000},{0.918750,0.718750,0.050000,0.050000},{0.931250,0.718750,0.025000,0.025000},{0.931250,0.718750,0.050000,0.050000},{0.943750,0.718750,0.025000,0.025000},{0.943750,0.718750,0.050000,0.050000},{0.956250,0.718750,0.025000,0.025000},{0.956250,0.718750,0.050000,0.050000},{0.968750,0.718750,0.025000,0.025000},{0.968750,0.718750,0.050000,0.050000},{0.981250,0.718750,0.025000,0.025000},{0.981250,0.718750,0.050000,0.050000},{0.993750,0.718750,0.025000,0.025000},{0.993750,0.718750,0.050000,0.050000},{0.006250,0.731250,0.025000,0.025000},{0.006250,0.731250,0.050000,0.050000},{0.018750,0.731250,0.025000,0.025000},{0.018750,0.731250,0.050000,0.050000},{0.031250,0.731250,0.025000,0.025000},{0.031250,0.731250,0.050000,0.050000},{0.043750,0.731250,0.025000,0.025000},{0.043750,0.731250,0.050000,0.050000},{0.056250,0.731250,0.025000,0.025000},{0.056250,0.731250,0.050000,0.050000},{0.068750,0.731250,0.025000,0.025000},{0.068750,0.731250,0.050000,0.050000},{0.081250,0.731250,0.025000,0.025000},{0.081250,0.731250,0.050000,0.050000},{0.093750,0.731250,0.025000,0.025000},{0.093750,0.731250,0.050000,0.050000},{0.106250,0.731250,0.025000,0.025000},{0.106250,0.731250,0.050000,0.050000},{0.118750,0.731250,0.025000,0.025000},{0.118750,0.731250,0.050000,0.050000},{0.131250,0.731250,0.025000,0.025000},{0.131250,0.731250,0.050000,0.050000},{0.143750,0.731250,0.025000,0.025000},{0.143750,0.731250,0.050000,0.050000},{0.156250,0.731250,0.025000,0.025000},{0.156250,0.731250,0.050000,0.050000},{0.168750,0.731250,0.025000,0.025000},{0.168750,0.731250,0.050000,0.050000},{0.181250,0.731250,0.025000,0.025000},{0.181250,0.731250,0.050000,0.050000},{0.193750,0.731250,0.025000,0.025000},{0.193750,0.731250,0.050000,0.050000},{0.206250,0.731250,0.025000,0.025000},{0.206250,0.731250,0.050000,0.050000},{0.218750,0.731250,0.025000,0.025000},{0.218750,0.731250,0.050000,0.050000},{0.231250,0.731250,0.025000,0.025000},{0.231250,0.731250,0.050000,0.050000},{0.243750,0.731250,0.025000,0.025000},{0.243750,0.731250,0.050000,0.050000},{0.256250,0.731250,0.025000,0.025000},{0.256250,0.731250,0.050000,0.050000},{0.268750,0.731250,0.025000,0.025000},{0.268750,0.731250,0.050000,0.050000},{0.281250,0.731250,0.025000,0.025000},{0.281250,0.731250,0.050000,0.050000},{0.293750,0.731250,0.025000,0.025000},{0.293750,0.731250,0.050000,0.050000},{0.306250,0.731250,0.025000,0.025000},{0.306250,0.731250,0.050000,0.050000},{0.318750,0.731250,0.025000,0.025000},{0.318750,0.731250,0.050000,0.050000},{0.331250,0.731250,0.025000,0.025000},{0.331250,0.731250,0.050000,0.050000},{0.343750,0.731250,0.025000,0.025000},{0.343750,0.731250,0.050000,0.050000},{0.356250,0.731250,0.025000,0.025000},{0.356250,0.731250,0.050000,0.050000},{0.368750,0.731250,0.025000,0.025000},{0.368750,0.731250,0.050000,0.050000},{0.381250,0.731250,0.025000,0.025000},{0.381250,0.731250,0.050000,0.050000},{0.393750,0.731250,0.025000,0.025000},{0.393750,0.731250,0.050000,0.050000},{0.406250,0.731250,0.025000,0.025000},{0.406250,0.731250,0.050000,0.050000},{0.418750,0.731250,0.025000,0.025000},{0.418750,0.731250,0.050000,0.050000},{0.431250,0.731250,0.025000,0.025000},{0.431250,0.731250,0.050000,0.050000},{0.443750,0.731250,0.025000,0.025000},{0.443750,0.731250,0.050000,0.050000},{0.456250,0.731250,0.025000,0.025000},{0.456250,0.731250,0.050000,0.050000},{0.468750,0.731250,0.025000,0.025000},{0.468750,0.731250,0.050000,0.050000},{0.481250,0.731250,0.025000,0.025000},{0.481250,0.731250,0.050000,0.050000},{0.493750,0.731250,0.025000,0.025000},{0.493750,0.731250,0.050000,0.050000},{0.506250,0.731250,0.025000,0.025000},{0.506250,0.731250,0.050000,0.050000},{0.518750,0.731250,0.025000,0.025000},{0.518750,0.731250,0.050000,0.050000},{0.531250,0.731250,0.025000,0.025000},{0.531250,0.731250,0.050000,0.050000},{0.543750,0.731250,0.025000,0.025000},{0.543750,0.731250,0.050000,0.050000},{0.556250,0.731250,0.025000,0.025000},{0.556250,0.731250,0.050000,0.050000},{0.568750,0.731250,0.025000,0.025000},{0.568750,0.731250,0.050000,0.050000},{0.581250,0.731250,0.025000,0.025000},{0.581250,0.731250,0.050000,0.050000},{0.593750,0.731250,0.025000,0.025000},{0.593750,0.731250,0.050000,0.050000},{0.606250,0.731250,0.025000,0.025000},{0.606250,0.731250,0.050000,0.050000},{0.618750,0.731250,0.025000,0.025000},{0.618750,0.731250,0.050000,0.050000},{0.631250,0.731250,0.025000,0.025000},{0.631250,0.731250,0.050000,0.050000},{0.643750,0.731250,0.025000,0.025000},{0.643750,0.731250,0.050000,0.050000},{0.656250,0.731250,0.025000,0.025000},{0.656250,0.731250,0.050000,0.050000},{0.668750,0.731250,0.025000,0.025000},{0.668750,0.731250,0.050000,0.050000},{0.681250,0.731250,0.025000,0.025000},{0.681250,0.731250,0.050000,0.050000},{0.693750,0.731250,0.025000,0.025000},{0.693750,0.731250,0.050000,0.050000},{0.706250,0.731250,0.025000,0.025000},{0.706250,0.731250,0.050000,0.050000},{0.718750,0.731250,0.025000,0.025000},{0.718750,0.731250,0.050000,0.050000},{0.731250,0.731250,0.025000,0.025000},{0.731250,0.731250,0.050000,0.050000},{0.743750,0.731250,0.025000,0.025000},{0.743750,0.731250,0.050000,0.050000},{0.756250,0.731250,0.025000,0.025000},{0.756250,0.731250,0.050000,0.050000},{0.768750,0.731250,0.025000,0.025000},{0.768750,0.731250,0.050000,0.050000},{0.781250,0.731250,0.025000,0.025000},{0.781250,0.731250,0.050000,0.050000},{0.793750,0.731250,0.025000,0.025000},{0.793750,0.731250,0.050000,0.050000},{0.806250,0.731250,0.025000,0.025000},{0.806250,0.731250,0.050000,0.050000},{0.818750,0.731250,0.025000,0.025000},{0.818750,0.731250,0.050000,0.050000},{0.831250,0.731250,0.025000,0.025000},{0.831250,0.731250,0.050000,0.050000},{0.843750,0.731250,0.025000,0.025000},{0.843750,0.731250,0.050000,0.050000},{0.856250,0.731250,0.025000,0.025000},{0.856250,0.731250,0.050000,0.050000},{0.868750,0.731250,0.025000,0.025000},{0.868750,0.731250,0.050000,0.050000},{0.881250,0.731250,0.025000,0.025000},{0.881250,0.731250,0.050000,0.050000},{0.893750,0.731250,0.025000,0.025000},{0.893750,0.731250,0.050000,0.050000},{0.906250,0.731250,0.025000,0.025000},{0.906250,0.731250,0.050000,0.050000},{0.918750,0.731250,0.025000,0.025000},{0.918750,0.731250,0.050000,0.050000},{0.931250,0.731250,0.025000,0.025000},{0.931250,0.731250,0.050000,0.050000},{0.943750,0.731250,0.025000,0.025000},{0.943750,0.731250,0.050000,0.050000},{0.956250,0.731250,0.025000,0.025000},{0.956250,0.731250,0.050000,0.050000},{0.968750,0.731250,0.025000,0.025000},{0.968750,0.731250,0.050000,0.050000},{0.981250,0.731250,0.025000,0.025000},{0.981250,0.731250,0.050000,0.050000},{0.993750,0.731250,0.025000,0.025000},{0.993750,0.731250,0.050000,0.050000},{0.006250,0.743750,0.025000,0.025000},{0.006250,0.743750,0.050000,0.050000},{0.018750,0.743750,0.025000,0.025000},{0.018750,0.743750,0.050000,0.050000},{0.031250,0.743750,0.025000,0.025000},{0.031250,0.743750,0.050000,0.050000},{0.043750,0.743750,0.025000,0.025000},{0.043750,0.743750,0.050000,0.050000},{0.056250,0.743750,0.025000,0.025000},{0.056250,0.743750,0.050000,0.050000},{0.068750,0.743750,0.025000,0.025000},{0.068750,0.743750,0.050000,0.050000},{0.081250,0.743750,0.025000,0.025000},{0.081250,0.743750,0.050000,0.050000},{0.093750,0.743750,0.025000,0.025000},{0.093750,0.743750,0.050000,0.050000},{0.106250,0.743750,0.025000,0.025000},{0.106250,0.743750,0.050000,0.050000},{0.118750,0.743750,0.025000,0.025000},{0.118750,0.743750,0.050000,0.050000},{0.131250,0.743750,0.025000,0.025000},{0.131250,0.743750,0.050000,0.050000},{0.143750,0.743750,0.025000,0.025000},{0.143750,0.743750,0.050000,0.050000},{0.156250,0.743750,0.025000,0.025000},{0.156250,0.743750,0.050000,0.050000},{0.168750,0.743750,0.025000,0.025000},{0.168750,0.743750,0.050000,0.050000},{0.181250,0.743750,0.025000,0.025000},{0.181250,0.743750,0.050000,0.050000},{0.193750,0.743750,0.025000,0.025000},{0.193750,0.743750,0.050000,0.050000},{0.206250,0.743750,0.025000,0.025000},{0.206250,0.743750,0.050000,0.050000},{0.218750,0.743750,0.025000,0.025000},{0.218750,0.743750,0.050000,0.050000},{0.231250,0.743750,0.025000,0.025000},{0.231250,0.743750,0.050000,0.050000},{0.243750,0.743750,0.025000,0.025000},{0.243750,0.743750,0.050000,0.050000},{0.256250,0.743750,0.025000,0.025000},{0.256250,0.743750,0.050000,0.050000},{0.268750,0.743750,0.025000,0.025000},{0.268750,0.743750,0.050000,0.050000},{0.281250,0.743750,0.025000,0.025000},{0.281250,0.743750,0.050000,0.050000},{0.293750,0.743750,0.025000,0.025000},{0.293750,0.743750,0.050000,0.050000},{0.306250,0.743750,0.025000,0.025000},{0.306250,0.743750,0.050000,0.050000},{0.318750,0.743750,0.025000,0.025000},{0.318750,0.743750,0.050000,0.050000},{0.331250,0.743750,0.025000,0.025000},{0.331250,0.743750,0.050000,0.050000},{0.343750,0.743750,0.025000,0.025000},{0.343750,0.743750,0.050000,0.050000},{0.356250,0.743750,0.025000,0.025000},{0.356250,0.743750,0.050000,0.050000},{0.368750,0.743750,0.025000,0.025000},{0.368750,0.743750,0.050000,0.050000},{0.381250,0.743750,0.025000,0.025000},{0.381250,0.743750,0.050000,0.050000},{0.393750,0.743750,0.025000,0.025000},{0.393750,0.743750,0.050000,0.050000},{0.406250,0.743750,0.025000,0.025000},{0.406250,0.743750,0.050000,0.050000},{0.418750,0.743750,0.025000,0.025000},{0.418750,0.743750,0.050000,0.050000},{0.431250,0.743750,0.025000,0.025000},{0.431250,0.743750,0.050000,0.050000},{0.443750,0.743750,0.025000,0.025000},{0.443750,0.743750,0.050000,0.050000},{0.456250,0.743750,0.025000,0.025000},{0.456250,0.743750,0.050000,0.050000},{0.468750,0.743750,0.025000,0.025000},{0.468750,0.743750,0.050000,0.050000},{0.481250,0.743750,0.025000,0.025000},{0.481250,0.743750,0.050000,0.050000},{0.493750,0.743750,0.025000,0.025000},{0.493750,0.743750,0.050000,0.050000},{0.506250,0.743750,0.025000,0.025000},{0.506250,0.743750,0.050000,0.050000},{0.518750,0.743750,0.025000,0.025000},{0.518750,0.743750,0.050000,0.050000},{0.531250,0.743750,0.025000,0.025000},{0.531250,0.743750,0.050000,0.050000},{0.543750,0.743750,0.025000,0.025000},{0.543750,0.743750,0.050000,0.050000},{0.556250,0.743750,0.025000,0.025000},{0.556250,0.743750,0.050000,0.050000},{0.568750,0.743750,0.025000,0.025000},{0.568750,0.743750,0.050000,0.050000},{0.581250,0.743750,0.025000,0.025000},{0.581250,0.743750,0.050000,0.050000},{0.593750,0.743750,0.025000,0.025000},{0.593750,0.743750,0.050000,0.050000},{0.606250,0.743750,0.025000,0.025000},{0.606250,0.743750,0.050000,0.050000},{0.618750,0.743750,0.025000,0.025000},{0.618750,0.743750,0.050000,0.050000},{0.631250,0.743750,0.025000,0.025000},{0.631250,0.743750,0.050000,0.050000},{0.643750,0.743750,0.025000,0.025000},{0.643750,0.743750,0.050000,0.050000},{0.656250,0.743750,0.025000,0.025000},{0.656250,0.743750,0.050000,0.050000},{0.668750,0.743750,0.025000,0.025000},{0.668750,0.743750,0.050000,0.050000},{0.681250,0.743750,0.025000,0.025000},{0.681250,0.743750,0.050000,0.050000},{0.693750,0.743750,0.025000,0.025000},{0.693750,0.743750,0.050000,0.050000},{0.706250,0.743750,0.025000,0.025000},{0.706250,0.743750,0.050000,0.050000},{0.718750,0.743750,0.025000,0.025000},{0.718750,0.743750,0.050000,0.050000},{0.731250,0.743750,0.025000,0.025000},{0.731250,0.743750,0.050000,0.050000},{0.743750,0.743750,0.025000,0.025000},{0.743750,0.743750,0.050000,0.050000},{0.756250,0.743750,0.025000,0.025000},{0.756250,0.743750,0.050000,0.050000},{0.768750,0.743750,0.025000,0.025000},{0.768750,0.743750,0.050000,0.050000},{0.781250,0.743750,0.025000,0.025000},{0.781250,0.743750,0.050000,0.050000},{0.793750,0.743750,0.025000,0.025000},{0.793750,0.743750,0.050000,0.050000},{0.806250,0.743750,0.025000,0.025000},{0.806250,0.743750,0.050000,0.050000},{0.818750,0.743750,0.025000,0.025000},{0.818750,0.743750,0.050000,0.050000},{0.831250,0.743750,0.025000,0.025000},{0.831250,0.743750,0.050000,0.050000},{0.843750,0.743750,0.025000,0.025000},{0.843750,0.743750,0.050000,0.050000},{0.856250,0.743750,0.025000,0.025000},{0.856250,0.743750,0.050000,0.050000},{0.868750,0.743750,0.025000,0.025000},{0.868750,0.743750,0.050000,0.050000},{0.881250,0.743750,0.025000,0.025000},{0.881250,0.743750,0.050000,0.050000},{0.893750,0.743750,0.025000,0.025000},{0.893750,0.743750,0.050000,0.050000},{0.906250,0.743750,0.025000,0.025000},{0.906250,0.743750,0.050000,0.050000},{0.918750,0.743750,0.025000,0.025000},{0.918750,0.743750,0.050000,0.050000},{0.931250,0.743750,0.025000,0.025000},{0.931250,0.743750,0.050000,0.050000},{0.943750,0.743750,0.025000,0.025000},{0.943750,0.743750,0.050000,0.050000},{0.956250,0.743750,0.025000,0.025000},{0.956250,0.743750,0.050000,0.050000},{0.968750,0.743750,0.025000,0.025000},{0.968750,0.743750,0.050000,0.050000},{0.981250,0.743750,0.025000,0.025000},{0.981250,0.743750,0.050000,0.050000},{0.993750,0.743750,0.025000,0.025000},{0.993750,0.743750,0.050000,0.050000},{0.006250,0.756250,0.025000,0.025000},{0.006250,0.756250,0.050000,0.050000},{0.018750,0.756250,0.025000,0.025000},{0.018750,0.756250,0.050000,0.050000},{0.031250,0.756250,0.025000,0.025000},{0.031250,0.756250,0.050000,0.050000},{0.043750,0.756250,0.025000,0.025000},{0.043750,0.756250,0.050000,0.050000},{0.056250,0.756250,0.025000,0.025000},{0.056250,0.756250,0.050000,0.050000},{0.068750,0.756250,0.025000,0.025000},{0.068750,0.756250,0.050000,0.050000},{0.081250,0.756250,0.025000,0.025000},{0.081250,0.756250,0.050000,0.050000},{0.093750,0.756250,0.025000,0.025000},{0.093750,0.756250,0.050000,0.050000},{0.106250,0.756250,0.025000,0.025000},{0.106250,0.756250,0.050000,0.050000},{0.118750,0.756250,0.025000,0.025000},{0.118750,0.756250,0.050000,0.050000},{0.131250,0.756250,0.025000,0.025000},{0.131250,0.756250,0.050000,0.050000},{0.143750,0.756250,0.025000,0.025000},{0.143750,0.756250,0.050000,0.050000},{0.156250,0.756250,0.025000,0.025000},{0.156250,0.756250,0.050000,0.050000},{0.168750,0.756250,0.025000,0.025000},{0.168750,0.756250,0.050000,0.050000},{0.181250,0.756250,0.025000,0.025000},{0.181250,0.756250,0.050000,0.050000},{0.193750,0.756250,0.025000,0.025000},{0.193750,0.756250,0.050000,0.050000},{0.206250,0.756250,0.025000,0.025000},{0.206250,0.756250,0.050000,0.050000},{0.218750,0.756250,0.025000,0.025000},{0.218750,0.756250,0.050000,0.050000},{0.231250,0.756250,0.025000,0.025000},{0.231250,0.756250,0.050000,0.050000},{0.243750,0.756250,0.025000,0.025000},{0.243750,0.756250,0.050000,0.050000},{0.256250,0.756250,0.025000,0.025000},{0.256250,0.756250,0.050000,0.050000},{0.268750,0.756250,0.025000,0.025000},{0.268750,0.756250,0.050000,0.050000},{0.281250,0.756250,0.025000,0.025000},{0.281250,0.756250,0.050000,0.050000},{0.293750,0.756250,0.025000,0.025000},{0.293750,0.756250,0.050000,0.050000},{0.306250,0.756250,0.025000,0.025000},{0.306250,0.756250,0.050000,0.050000},{0.318750,0.756250,0.025000,0.025000},{0.318750,0.756250,0.050000,0.050000},{0.331250,0.756250,0.025000,0.025000},{0.331250,0.756250,0.050000,0.050000},{0.343750,0.756250,0.025000,0.025000},{0.343750,0.756250,0.050000,0.050000},{0.356250,0.756250,0.025000,0.025000},{0.356250,0.756250,0.050000,0.050000},{0.368750,0.756250,0.025000,0.025000},{0.368750,0.756250,0.050000,0.050000},{0.381250,0.756250,0.025000,0.025000},{0.381250,0.756250,0.050000,0.050000},{0.393750,0.756250,0.025000,0.025000},{0.393750,0.756250,0.050000,0.050000},{0.406250,0.756250,0.025000,0.025000},{0.406250,0.756250,0.050000,0.050000},{0.418750,0.756250,0.025000,0.025000},{0.418750,0.756250,0.050000,0.050000},{0.431250,0.756250,0.025000,0.025000},{0.431250,0.756250,0.050000,0.050000},{0.443750,0.756250,0.025000,0.025000},{0.443750,0.756250,0.050000,0.050000},{0.456250,0.756250,0.025000,0.025000},{0.456250,0.756250,0.050000,0.050000},{0.468750,0.756250,0.025000,0.025000},{0.468750,0.756250,0.050000,0.050000},{0.481250,0.756250,0.025000,0.025000},{0.481250,0.756250,0.050000,0.050000},{0.493750,0.756250,0.025000,0.025000},{0.493750,0.756250,0.050000,0.050000},{0.506250,0.756250,0.025000,0.025000},{0.506250,0.756250,0.050000,0.050000},{0.518750,0.756250,0.025000,0.025000},{0.518750,0.756250,0.050000,0.050000},{0.531250,0.756250,0.025000,0.025000},{0.531250,0.756250,0.050000,0.050000},{0.543750,0.756250,0.025000,0.025000},{0.543750,0.756250,0.050000,0.050000},{0.556250,0.756250,0.025000,0.025000},{0.556250,0.756250,0.050000,0.050000},{0.568750,0.756250,0.025000,0.025000},{0.568750,0.756250,0.050000,0.050000},{0.581250,0.756250,0.025000,0.025000},{0.581250,0.756250,0.050000,0.050000},{0.593750,0.756250,0.025000,0.025000},{0.593750,0.756250,0.050000,0.050000},{0.606250,0.756250,0.025000,0.025000},{0.606250,0.756250,0.050000,0.050000},{0.618750,0.756250,0.025000,0.025000},{0.618750,0.756250,0.050000,0.050000},{0.631250,0.756250,0.025000,0.025000},{0.631250,0.756250,0.050000,0.050000},{0.643750,0.756250,0.025000,0.025000},{0.643750,0.756250,0.050000,0.050000},{0.656250,0.756250,0.025000,0.025000},{0.656250,0.756250,0.050000,0.050000},{0.668750,0.756250,0.025000,0.025000},{0.668750,0.756250,0.050000,0.050000},{0.681250,0.756250,0.025000,0.025000},{0.681250,0.756250,0.050000,0.050000},{0.693750,0.756250,0.025000,0.025000},{0.693750,0.756250,0.050000,0.050000},{0.706250,0.756250,0.025000,0.025000},{0.706250,0.756250,0.050000,0.050000},{0.718750,0.756250,0.025000,0.025000},{0.718750,0.756250,0.050000,0.050000},{0.731250,0.756250,0.025000,0.025000},{0.731250,0.756250,0.050000,0.050000},{0.743750,0.756250,0.025000,0.025000},{0.743750,0.756250,0.050000,0.050000},{0.756250,0.756250,0.025000,0.025000},{0.756250,0.756250,0.050000,0.050000},{0.768750,0.756250,0.025000,0.025000},{0.768750,0.756250,0.050000,0.050000},{0.781250,0.756250,0.025000,0.025000},{0.781250,0.756250,0.050000,0.050000},{0.793750,0.756250,0.025000,0.025000},{0.793750,0.756250,0.050000,0.050000},{0.806250,0.756250,0.025000,0.025000},{0.806250,0.756250,0.050000,0.050000},{0.818750,0.756250,0.025000,0.025000},{0.818750,0.756250,0.050000,0.050000},{0.831250,0.756250,0.025000,0.025000},{0.831250,0.756250,0.050000,0.050000},{0.843750,0.756250,0.025000,0.025000},{0.843750,0.756250,0.050000,0.050000},{0.856250,0.756250,0.025000,0.025000},{0.856250,0.756250,0.050000,0.050000},{0.868750,0.756250,0.025000,0.025000},{0.868750,0.756250,0.050000,0.050000},{0.881250,0.756250,0.025000,0.025000},{0.881250,0.756250,0.050000,0.050000},{0.893750,0.756250,0.025000,0.025000},{0.893750,0.756250,0.050000,0.050000},{0.906250,0.756250,0.025000,0.025000},{0.906250,0.756250,0.050000,0.050000},{0.918750,0.756250,0.025000,0.025000},{0.918750,0.756250,0.050000,0.050000},{0.931250,0.756250,0.025000,0.025000},{0.931250,0.756250,0.050000,0.050000},{0.943750,0.756250,0.025000,0.025000},{0.943750,0.756250,0.050000,0.050000},{0.956250,0.756250,0.025000,0.025000},{0.956250,0.756250,0.050000,0.050000},{0.968750,0.756250,0.025000,0.025000},{0.968750,0.756250,0.050000,0.050000},{0.981250,0.756250,0.025000,0.025000},{0.981250,0.756250,0.050000,0.050000},{0.993750,0.756250,0.025000,0.025000},{0.993750,0.756250,0.050000,0.050000},{0.006250,0.768750,0.025000,0.025000},{0.006250,0.768750,0.050000,0.050000},{0.018750,0.768750,0.025000,0.025000},{0.018750,0.768750,0.050000,0.050000},{0.031250,0.768750,0.025000,0.025000},{0.031250,0.768750,0.050000,0.050000},{0.043750,0.768750,0.025000,0.025000},{0.043750,0.768750,0.050000,0.050000},{0.056250,0.768750,0.025000,0.025000},{0.056250,0.768750,0.050000,0.050000},{0.068750,0.768750,0.025000,0.025000},{0.068750,0.768750,0.050000,0.050000},{0.081250,0.768750,0.025000,0.025000},{0.081250,0.768750,0.050000,0.050000},{0.093750,0.768750,0.025000,0.025000},{0.093750,0.768750,0.050000,0.050000},{0.106250,0.768750,0.025000,0.025000},{0.106250,0.768750,0.050000,0.050000},{0.118750,0.768750,0.025000,0.025000},{0.118750,0.768750,0.050000,0.050000},{0.131250,0.768750,0.025000,0.025000},{0.131250,0.768750,0.050000,0.050000},{0.143750,0.768750,0.025000,0.025000},{0.143750,0.768750,0.050000,0.050000},{0.156250,0.768750,0.025000,0.025000},{0.156250,0.768750,0.050000,0.050000},{0.168750,0.768750,0.025000,0.025000},{0.168750,0.768750,0.050000,0.050000},{0.181250,0.768750,0.025000,0.025000},{0.181250,0.768750,0.050000,0.050000},{0.193750,0.768750,0.025000,0.025000},{0.193750,0.768750,0.050000,0.050000},{0.206250,0.768750,0.025000,0.025000},{0.206250,0.768750,0.050000,0.050000},{0.218750,0.768750,0.025000,0.025000},{0.218750,0.768750,0.050000,0.050000},{0.231250,0.768750,0.025000,0.025000},{0.231250,0.768750,0.050000,0.050000},{0.243750,0.768750,0.025000,0.025000},{0.243750,0.768750,0.050000,0.050000},{0.256250,0.768750,0.025000,0.025000},{0.256250,0.768750,0.050000,0.050000},{0.268750,0.768750,0.025000,0.025000},{0.268750,0.768750,0.050000,0.050000},{0.281250,0.768750,0.025000,0.025000},{0.281250,0.768750,0.050000,0.050000},{0.293750,0.768750,0.025000,0.025000},{0.293750,0.768750,0.050000,0.050000},{0.306250,0.768750,0.025000,0.025000},{0.306250,0.768750,0.050000,0.050000},{0.318750,0.768750,0.025000,0.025000},{0.318750,0.768750,0.050000,0.050000},{0.331250,0.768750,0.025000,0.025000},{0.331250,0.768750,0.050000,0.050000},{0.343750,0.768750,0.025000,0.025000},{0.343750,0.768750,0.050000,0.050000},{0.356250,0.768750,0.025000,0.025000},{0.356250,0.768750,0.050000,0.050000},{0.368750,0.768750,0.025000,0.025000},{0.368750,0.768750,0.050000,0.050000},{0.381250,0.768750,0.025000,0.025000},{0.381250,0.768750,0.050000,0.050000},{0.393750,0.768750,0.025000,0.025000},{0.393750,0.768750,0.050000,0.050000},{0.406250,0.768750,0.025000,0.025000},{0.406250,0.768750,0.050000,0.050000},{0.418750,0.768750,0.025000,0.025000},{0.418750,0.768750,0.050000,0.050000},{0.431250,0.768750,0.025000,0.025000},{0.431250,0.768750,0.050000,0.050000},{0.443750,0.768750,0.025000,0.025000},{0.443750,0.768750,0.050000,0.050000},{0.456250,0.768750,0.025000,0.025000},{0.456250,0.768750,0.050000,0.050000},{0.468750,0.768750,0.025000,0.025000},{0.468750,0.768750,0.050000,0.050000},{0.481250,0.768750,0.025000,0.025000},{0.481250,0.768750,0.050000,0.050000},{0.493750,0.768750,0.025000,0.025000},{0.493750,0.768750,0.050000,0.050000},{0.506250,0.768750,0.025000,0.025000},{0.506250,0.768750,0.050000,0.050000},{0.518750,0.768750,0.025000,0.025000},{0.518750,0.768750,0.050000,0.050000},{0.531250,0.768750,0.025000,0.025000},{0.531250,0.768750,0.050000,0.050000},{0.543750,0.768750,0.025000,0.025000},{0.543750,0.768750,0.050000,0.050000},{0.556250,0.768750,0.025000,0.025000},{0.556250,0.768750,0.050000,0.050000},{0.568750,0.768750,0.025000,0.025000},{0.568750,0.768750,0.050000,0.050000},{0.581250,0.768750,0.025000,0.025000},{0.581250,0.768750,0.050000,0.050000},{0.593750,0.768750,0.025000,0.025000},{0.593750,0.768750,0.050000,0.050000},{0.606250,0.768750,0.025000,0.025000},{0.606250,0.768750,0.050000,0.050000},{0.618750,0.768750,0.025000,0.025000},{0.618750,0.768750,0.050000,0.050000},{0.631250,0.768750,0.025000,0.025000},{0.631250,0.768750,0.050000,0.050000},{0.643750,0.768750,0.025000,0.025000},{0.643750,0.768750,0.050000,0.050000},{0.656250,0.768750,0.025000,0.025000},{0.656250,0.768750,0.050000,0.050000},{0.668750,0.768750,0.025000,0.025000},{0.668750,0.768750,0.050000,0.050000},{0.681250,0.768750,0.025000,0.025000},{0.681250,0.768750,0.050000,0.050000},{0.693750,0.768750,0.025000,0.025000},{0.693750,0.768750,0.050000,0.050000},{0.706250,0.768750,0.025000,0.025000},{0.706250,0.768750,0.050000,0.050000},{0.718750,0.768750,0.025000,0.025000},{0.718750,0.768750,0.050000,0.050000},{0.731250,0.768750,0.025000,0.025000},{0.731250,0.768750,0.050000,0.050000},{0.743750,0.768750,0.025000,0.025000},{0.743750,0.768750,0.050000,0.050000},{0.756250,0.768750,0.025000,0.025000},{0.756250,0.768750,0.050000,0.050000},{0.768750,0.768750,0.025000,0.025000},{0.768750,0.768750,0.050000,0.050000},{0.781250,0.768750,0.025000,0.025000},{0.781250,0.768750,0.050000,0.050000},{0.793750,0.768750,0.025000,0.025000},{0.793750,0.768750,0.050000,0.050000},{0.806250,0.768750,0.025000,0.025000},{0.806250,0.768750,0.050000,0.050000},{0.818750,0.768750,0.025000,0.025000},{0.818750,0.768750,0.050000,0.050000},{0.831250,0.768750,0.025000,0.025000},{0.831250,0.768750,0.050000,0.050000},{0.843750,0.768750,0.025000,0.025000},{0.843750,0.768750,0.050000,0.050000},{0.856250,0.768750,0.025000,0.025000},{0.856250,0.768750,0.050000,0.050000},{0.868750,0.768750,0.025000,0.025000},{0.868750,0.768750,0.050000,0.050000},{0.881250,0.768750,0.025000,0.025000},{0.881250,0.768750,0.050000,0.050000},{0.893750,0.768750,0.025000,0.025000},{0.893750,0.768750,0.050000,0.050000},{0.906250,0.768750,0.025000,0.025000},{0.906250,0.768750,0.050000,0.050000},{0.918750,0.768750,0.025000,0.025000},{0.918750,0.768750,0.050000,0.050000},{0.931250,0.768750,0.025000,0.025000},{0.931250,0.768750,0.050000,0.050000},{0.943750,0.768750,0.025000,0.025000},{0.943750,0.768750,0.050000,0.050000},{0.956250,0.768750,0.025000,0.025000},{0.956250,0.768750,0.050000,0.050000},{0.968750,0.768750,0.025000,0.025000},{0.968750,0.768750,0.050000,0.050000},{0.981250,0.768750,0.025000,0.025000},{0.981250,0.768750,0.050000,0.050000},{0.993750,0.768750,0.025000,0.025000},{0.993750,0.768750,0.050000,0.050000},{0.006250,0.781250,0.025000,0.025000},{0.006250,0.781250,0.050000,0.050000},{0.018750,0.781250,0.025000,0.025000},{0.018750,0.781250,0.050000,0.050000},{0.031250,0.781250,0.025000,0.025000},{0.031250,0.781250,0.050000,0.050000},{0.043750,0.781250,0.025000,0.025000},{0.043750,0.781250,0.050000,0.050000},{0.056250,0.781250,0.025000,0.025000},{0.056250,0.781250,0.050000,0.050000},{0.068750,0.781250,0.025000,0.025000},{0.068750,0.781250,0.050000,0.050000},{0.081250,0.781250,0.025000,0.025000},{0.081250,0.781250,0.050000,0.050000},{0.093750,0.781250,0.025000,0.025000},{0.093750,0.781250,0.050000,0.050000},{0.106250,0.781250,0.025000,0.025000},{0.106250,0.781250,0.050000,0.050000},{0.118750,0.781250,0.025000,0.025000},{0.118750,0.781250,0.050000,0.050000},{0.131250,0.781250,0.025000,0.025000},{0.131250,0.781250,0.050000,0.050000},{0.143750,0.781250,0.025000,0.025000},{0.143750,0.781250,0.050000,0.050000},{0.156250,0.781250,0.025000,0.025000},{0.156250,0.781250,0.050000,0.050000},{0.168750,0.781250,0.025000,0.025000},{0.168750,0.781250,0.050000,0.050000},{0.181250,0.781250,0.025000,0.025000},{0.181250,0.781250,0.050000,0.050000},{0.193750,0.781250,0.025000,0.025000},{0.193750,0.781250,0.050000,0.050000},{0.206250,0.781250,0.025000,0.025000},{0.206250,0.781250,0.050000,0.050000},{0.218750,0.781250,0.025000,0.025000},{0.218750,0.781250,0.050000,0.050000},{0.231250,0.781250,0.025000,0.025000},{0.231250,0.781250,0.050000,0.050000},{0.243750,0.781250,0.025000,0.025000},{0.243750,0.781250,0.050000,0.050000},{0.256250,0.781250,0.025000,0.025000},{0.256250,0.781250,0.050000,0.050000},{0.268750,0.781250,0.025000,0.025000},{0.268750,0.781250,0.050000,0.050000},{0.281250,0.781250,0.025000,0.025000},{0.281250,0.781250,0.050000,0.050000},{0.293750,0.781250,0.025000,0.025000},{0.293750,0.781250,0.050000,0.050000},{0.306250,0.781250,0.025000,0.025000},{0.306250,0.781250,0.050000,0.050000},{0.318750,0.781250,0.025000,0.025000},{0.318750,0.781250,0.050000,0.050000},{0.331250,0.781250,0.025000,0.025000},{0.331250,0.781250,0.050000,0.050000},{0.343750,0.781250,0.025000,0.025000},{0.343750,0.781250,0.050000,0.050000},{0.356250,0.781250,0.025000,0.025000},{0.356250,0.781250,0.050000,0.050000},{0.368750,0.781250,0.025000,0.025000},{0.368750,0.781250,0.050000,0.050000},{0.381250,0.781250,0.025000,0.025000},{0.381250,0.781250,0.050000,0.050000},{0.393750,0.781250,0.025000,0.025000},{0.393750,0.781250,0.050000,0.050000},{0.406250,0.781250,0.025000,0.025000},{0.406250,0.781250,0.050000,0.050000},{0.418750,0.781250,0.025000,0.025000},{0.418750,0.781250,0.050000,0.050000},{0.431250,0.781250,0.025000,0.025000},{0.431250,0.781250,0.050000,0.050000},{0.443750,0.781250,0.025000,0.025000},{0.443750,0.781250,0.050000,0.050000},{0.456250,0.781250,0.025000,0.025000},{0.456250,0.781250,0.050000,0.050000},{0.468750,0.781250,0.025000,0.025000},{0.468750,0.781250,0.050000,0.050000},{0.481250,0.781250,0.025000,0.025000},{0.481250,0.781250,0.050000,0.050000},{0.493750,0.781250,0.025000,0.025000},{0.493750,0.781250,0.050000,0.050000},{0.506250,0.781250,0.025000,0.025000},{0.506250,0.781250,0.050000,0.050000},{0.518750,0.781250,0.025000,0.025000},{0.518750,0.781250,0.050000,0.050000},{0.531250,0.781250,0.025000,0.025000},{0.531250,0.781250,0.050000,0.050000},{0.543750,0.781250,0.025000,0.025000},{0.543750,0.781250,0.050000,0.050000},{0.556250,0.781250,0.025000,0.025000},{0.556250,0.781250,0.050000,0.050000},{0.568750,0.781250,0.025000,0.025000},{0.568750,0.781250,0.050000,0.050000},{0.581250,0.781250,0.025000,0.025000},{0.581250,0.781250,0.050000,0.050000},{0.593750,0.781250,0.025000,0.025000},{0.593750,0.781250,0.050000,0.050000},{0.606250,0.781250,0.025000,0.025000},{0.606250,0.781250,0.050000,0.050000},{0.618750,0.781250,0.025000,0.025000},{0.618750,0.781250,0.050000,0.050000},{0.631250,0.781250,0.025000,0.025000},{0.631250,0.781250,0.050000,0.050000},{0.643750,0.781250,0.025000,0.025000},{0.643750,0.781250,0.050000,0.050000},{0.656250,0.781250,0.025000,0.025000},{0.656250,0.781250,0.050000,0.050000},{0.668750,0.781250,0.025000,0.025000},{0.668750,0.781250,0.050000,0.050000},{0.681250,0.781250,0.025000,0.025000},{0.681250,0.781250,0.050000,0.050000},{0.693750,0.781250,0.025000,0.025000},{0.693750,0.781250,0.050000,0.050000},{0.706250,0.781250,0.025000,0.025000},{0.706250,0.781250,0.050000,0.050000},{0.718750,0.781250,0.025000,0.025000},{0.718750,0.781250,0.050000,0.050000},{0.731250,0.781250,0.025000,0.025000},{0.731250,0.781250,0.050000,0.050000},{0.743750,0.781250,0.025000,0.025000},{0.743750,0.781250,0.050000,0.050000},{0.756250,0.781250,0.025000,0.025000},{0.756250,0.781250,0.050000,0.050000},{0.768750,0.781250,0.025000,0.025000},{0.768750,0.781250,0.050000,0.050000},{0.781250,0.781250,0.025000,0.025000},{0.781250,0.781250,0.050000,0.050000},{0.793750,0.781250,0.025000,0.025000},{0.793750,0.781250,0.050000,0.050000},{0.806250,0.781250,0.025000,0.025000},{0.806250,0.781250,0.050000,0.050000},{0.818750,0.781250,0.025000,0.025000},{0.818750,0.781250,0.050000,0.050000},{0.831250,0.781250,0.025000,0.025000},{0.831250,0.781250,0.050000,0.050000},{0.843750,0.781250,0.025000,0.025000},{0.843750,0.781250,0.050000,0.050000},{0.856250,0.781250,0.025000,0.025000},{0.856250,0.781250,0.050000,0.050000},{0.868750,0.781250,0.025000,0.025000},{0.868750,0.781250,0.050000,0.050000},{0.881250,0.781250,0.025000,0.025000},{0.881250,0.781250,0.050000,0.050000},{0.893750,0.781250,0.025000,0.025000},{0.893750,0.781250,0.050000,0.050000},{0.906250,0.781250,0.025000,0.025000},{0.906250,0.781250,0.050000,0.050000},{0.918750,0.781250,0.025000,0.025000},{0.918750,0.781250,0.050000,0.050000},{0.931250,0.781250,0.025000,0.025000},{0.931250,0.781250,0.050000,0.050000},{0.943750,0.781250,0.025000,0.025000},{0.943750,0.781250,0.050000,0.050000},{0.956250,0.781250,0.025000,0.025000},{0.956250,0.781250,0.050000,0.050000},{0.968750,0.781250,0.025000,0.025000},{0.968750,0.781250,0.050000,0.050000},{0.981250,0.781250,0.025000,0.025000},{0.981250,0.781250,0.050000,0.050000},{0.993750,0.781250,0.025000,0.025000},{0.993750,0.781250,0.050000,0.050000},{0.006250,0.793750,0.025000,0.025000},{0.006250,0.793750,0.050000,0.050000},{0.018750,0.793750,0.025000,0.025000},{0.018750,0.793750,0.050000,0.050000},{0.031250,0.793750,0.025000,0.025000},{0.031250,0.793750,0.050000,0.050000},{0.043750,0.793750,0.025000,0.025000},{0.043750,0.793750,0.050000,0.050000},{0.056250,0.793750,0.025000,0.025000},{0.056250,0.793750,0.050000,0.050000},{0.068750,0.793750,0.025000,0.025000},{0.068750,0.793750,0.050000,0.050000},{0.081250,0.793750,0.025000,0.025000},{0.081250,0.793750,0.050000,0.050000},{0.093750,0.793750,0.025000,0.025000},{0.093750,0.793750,0.050000,0.050000},{0.106250,0.793750,0.025000,0.025000},{0.106250,0.793750,0.050000,0.050000},{0.118750,0.793750,0.025000,0.025000},{0.118750,0.793750,0.050000,0.050000},{0.131250,0.793750,0.025000,0.025000},{0.131250,0.793750,0.050000,0.050000},{0.143750,0.793750,0.025000,0.025000},{0.143750,0.793750,0.050000,0.050000},{0.156250,0.793750,0.025000,0.025000},{0.156250,0.793750,0.050000,0.050000},{0.168750,0.793750,0.025000,0.025000},{0.168750,0.793750,0.050000,0.050000},{0.181250,0.793750,0.025000,0.025000},{0.181250,0.793750,0.050000,0.050000},{0.193750,0.793750,0.025000,0.025000},{0.193750,0.793750,0.050000,0.050000},{0.206250,0.793750,0.025000,0.025000},{0.206250,0.793750,0.050000,0.050000},{0.218750,0.793750,0.025000,0.025000},{0.218750,0.793750,0.050000,0.050000},{0.231250,0.793750,0.025000,0.025000},{0.231250,0.793750,0.050000,0.050000},{0.243750,0.793750,0.025000,0.025000},{0.243750,0.793750,0.050000,0.050000},{0.256250,0.793750,0.025000,0.025000},{0.256250,0.793750,0.050000,0.050000},{0.268750,0.793750,0.025000,0.025000},{0.268750,0.793750,0.050000,0.050000},{0.281250,0.793750,0.025000,0.025000},{0.281250,0.793750,0.050000,0.050000},{0.293750,0.793750,0.025000,0.025000},{0.293750,0.793750,0.050000,0.050000},{0.306250,0.793750,0.025000,0.025000},{0.306250,0.793750,0.050000,0.050000},{0.318750,0.793750,0.025000,0.025000},{0.318750,0.793750,0.050000,0.050000},{0.331250,0.793750,0.025000,0.025000},{0.331250,0.793750,0.050000,0.050000},{0.343750,0.793750,0.025000,0.025000},{0.343750,0.793750,0.050000,0.050000},{0.356250,0.793750,0.025000,0.025000},{0.356250,0.793750,0.050000,0.050000},{0.368750,0.793750,0.025000,0.025000},{0.368750,0.793750,0.050000,0.050000},{0.381250,0.793750,0.025000,0.025000},{0.381250,0.793750,0.050000,0.050000},{0.393750,0.793750,0.025000,0.025000},{0.393750,0.793750,0.050000,0.050000},{0.406250,0.793750,0.025000,0.025000},{0.406250,0.793750,0.050000,0.050000},{0.418750,0.793750,0.025000,0.025000},{0.418750,0.793750,0.050000,0.050000},{0.431250,0.793750,0.025000,0.025000},{0.431250,0.793750,0.050000,0.050000},{0.443750,0.793750,0.025000,0.025000},{0.443750,0.793750,0.050000,0.050000},{0.456250,0.793750,0.025000,0.025000},{0.456250,0.793750,0.050000,0.050000},{0.468750,0.793750,0.025000,0.025000},{0.468750,0.793750,0.050000,0.050000},{0.481250,0.793750,0.025000,0.025000},{0.481250,0.793750,0.050000,0.050000},{0.493750,0.793750,0.025000,0.025000},{0.493750,0.793750,0.050000,0.050000},{0.506250,0.793750,0.025000,0.025000},{0.506250,0.793750,0.050000,0.050000},{0.518750,0.793750,0.025000,0.025000},{0.518750,0.793750,0.050000,0.050000},{0.531250,0.793750,0.025000,0.025000},{0.531250,0.793750,0.050000,0.050000},{0.543750,0.793750,0.025000,0.025000},{0.543750,0.793750,0.050000,0.050000},{0.556250,0.793750,0.025000,0.025000},{0.556250,0.793750,0.050000,0.050000},{0.568750,0.793750,0.025000,0.025000},{0.568750,0.793750,0.050000,0.050000},{0.581250,0.793750,0.025000,0.025000},{0.581250,0.793750,0.050000,0.050000},{0.593750,0.793750,0.025000,0.025000},{0.593750,0.793750,0.050000,0.050000},{0.606250,0.793750,0.025000,0.025000},{0.606250,0.793750,0.050000,0.050000},{0.618750,0.793750,0.025000,0.025000},{0.618750,0.793750,0.050000,0.050000},{0.631250,0.793750,0.025000,0.025000},{0.631250,0.793750,0.050000,0.050000},{0.643750,0.793750,0.025000,0.025000},{0.643750,0.793750,0.050000,0.050000},{0.656250,0.793750,0.025000,0.025000},{0.656250,0.793750,0.050000,0.050000},{0.668750,0.793750,0.025000,0.025000},{0.668750,0.793750,0.050000,0.050000},{0.681250,0.793750,0.025000,0.025000},{0.681250,0.793750,0.050000,0.050000},{0.693750,0.793750,0.025000,0.025000},{0.693750,0.793750,0.050000,0.050000},{0.706250,0.793750,0.025000,0.025000},{0.706250,0.793750,0.050000,0.050000},{0.718750,0.793750,0.025000,0.025000},{0.718750,0.793750,0.050000,0.050000},{0.731250,0.793750,0.025000,0.025000},{0.731250,0.793750,0.050000,0.050000},{0.743750,0.793750,0.025000,0.025000},{0.743750,0.793750,0.050000,0.050000},{0.756250,0.793750,0.025000,0.025000},{0.756250,0.793750,0.050000,0.050000},{0.768750,0.793750,0.025000,0.025000},{0.768750,0.793750,0.050000,0.050000},{0.781250,0.793750,0.025000,0.025000},{0.781250,0.793750,0.050000,0.050000},{0.793750,0.793750,0.025000,0.025000},{0.793750,0.793750,0.050000,0.050000},{0.806250,0.793750,0.025000,0.025000},{0.806250,0.793750,0.050000,0.050000},{0.818750,0.793750,0.025000,0.025000},{0.818750,0.793750,0.050000,0.050000},{0.831250,0.793750,0.025000,0.025000},{0.831250,0.793750,0.050000,0.050000},{0.843750,0.793750,0.025000,0.025000},{0.843750,0.793750,0.050000,0.050000},{0.856250,0.793750,0.025000,0.025000},{0.856250,0.793750,0.050000,0.050000},{0.868750,0.793750,0.025000,0.025000},{0.868750,0.793750,0.050000,0.050000},{0.881250,0.793750,0.025000,0.025000},{0.881250,0.793750,0.050000,0.050000},{0.893750,0.793750,0.025000,0.025000},{0.893750,0.793750,0.050000,0.050000},{0.906250,0.793750,0.025000,0.025000},{0.906250,0.793750,0.050000,0.050000},{0.918750,0.793750,0.025000,0.025000},{0.918750,0.793750,0.050000,0.050000},{0.931250,0.793750,0.025000,0.025000},{0.931250,0.793750,0.050000,0.050000},{0.943750,0.793750,0.025000,0.025000},{0.943750,0.793750,0.050000,0.050000},{0.956250,0.793750,0.025000,0.025000},{0.956250,0.793750,0.050000,0.050000},{0.968750,0.793750,0.025000,0.025000},{0.968750,0.793750,0.050000,0.050000},{0.981250,0.793750,0.025000,0.025000},{0.981250,0.793750,0.050000,0.050000},{0.993750,0.793750,0.025000,0.025000},{0.993750,0.793750,0.050000,0.050000},{0.006250,0.806250,0.025000,0.025000},{0.006250,0.806250,0.050000,0.050000},{0.018750,0.806250,0.025000,0.025000},{0.018750,0.806250,0.050000,0.050000},{0.031250,0.806250,0.025000,0.025000},{0.031250,0.806250,0.050000,0.050000},{0.043750,0.806250,0.025000,0.025000},{0.043750,0.806250,0.050000,0.050000},{0.056250,0.806250,0.025000,0.025000},{0.056250,0.806250,0.050000,0.050000},{0.068750,0.806250,0.025000,0.025000},{0.068750,0.806250,0.050000,0.050000},{0.081250,0.806250,0.025000,0.025000},{0.081250,0.806250,0.050000,0.050000},{0.093750,0.806250,0.025000,0.025000},{0.093750,0.806250,0.050000,0.050000},{0.106250,0.806250,0.025000,0.025000},{0.106250,0.806250,0.050000,0.050000},{0.118750,0.806250,0.025000,0.025000},{0.118750,0.806250,0.050000,0.050000},{0.131250,0.806250,0.025000,0.025000},{0.131250,0.806250,0.050000,0.050000},{0.143750,0.806250,0.025000,0.025000},{0.143750,0.806250,0.050000,0.050000},{0.156250,0.806250,0.025000,0.025000},{0.156250,0.806250,0.050000,0.050000},{0.168750,0.806250,0.025000,0.025000},{0.168750,0.806250,0.050000,0.050000},{0.181250,0.806250,0.025000,0.025000},{0.181250,0.806250,0.050000,0.050000},{0.193750,0.806250,0.025000,0.025000},{0.193750,0.806250,0.050000,0.050000},{0.206250,0.806250,0.025000,0.025000},{0.206250,0.806250,0.050000,0.050000},{0.218750,0.806250,0.025000,0.025000},{0.218750,0.806250,0.050000,0.050000},{0.231250,0.806250,0.025000,0.025000},{0.231250,0.806250,0.050000,0.050000},{0.243750,0.806250,0.025000,0.025000},{0.243750,0.806250,0.050000,0.050000},{0.256250,0.806250,0.025000,0.025000},{0.256250,0.806250,0.050000,0.050000},{0.268750,0.806250,0.025000,0.025000},{0.268750,0.806250,0.050000,0.050000},{0.281250,0.806250,0.025000,0.025000},{0.281250,0.806250,0.050000,0.050000},{0.293750,0.806250,0.025000,0.025000},{0.293750,0.806250,0.050000,0.050000},{0.306250,0.806250,0.025000,0.025000},{0.306250,0.806250,0.050000,0.050000},{0.318750,0.806250,0.025000,0.025000},{0.318750,0.806250,0.050000,0.050000},{0.331250,0.806250,0.025000,0.025000},{0.331250,0.806250,0.050000,0.050000},{0.343750,0.806250,0.025000,0.025000},{0.343750,0.806250,0.050000,0.050000},{0.356250,0.806250,0.025000,0.025000},{0.356250,0.806250,0.050000,0.050000},{0.368750,0.806250,0.025000,0.025000},{0.368750,0.806250,0.050000,0.050000},{0.381250,0.806250,0.025000,0.025000},{0.381250,0.806250,0.050000,0.050000},{0.393750,0.806250,0.025000,0.025000},{0.393750,0.806250,0.050000,0.050000},{0.406250,0.806250,0.025000,0.025000},{0.406250,0.806250,0.050000,0.050000},{0.418750,0.806250,0.025000,0.025000},{0.418750,0.806250,0.050000,0.050000},{0.431250,0.806250,0.025000,0.025000},{0.431250,0.806250,0.050000,0.050000},{0.443750,0.806250,0.025000,0.025000},{0.443750,0.806250,0.050000,0.050000},{0.456250,0.806250,0.025000,0.025000},{0.456250,0.806250,0.050000,0.050000},{0.468750,0.806250,0.025000,0.025000},{0.468750,0.806250,0.050000,0.050000},{0.481250,0.806250,0.025000,0.025000},{0.481250,0.806250,0.050000,0.050000},{0.493750,0.806250,0.025000,0.025000},{0.493750,0.806250,0.050000,0.050000},{0.506250,0.806250,0.025000,0.025000},{0.506250,0.806250,0.050000,0.050000},{0.518750,0.806250,0.025000,0.025000},{0.518750,0.806250,0.050000,0.050000},{0.531250,0.806250,0.025000,0.025000},{0.531250,0.806250,0.050000,0.050000},{0.543750,0.806250,0.025000,0.025000},{0.543750,0.806250,0.050000,0.050000},{0.556250,0.806250,0.025000,0.025000},{0.556250,0.806250,0.050000,0.050000},{0.568750,0.806250,0.025000,0.025000},{0.568750,0.806250,0.050000,0.050000},{0.581250,0.806250,0.025000,0.025000},{0.581250,0.806250,0.050000,0.050000},{0.593750,0.806250,0.025000,0.025000},{0.593750,0.806250,0.050000,0.050000},{0.606250,0.806250,0.025000,0.025000},{0.606250,0.806250,0.050000,0.050000},{0.618750,0.806250,0.025000,0.025000},{0.618750,0.806250,0.050000,0.050000},{0.631250,0.806250,0.025000,0.025000},{0.631250,0.806250,0.050000,0.050000},{0.643750,0.806250,0.025000,0.025000},{0.643750,0.806250,0.050000,0.050000},{0.656250,0.806250,0.025000,0.025000},{0.656250,0.806250,0.050000,0.050000},{0.668750,0.806250,0.025000,0.025000},{0.668750,0.806250,0.050000,0.050000},{0.681250,0.806250,0.025000,0.025000},{0.681250,0.806250,0.050000,0.050000},{0.693750,0.806250,0.025000,0.025000},{0.693750,0.806250,0.050000,0.050000},{0.706250,0.806250,0.025000,0.025000},{0.706250,0.806250,0.050000,0.050000},{0.718750,0.806250,0.025000,0.025000},{0.718750,0.806250,0.050000,0.050000},{0.731250,0.806250,0.025000,0.025000},{0.731250,0.806250,0.050000,0.050000},{0.743750,0.806250,0.025000,0.025000},{0.743750,0.806250,0.050000,0.050000},{0.756250,0.806250,0.025000,0.025000},{0.756250,0.806250,0.050000,0.050000},{0.768750,0.806250,0.025000,0.025000},{0.768750,0.806250,0.050000,0.050000},{0.781250,0.806250,0.025000,0.025000},{0.781250,0.806250,0.050000,0.050000},{0.793750,0.806250,0.025000,0.025000},{0.793750,0.806250,0.050000,0.050000},{0.806250,0.806250,0.025000,0.025000},{0.806250,0.806250,0.050000,0.050000},{0.818750,0.806250,0.025000,0.025000},{0.818750,0.806250,0.050000,0.050000},{0.831250,0.806250,0.025000,0.025000},{0.831250,0.806250,0.050000,0.050000},{0.843750,0.806250,0.025000,0.025000},{0.843750,0.806250,0.050000,0.050000},{0.856250,0.806250,0.025000,0.025000},{0.856250,0.806250,0.050000,0.050000},{0.868750,0.806250,0.025000,0.025000},{0.868750,0.806250,0.050000,0.050000},{0.881250,0.806250,0.025000,0.025000},{0.881250,0.806250,0.050000,0.050000},{0.893750,0.806250,0.025000,0.025000},{0.893750,0.806250,0.050000,0.050000},{0.906250,0.806250,0.025000,0.025000},{0.906250,0.806250,0.050000,0.050000},{0.918750,0.806250,0.025000,0.025000},{0.918750,0.806250,0.050000,0.050000},{0.931250,0.806250,0.025000,0.025000},{0.931250,0.806250,0.050000,0.050000},{0.943750,0.806250,0.025000,0.025000},{0.943750,0.806250,0.050000,0.050000},{0.956250,0.806250,0.025000,0.025000},{0.956250,0.806250,0.050000,0.050000},{0.968750,0.806250,0.025000,0.025000},{0.968750,0.806250,0.050000,0.050000},{0.981250,0.806250,0.025000,0.025000},{0.981250,0.806250,0.050000,0.050000},{0.993750,0.806250,0.025000,0.025000},{0.993750,0.806250,0.050000,0.050000},{0.006250,0.818750,0.025000,0.025000},{0.006250,0.818750,0.050000,0.050000},{0.018750,0.818750,0.025000,0.025000},{0.018750,0.818750,0.050000,0.050000},{0.031250,0.818750,0.025000,0.025000},{0.031250,0.818750,0.050000,0.050000},{0.043750,0.818750,0.025000,0.025000},{0.043750,0.818750,0.050000,0.050000},{0.056250,0.818750,0.025000,0.025000},{0.056250,0.818750,0.050000,0.050000},{0.068750,0.818750,0.025000,0.025000},{0.068750,0.818750,0.050000,0.050000},{0.081250,0.818750,0.025000,0.025000},{0.081250,0.818750,0.050000,0.050000},{0.093750,0.818750,0.025000,0.025000},{0.093750,0.818750,0.050000,0.050000},{0.106250,0.818750,0.025000,0.025000},{0.106250,0.818750,0.050000,0.050000},{0.118750,0.818750,0.025000,0.025000},{0.118750,0.818750,0.050000,0.050000},{0.131250,0.818750,0.025000,0.025000},{0.131250,0.818750,0.050000,0.050000},{0.143750,0.818750,0.025000,0.025000},{0.143750,0.818750,0.050000,0.050000},{0.156250,0.818750,0.025000,0.025000},{0.156250,0.818750,0.050000,0.050000},{0.168750,0.818750,0.025000,0.025000},{0.168750,0.818750,0.050000,0.050000},{0.181250,0.818750,0.025000,0.025000},{0.181250,0.818750,0.050000,0.050000},{0.193750,0.818750,0.025000,0.025000},{0.193750,0.818750,0.050000,0.050000},{0.206250,0.818750,0.025000,0.025000},{0.206250,0.818750,0.050000,0.050000},{0.218750,0.818750,0.025000,0.025000},{0.218750,0.818750,0.050000,0.050000},{0.231250,0.818750,0.025000,0.025000},{0.231250,0.818750,0.050000,0.050000},{0.243750,0.818750,0.025000,0.025000},{0.243750,0.818750,0.050000,0.050000},{0.256250,0.818750,0.025000,0.025000},{0.256250,0.818750,0.050000,0.050000},{0.268750,0.818750,0.025000,0.025000},{0.268750,0.818750,0.050000,0.050000},{0.281250,0.818750,0.025000,0.025000},{0.281250,0.818750,0.050000,0.050000},{0.293750,0.818750,0.025000,0.025000},{0.293750,0.818750,0.050000,0.050000},{0.306250,0.818750,0.025000,0.025000},{0.306250,0.818750,0.050000,0.050000},{0.318750,0.818750,0.025000,0.025000},{0.318750,0.818750,0.050000,0.050000},{0.331250,0.818750,0.025000,0.025000},{0.331250,0.818750,0.050000,0.050000},{0.343750,0.818750,0.025000,0.025000},{0.343750,0.818750,0.050000,0.050000},{0.356250,0.818750,0.025000,0.025000},{0.356250,0.818750,0.050000,0.050000},{0.368750,0.818750,0.025000,0.025000},{0.368750,0.818750,0.050000,0.050000},{0.381250,0.818750,0.025000,0.025000},{0.381250,0.818750,0.050000,0.050000},{0.393750,0.818750,0.025000,0.025000},{0.393750,0.818750,0.050000,0.050000},{0.406250,0.818750,0.025000,0.025000},{0.406250,0.818750,0.050000,0.050000},{0.418750,0.818750,0.025000,0.025000},{0.418750,0.818750,0.050000,0.050000},{0.431250,0.818750,0.025000,0.025000},{0.431250,0.818750,0.050000,0.050000},{0.443750,0.818750,0.025000,0.025000},{0.443750,0.818750,0.050000,0.050000},{0.456250,0.818750,0.025000,0.025000},{0.456250,0.818750,0.050000,0.050000},{0.468750,0.818750,0.025000,0.025000},{0.468750,0.818750,0.050000,0.050000},{0.481250,0.818750,0.025000,0.025000},{0.481250,0.818750,0.050000,0.050000},{0.493750,0.818750,0.025000,0.025000},{0.493750,0.818750,0.050000,0.050000},{0.506250,0.818750,0.025000,0.025000},{0.506250,0.818750,0.050000,0.050000},{0.518750,0.818750,0.025000,0.025000},{0.518750,0.818750,0.050000,0.050000},{0.531250,0.818750,0.025000,0.025000},{0.531250,0.818750,0.050000,0.050000},{0.543750,0.818750,0.025000,0.025000},{0.543750,0.818750,0.050000,0.050000},{0.556250,0.818750,0.025000,0.025000},{0.556250,0.818750,0.050000,0.050000},{0.568750,0.818750,0.025000,0.025000},{0.568750,0.818750,0.050000,0.050000},{0.581250,0.818750,0.025000,0.025000},{0.581250,0.818750,0.050000,0.050000},{0.593750,0.818750,0.025000,0.025000},{0.593750,0.818750,0.050000,0.050000},{0.606250,0.818750,0.025000,0.025000},{0.606250,0.818750,0.050000,0.050000},{0.618750,0.818750,0.025000,0.025000},{0.618750,0.818750,0.050000,0.050000},{0.631250,0.818750,0.025000,0.025000},{0.631250,0.818750,0.050000,0.050000},{0.643750,0.818750,0.025000,0.025000},{0.643750,0.818750,0.050000,0.050000},{0.656250,0.818750,0.025000,0.025000},{0.656250,0.818750,0.050000,0.050000},{0.668750,0.818750,0.025000,0.025000},{0.668750,0.818750,0.050000,0.050000},{0.681250,0.818750,0.025000,0.025000},{0.681250,0.818750,0.050000,0.050000},{0.693750,0.818750,0.025000,0.025000},{0.693750,0.818750,0.050000,0.050000},{0.706250,0.818750,0.025000,0.025000},{0.706250,0.818750,0.050000,0.050000},{0.718750,0.818750,0.025000,0.025000},{0.718750,0.818750,0.050000,0.050000},{0.731250,0.818750,0.025000,0.025000},{0.731250,0.818750,0.050000,0.050000},{0.743750,0.818750,0.025000,0.025000},{0.743750,0.818750,0.050000,0.050000},{0.756250,0.818750,0.025000,0.025000},{0.756250,0.818750,0.050000,0.050000},{0.768750,0.818750,0.025000,0.025000},{0.768750,0.818750,0.050000,0.050000},{0.781250,0.818750,0.025000,0.025000},{0.781250,0.818750,0.050000,0.050000},{0.793750,0.818750,0.025000,0.025000},{0.793750,0.818750,0.050000,0.050000},{0.806250,0.818750,0.025000,0.025000},{0.806250,0.818750,0.050000,0.050000},{0.818750,0.818750,0.025000,0.025000},{0.818750,0.818750,0.050000,0.050000},{0.831250,0.818750,0.025000,0.025000},{0.831250,0.818750,0.050000,0.050000},{0.843750,0.818750,0.025000,0.025000},{0.843750,0.818750,0.050000,0.050000},{0.856250,0.818750,0.025000,0.025000},{0.856250,0.818750,0.050000,0.050000},{0.868750,0.818750,0.025000,0.025000},{0.868750,0.818750,0.050000,0.050000},{0.881250,0.818750,0.025000,0.025000},{0.881250,0.818750,0.050000,0.050000},{0.893750,0.818750,0.025000,0.025000},{0.893750,0.818750,0.050000,0.050000},{0.906250,0.818750,0.025000,0.025000},{0.906250,0.818750,0.050000,0.050000},{0.918750,0.818750,0.025000,0.025000},{0.918750,0.818750,0.050000,0.050000},{0.931250,0.818750,0.025000,0.025000},{0.931250,0.818750,0.050000,0.050000},{0.943750,0.818750,0.025000,0.025000},{0.943750,0.818750,0.050000,0.050000},{0.956250,0.818750,0.025000,0.025000},{0.956250,0.818750,0.050000,0.050000},{0.968750,0.818750,0.025000,0.025000},{0.968750,0.818750,0.050000,0.050000},{0.981250,0.818750,0.025000,0.025000},{0.981250,0.818750,0.050000,0.050000},{0.993750,0.818750,0.025000,0.025000},{0.993750,0.818750,0.050000,0.050000},{0.006250,0.831250,0.025000,0.025000},{0.006250,0.831250,0.050000,0.050000},{0.018750,0.831250,0.025000,0.025000},{0.018750,0.831250,0.050000,0.050000},{0.031250,0.831250,0.025000,0.025000},{0.031250,0.831250,0.050000,0.050000},{0.043750,0.831250,0.025000,0.025000},{0.043750,0.831250,0.050000,0.050000},{0.056250,0.831250,0.025000,0.025000},{0.056250,0.831250,0.050000,0.050000},{0.068750,0.831250,0.025000,0.025000},{0.068750,0.831250,0.050000,0.050000},{0.081250,0.831250,0.025000,0.025000},{0.081250,0.831250,0.050000,0.050000},{0.093750,0.831250,0.025000,0.025000},{0.093750,0.831250,0.050000,0.050000},{0.106250,0.831250,0.025000,0.025000},{0.106250,0.831250,0.050000,0.050000},{0.118750,0.831250,0.025000,0.025000},{0.118750,0.831250,0.050000,0.050000},{0.131250,0.831250,0.025000,0.025000},{0.131250,0.831250,0.050000,0.050000},{0.143750,0.831250,0.025000,0.025000},{0.143750,0.831250,0.050000,0.050000},{0.156250,0.831250,0.025000,0.025000},{0.156250,0.831250,0.050000,0.050000},{0.168750,0.831250,0.025000,0.025000},{0.168750,0.831250,0.050000,0.050000},{0.181250,0.831250,0.025000,0.025000},{0.181250,0.831250,0.050000,0.050000},{0.193750,0.831250,0.025000,0.025000},{0.193750,0.831250,0.050000,0.050000},{0.206250,0.831250,0.025000,0.025000},{0.206250,0.831250,0.050000,0.050000},{0.218750,0.831250,0.025000,0.025000},{0.218750,0.831250,0.050000,0.050000},{0.231250,0.831250,0.025000,0.025000},{0.231250,0.831250,0.050000,0.050000},{0.243750,0.831250,0.025000,0.025000},{0.243750,0.831250,0.050000,0.050000},{0.256250,0.831250,0.025000,0.025000},{0.256250,0.831250,0.050000,0.050000},{0.268750,0.831250,0.025000,0.025000},{0.268750,0.831250,0.050000,0.050000},{0.281250,0.831250,0.025000,0.025000},{0.281250,0.831250,0.050000,0.050000},{0.293750,0.831250,0.025000,0.025000},{0.293750,0.831250,0.050000,0.050000},{0.306250,0.831250,0.025000,0.025000},{0.306250,0.831250,0.050000,0.050000},{0.318750,0.831250,0.025000,0.025000},{0.318750,0.831250,0.050000,0.050000},{0.331250,0.831250,0.025000,0.025000},{0.331250,0.831250,0.050000,0.050000},{0.343750,0.831250,0.025000,0.025000},{0.343750,0.831250,0.050000,0.050000},{0.356250,0.831250,0.025000,0.025000},{0.356250,0.831250,0.050000,0.050000},{0.368750,0.831250,0.025000,0.025000},{0.368750,0.831250,0.050000,0.050000},{0.381250,0.831250,0.025000,0.025000},{0.381250,0.831250,0.050000,0.050000},{0.393750,0.831250,0.025000,0.025000},{0.393750,0.831250,0.050000,0.050000},{0.406250,0.831250,0.025000,0.025000},{0.406250,0.831250,0.050000,0.050000},{0.418750,0.831250,0.025000,0.025000},{0.418750,0.831250,0.050000,0.050000},{0.431250,0.831250,0.025000,0.025000},{0.431250,0.831250,0.050000,0.050000},{0.443750,0.831250,0.025000,0.025000},{0.443750,0.831250,0.050000,0.050000},{0.456250,0.831250,0.025000,0.025000},{0.456250,0.831250,0.050000,0.050000},{0.468750,0.831250,0.025000,0.025000},{0.468750,0.831250,0.050000,0.050000},{0.481250,0.831250,0.025000,0.025000},{0.481250,0.831250,0.050000,0.050000},{0.493750,0.831250,0.025000,0.025000},{0.493750,0.831250,0.050000,0.050000},{0.506250,0.831250,0.025000,0.025000},{0.506250,0.831250,0.050000,0.050000},{0.518750,0.831250,0.025000,0.025000},{0.518750,0.831250,0.050000,0.050000},{0.531250,0.831250,0.025000,0.025000},{0.531250,0.831250,0.050000,0.050000},{0.543750,0.831250,0.025000,0.025000},{0.543750,0.831250,0.050000,0.050000},{0.556250,0.831250,0.025000,0.025000},{0.556250,0.831250,0.050000,0.050000},{0.568750,0.831250,0.025000,0.025000},{0.568750,0.831250,0.050000,0.050000},{0.581250,0.831250,0.025000,0.025000},{0.581250,0.831250,0.050000,0.050000},{0.593750,0.831250,0.025000,0.025000},{0.593750,0.831250,0.050000,0.050000},{0.606250,0.831250,0.025000,0.025000},{0.606250,0.831250,0.050000,0.050000},{0.618750,0.831250,0.025000,0.025000},{0.618750,0.831250,0.050000,0.050000},{0.631250,0.831250,0.025000,0.025000},{0.631250,0.831250,0.050000,0.050000},{0.643750,0.831250,0.025000,0.025000},{0.643750,0.831250,0.050000,0.050000},{0.656250,0.831250,0.025000,0.025000},{0.656250,0.831250,0.050000,0.050000},{0.668750,0.831250,0.025000,0.025000},{0.668750,0.831250,0.050000,0.050000},{0.681250,0.831250,0.025000,0.025000},{0.681250,0.831250,0.050000,0.050000},{0.693750,0.831250,0.025000,0.025000},{0.693750,0.831250,0.050000,0.050000},{0.706250,0.831250,0.025000,0.025000},{0.706250,0.831250,0.050000,0.050000},{0.718750,0.831250,0.025000,0.025000},{0.718750,0.831250,0.050000,0.050000},{0.731250,0.831250,0.025000,0.025000},{0.731250,0.831250,0.050000,0.050000},{0.743750,0.831250,0.025000,0.025000},{0.743750,0.831250,0.050000,0.050000},{0.756250,0.831250,0.025000,0.025000},{0.756250,0.831250,0.050000,0.050000},{0.768750,0.831250,0.025000,0.025000},{0.768750,0.831250,0.050000,0.050000},{0.781250,0.831250,0.025000,0.025000},{0.781250,0.831250,0.050000,0.050000},{0.793750,0.831250,0.025000,0.025000},{0.793750,0.831250,0.050000,0.050000},{0.806250,0.831250,0.025000,0.025000},{0.806250,0.831250,0.050000,0.050000},{0.818750,0.831250,0.025000,0.025000},{0.818750,0.831250,0.050000,0.050000},{0.831250,0.831250,0.025000,0.025000},{0.831250,0.831250,0.050000,0.050000},{0.843750,0.831250,0.025000,0.025000},{0.843750,0.831250,0.050000,0.050000},{0.856250,0.831250,0.025000,0.025000},{0.856250,0.831250,0.050000,0.050000},{0.868750,0.831250,0.025000,0.025000},{0.868750,0.831250,0.050000,0.050000},{0.881250,0.831250,0.025000,0.025000},{0.881250,0.831250,0.050000,0.050000},{0.893750,0.831250,0.025000,0.025000},{0.893750,0.831250,0.050000,0.050000},{0.906250,0.831250,0.025000,0.025000},{0.906250,0.831250,0.050000,0.050000},{0.918750,0.831250,0.025000,0.025000},{0.918750,0.831250,0.050000,0.050000},{0.931250,0.831250,0.025000,0.025000},{0.931250,0.831250,0.050000,0.050000},{0.943750,0.831250,0.025000,0.025000},{0.943750,0.831250,0.050000,0.050000},{0.956250,0.831250,0.025000,0.025000},{0.956250,0.831250,0.050000,0.050000},{0.968750,0.831250,0.025000,0.025000},{0.968750,0.831250,0.050000,0.050000},{0.981250,0.831250,0.025000,0.025000},{0.981250,0.831250,0.050000,0.050000},{0.993750,0.831250,0.025000,0.025000},{0.993750,0.831250,0.050000,0.050000},{0.006250,0.843750,0.025000,0.025000},{0.006250,0.843750,0.050000,0.050000},{0.018750,0.843750,0.025000,0.025000},{0.018750,0.843750,0.050000,0.050000},{0.031250,0.843750,0.025000,0.025000},{0.031250,0.843750,0.050000,0.050000},{0.043750,0.843750,0.025000,0.025000},{0.043750,0.843750,0.050000,0.050000},{0.056250,0.843750,0.025000,0.025000},{0.056250,0.843750,0.050000,0.050000},{0.068750,0.843750,0.025000,0.025000},{0.068750,0.843750,0.050000,0.050000},{0.081250,0.843750,0.025000,0.025000},{0.081250,0.843750,0.050000,0.050000},{0.093750,0.843750,0.025000,0.025000},{0.093750,0.843750,0.050000,0.050000},{0.106250,0.843750,0.025000,0.025000},{0.106250,0.843750,0.050000,0.050000},{0.118750,0.843750,0.025000,0.025000},{0.118750,0.843750,0.050000,0.050000},{0.131250,0.843750,0.025000,0.025000},{0.131250,0.843750,0.050000,0.050000},{0.143750,0.843750,0.025000,0.025000},{0.143750,0.843750,0.050000,0.050000},{0.156250,0.843750,0.025000,0.025000},{0.156250,0.843750,0.050000,0.050000},{0.168750,0.843750,0.025000,0.025000},{0.168750,0.843750,0.050000,0.050000},{0.181250,0.843750,0.025000,0.025000},{0.181250,0.843750,0.050000,0.050000},{0.193750,0.843750,0.025000,0.025000},{0.193750,0.843750,0.050000,0.050000},{0.206250,0.843750,0.025000,0.025000},{0.206250,0.843750,0.050000,0.050000},{0.218750,0.843750,0.025000,0.025000},{0.218750,0.843750,0.050000,0.050000},{0.231250,0.843750,0.025000,0.025000},{0.231250,0.843750,0.050000,0.050000},{0.243750,0.843750,0.025000,0.025000},{0.243750,0.843750,0.050000,0.050000},{0.256250,0.843750,0.025000,0.025000},{0.256250,0.843750,0.050000,0.050000},{0.268750,0.843750,0.025000,0.025000},{0.268750,0.843750,0.050000,0.050000},{0.281250,0.843750,0.025000,0.025000},{0.281250,0.843750,0.050000,0.050000},{0.293750,0.843750,0.025000,0.025000},{0.293750,0.843750,0.050000,0.050000},{0.306250,0.843750,0.025000,0.025000},{0.306250,0.843750,0.050000,0.050000},{0.318750,0.843750,0.025000,0.025000},{0.318750,0.843750,0.050000,0.050000},{0.331250,0.843750,0.025000,0.025000},{0.331250,0.843750,0.050000,0.050000},{0.343750,0.843750,0.025000,0.025000},{0.343750,0.843750,0.050000,0.050000},{0.356250,0.843750,0.025000,0.025000},{0.356250,0.843750,0.050000,0.050000},{0.368750,0.843750,0.025000,0.025000},{0.368750,0.843750,0.050000,0.050000},{0.381250,0.843750,0.025000,0.025000},{0.381250,0.843750,0.050000,0.050000},{0.393750,0.843750,0.025000,0.025000},{0.393750,0.843750,0.050000,0.050000},{0.406250,0.843750,0.025000,0.025000},{0.406250,0.843750,0.050000,0.050000},{0.418750,0.843750,0.025000,0.025000},{0.418750,0.843750,0.050000,0.050000},{0.431250,0.843750,0.025000,0.025000},{0.431250,0.843750,0.050000,0.050000},{0.443750,0.843750,0.025000,0.025000},{0.443750,0.843750,0.050000,0.050000},{0.456250,0.843750,0.025000,0.025000},{0.456250,0.843750,0.050000,0.050000},{0.468750,0.843750,0.025000,0.025000},{0.468750,0.843750,0.050000,0.050000},{0.481250,0.843750,0.025000,0.025000},{0.481250,0.843750,0.050000,0.050000},{0.493750,0.843750,0.025000,0.025000},{0.493750,0.843750,0.050000,0.050000},{0.506250,0.843750,0.025000,0.025000},{0.506250,0.843750,0.050000,0.050000},{0.518750,0.843750,0.025000,0.025000},{0.518750,0.843750,0.050000,0.050000},{0.531250,0.843750,0.025000,0.025000},{0.531250,0.843750,0.050000,0.050000},{0.543750,0.843750,0.025000,0.025000},{0.543750,0.843750,0.050000,0.050000},{0.556250,0.843750,0.025000,0.025000},{0.556250,0.843750,0.050000,0.050000},{0.568750,0.843750,0.025000,0.025000},{0.568750,0.843750,0.050000,0.050000},{0.581250,0.843750,0.025000,0.025000},{0.581250,0.843750,0.050000,0.050000},{0.593750,0.843750,0.025000,0.025000},{0.593750,0.843750,0.050000,0.050000},{0.606250,0.843750,0.025000,0.025000},{0.606250,0.843750,0.050000,0.050000},{0.618750,0.843750,0.025000,0.025000},{0.618750,0.843750,0.050000,0.050000},{0.631250,0.843750,0.025000,0.025000},{0.631250,0.843750,0.050000,0.050000},{0.643750,0.843750,0.025000,0.025000},{0.643750,0.843750,0.050000,0.050000},{0.656250,0.843750,0.025000,0.025000},{0.656250,0.843750,0.050000,0.050000},{0.668750,0.843750,0.025000,0.025000},{0.668750,0.843750,0.050000,0.050000},{0.681250,0.843750,0.025000,0.025000},{0.681250,0.843750,0.050000,0.050000},{0.693750,0.843750,0.025000,0.025000},{0.693750,0.843750,0.050000,0.050000},{0.706250,0.843750,0.025000,0.025000},{0.706250,0.843750,0.050000,0.050000},{0.718750,0.843750,0.025000,0.025000},{0.718750,0.843750,0.050000,0.050000},{0.731250,0.843750,0.025000,0.025000},{0.731250,0.843750,0.050000,0.050000},{0.743750,0.843750,0.025000,0.025000},{0.743750,0.843750,0.050000,0.050000},{0.756250,0.843750,0.025000,0.025000},{0.756250,0.843750,0.050000,0.050000},{0.768750,0.843750,0.025000,0.025000},{0.768750,0.843750,0.050000,0.050000},{0.781250,0.843750,0.025000,0.025000},{0.781250,0.843750,0.050000,0.050000},{0.793750,0.843750,0.025000,0.025000},{0.793750,0.843750,0.050000,0.050000},{0.806250,0.843750,0.025000,0.025000},{0.806250,0.843750,0.050000,0.050000},{0.818750,0.843750,0.025000,0.025000},{0.818750,0.843750,0.050000,0.050000},{0.831250,0.843750,0.025000,0.025000},{0.831250,0.843750,0.050000,0.050000},{0.843750,0.843750,0.025000,0.025000},{0.843750,0.843750,0.050000,0.050000},{0.856250,0.843750,0.025000,0.025000},{0.856250,0.843750,0.050000,0.050000},{0.868750,0.843750,0.025000,0.025000},{0.868750,0.843750,0.050000,0.050000},{0.881250,0.843750,0.025000,0.025000},{0.881250,0.843750,0.050000,0.050000},{0.893750,0.843750,0.025000,0.025000},{0.893750,0.843750,0.050000,0.050000},{0.906250,0.843750,0.025000,0.025000},{0.906250,0.843750,0.050000,0.050000},{0.918750,0.843750,0.025000,0.025000},{0.918750,0.843750,0.050000,0.050000},{0.931250,0.843750,0.025000,0.025000},{0.931250,0.843750,0.050000,0.050000},{0.943750,0.843750,0.025000,0.025000},{0.943750,0.843750,0.050000,0.050000},{0.956250,0.843750,0.025000,0.025000},{0.956250,0.843750,0.050000,0.050000},{0.968750,0.843750,0.025000,0.025000},{0.968750,0.843750,0.050000,0.050000},{0.981250,0.843750,0.025000,0.025000},{0.981250,0.843750,0.050000,0.050000},{0.993750,0.843750,0.025000,0.025000},{0.993750,0.843750,0.050000,0.050000},{0.006250,0.856250,0.025000,0.025000},{0.006250,0.856250,0.050000,0.050000},{0.018750,0.856250,0.025000,0.025000},{0.018750,0.856250,0.050000,0.050000},{0.031250,0.856250,0.025000,0.025000},{0.031250,0.856250,0.050000,0.050000},{0.043750,0.856250,0.025000,0.025000},{0.043750,0.856250,0.050000,0.050000},{0.056250,0.856250,0.025000,0.025000},{0.056250,0.856250,0.050000,0.050000},{0.068750,0.856250,0.025000,0.025000},{0.068750,0.856250,0.050000,0.050000},{0.081250,0.856250,0.025000,0.025000},{0.081250,0.856250,0.050000,0.050000},{0.093750,0.856250,0.025000,0.025000},{0.093750,0.856250,0.050000,0.050000},{0.106250,0.856250,0.025000,0.025000},{0.106250,0.856250,0.050000,0.050000},{0.118750,0.856250,0.025000,0.025000},{0.118750,0.856250,0.050000,0.050000},{0.131250,0.856250,0.025000,0.025000},{0.131250,0.856250,0.050000,0.050000},{0.143750,0.856250,0.025000,0.025000},{0.143750,0.856250,0.050000,0.050000},{0.156250,0.856250,0.025000,0.025000},{0.156250,0.856250,0.050000,0.050000},{0.168750,0.856250,0.025000,0.025000},{0.168750,0.856250,0.050000,0.050000},{0.181250,0.856250,0.025000,0.025000},{0.181250,0.856250,0.050000,0.050000},{0.193750,0.856250,0.025000,0.025000},{0.193750,0.856250,0.050000,0.050000},{0.206250,0.856250,0.025000,0.025000},{0.206250,0.856250,0.050000,0.050000},{0.218750,0.856250,0.025000,0.025000},{0.218750,0.856250,0.050000,0.050000},{0.231250,0.856250,0.025000,0.025000},{0.231250,0.856250,0.050000,0.050000},{0.243750,0.856250,0.025000,0.025000},{0.243750,0.856250,0.050000,0.050000},{0.256250,0.856250,0.025000,0.025000},{0.256250,0.856250,0.050000,0.050000},{0.268750,0.856250,0.025000,0.025000},{0.268750,0.856250,0.050000,0.050000},{0.281250,0.856250,0.025000,0.025000},{0.281250,0.856250,0.050000,0.050000},{0.293750,0.856250,0.025000,0.025000},{0.293750,0.856250,0.050000,0.050000},{0.306250,0.856250,0.025000,0.025000},{0.306250,0.856250,0.050000,0.050000},{0.318750,0.856250,0.025000,0.025000},{0.318750,0.856250,0.050000,0.050000},{0.331250,0.856250,0.025000,0.025000},{0.331250,0.856250,0.050000,0.050000},{0.343750,0.856250,0.025000,0.025000},{0.343750,0.856250,0.050000,0.050000},{0.356250,0.856250,0.025000,0.025000},{0.356250,0.856250,0.050000,0.050000},{0.368750,0.856250,0.025000,0.025000},{0.368750,0.856250,0.050000,0.050000},{0.381250,0.856250,0.025000,0.025000},{0.381250,0.856250,0.050000,0.050000},{0.393750,0.856250,0.025000,0.025000},{0.393750,0.856250,0.050000,0.050000},{0.406250,0.856250,0.025000,0.025000},{0.406250,0.856250,0.050000,0.050000},{0.418750,0.856250,0.025000,0.025000},{0.418750,0.856250,0.050000,0.050000},{0.431250,0.856250,0.025000,0.025000},{0.431250,0.856250,0.050000,0.050000},{0.443750,0.856250,0.025000,0.025000},{0.443750,0.856250,0.050000,0.050000},{0.456250,0.856250,0.025000,0.025000},{0.456250,0.856250,0.050000,0.050000},{0.468750,0.856250,0.025000,0.025000},{0.468750,0.856250,0.050000,0.050000},{0.481250,0.856250,0.025000,0.025000},{0.481250,0.856250,0.050000,0.050000},{0.493750,0.856250,0.025000,0.025000},{0.493750,0.856250,0.050000,0.050000},{0.506250,0.856250,0.025000,0.025000},{0.506250,0.856250,0.050000,0.050000},{0.518750,0.856250,0.025000,0.025000},{0.518750,0.856250,0.050000,0.050000},{0.531250,0.856250,0.025000,0.025000},{0.531250,0.856250,0.050000,0.050000},{0.543750,0.856250,0.025000,0.025000},{0.543750,0.856250,0.050000,0.050000},{0.556250,0.856250,0.025000,0.025000},{0.556250,0.856250,0.050000,0.050000},{0.568750,0.856250,0.025000,0.025000},{0.568750,0.856250,0.050000,0.050000},{0.581250,0.856250,0.025000,0.025000},{0.581250,0.856250,0.050000,0.050000},{0.593750,0.856250,0.025000,0.025000},{0.593750,0.856250,0.050000,0.050000},{0.606250,0.856250,0.025000,0.025000},{0.606250,0.856250,0.050000,0.050000},{0.618750,0.856250,0.025000,0.025000},{0.618750,0.856250,0.050000,0.050000},{0.631250,0.856250,0.025000,0.025000},{0.631250,0.856250,0.050000,0.050000},{0.643750,0.856250,0.025000,0.025000},{0.643750,0.856250,0.050000,0.050000},{0.656250,0.856250,0.025000,0.025000},{0.656250,0.856250,0.050000,0.050000},{0.668750,0.856250,0.025000,0.025000},{0.668750,0.856250,0.050000,0.050000},{0.681250,0.856250,0.025000,0.025000},{0.681250,0.856250,0.050000,0.050000},{0.693750,0.856250,0.025000,0.025000},{0.693750,0.856250,0.050000,0.050000},{0.706250,0.856250,0.025000,0.025000},{0.706250,0.856250,0.050000,0.050000},{0.718750,0.856250,0.025000,0.025000},{0.718750,0.856250,0.050000,0.050000},{0.731250,0.856250,0.025000,0.025000},{0.731250,0.856250,0.050000,0.050000},{0.743750,0.856250,0.025000,0.025000},{0.743750,0.856250,0.050000,0.050000},{0.756250,0.856250,0.025000,0.025000},{0.756250,0.856250,0.050000,0.050000},{0.768750,0.856250,0.025000,0.025000},{0.768750,0.856250,0.050000,0.050000},{0.781250,0.856250,0.025000,0.025000},{0.781250,0.856250,0.050000,0.050000},{0.793750,0.856250,0.025000,0.025000},{0.793750,0.856250,0.050000,0.050000},{0.806250,0.856250,0.025000,0.025000},{0.806250,0.856250,0.050000,0.050000},{0.818750,0.856250,0.025000,0.025000},{0.818750,0.856250,0.050000,0.050000},{0.831250,0.856250,0.025000,0.025000},{0.831250,0.856250,0.050000,0.050000},{0.843750,0.856250,0.025000,0.025000},{0.843750,0.856250,0.050000,0.050000},{0.856250,0.856250,0.025000,0.025000},{0.856250,0.856250,0.050000,0.050000},{0.868750,0.856250,0.025000,0.025000},{0.868750,0.856250,0.050000,0.050000},{0.881250,0.856250,0.025000,0.025000},{0.881250,0.856250,0.050000,0.050000},{0.893750,0.856250,0.025000,0.025000},{0.893750,0.856250,0.050000,0.050000},{0.906250,0.856250,0.025000,0.025000},{0.906250,0.856250,0.050000,0.050000},{0.918750,0.856250,0.025000,0.025000},{0.918750,0.856250,0.050000,0.050000},{0.931250,0.856250,0.025000,0.025000},{0.931250,0.856250,0.050000,0.050000},{0.943750,0.856250,0.025000,0.025000},{0.943750,0.856250,0.050000,0.050000},{0.956250,0.856250,0.025000,0.025000},{0.956250,0.856250,0.050000,0.050000},{0.968750,0.856250,0.025000,0.025000},{0.968750,0.856250,0.050000,0.050000},{0.981250,0.856250,0.025000,0.025000},{0.981250,0.856250,0.050000,0.050000},{0.993750,0.856250,0.025000,0.025000},{0.993750,0.856250,0.050000,0.050000},{0.006250,0.868750,0.025000,0.025000},{0.006250,0.868750,0.050000,0.050000},{0.018750,0.868750,0.025000,0.025000},{0.018750,0.868750,0.050000,0.050000},{0.031250,0.868750,0.025000,0.025000},{0.031250,0.868750,0.050000,0.050000},{0.043750,0.868750,0.025000,0.025000},{0.043750,0.868750,0.050000,0.050000},{0.056250,0.868750,0.025000,0.025000},{0.056250,0.868750,0.050000,0.050000},{0.068750,0.868750,0.025000,0.025000},{0.068750,0.868750,0.050000,0.050000},{0.081250,0.868750,0.025000,0.025000},{0.081250,0.868750,0.050000,0.050000},{0.093750,0.868750,0.025000,0.025000},{0.093750,0.868750,0.050000,0.050000},{0.106250,0.868750,0.025000,0.025000},{0.106250,0.868750,0.050000,0.050000},{0.118750,0.868750,0.025000,0.025000},{0.118750,0.868750,0.050000,0.050000},{0.131250,0.868750,0.025000,0.025000},{0.131250,0.868750,0.050000,0.050000},{0.143750,0.868750,0.025000,0.025000},{0.143750,0.868750,0.050000,0.050000},{0.156250,0.868750,0.025000,0.025000},{0.156250,0.868750,0.050000,0.050000},{0.168750,0.868750,0.025000,0.025000},{0.168750,0.868750,0.050000,0.050000},{0.181250,0.868750,0.025000,0.025000},{0.181250,0.868750,0.050000,0.050000},{0.193750,0.868750,0.025000,0.025000},{0.193750,0.868750,0.050000,0.050000},{0.206250,0.868750,0.025000,0.025000},{0.206250,0.868750,0.050000,0.050000},{0.218750,0.868750,0.025000,0.025000},{0.218750,0.868750,0.050000,0.050000},{0.231250,0.868750,0.025000,0.025000},{0.231250,0.868750,0.050000,0.050000},{0.243750,0.868750,0.025000,0.025000},{0.243750,0.868750,0.050000,0.050000},{0.256250,0.868750,0.025000,0.025000},{0.256250,0.868750,0.050000,0.050000},{0.268750,0.868750,0.025000,0.025000},{0.268750,0.868750,0.050000,0.050000},{0.281250,0.868750,0.025000,0.025000},{0.281250,0.868750,0.050000,0.050000},{0.293750,0.868750,0.025000,0.025000},{0.293750,0.868750,0.050000,0.050000},{0.306250,0.868750,0.025000,0.025000},{0.306250,0.868750,0.050000,0.050000},{0.318750,0.868750,0.025000,0.025000},{0.318750,0.868750,0.050000,0.050000},{0.331250,0.868750,0.025000,0.025000},{0.331250,0.868750,0.050000,0.050000},{0.343750,0.868750,0.025000,0.025000},{0.343750,0.868750,0.050000,0.050000},{0.356250,0.868750,0.025000,0.025000},{0.356250,0.868750,0.050000,0.050000},{0.368750,0.868750,0.025000,0.025000},{0.368750,0.868750,0.050000,0.050000},{0.381250,0.868750,0.025000,0.025000},{0.381250,0.868750,0.050000,0.050000},{0.393750,0.868750,0.025000,0.025000},{0.393750,0.868750,0.050000,0.050000},{0.406250,0.868750,0.025000,0.025000},{0.406250,0.868750,0.050000,0.050000},{0.418750,0.868750,0.025000,0.025000},{0.418750,0.868750,0.050000,0.050000},{0.431250,0.868750,0.025000,0.025000},{0.431250,0.868750,0.050000,0.050000},{0.443750,0.868750,0.025000,0.025000},{0.443750,0.868750,0.050000,0.050000},{0.456250,0.868750,0.025000,0.025000},{0.456250,0.868750,0.050000,0.050000},{0.468750,0.868750,0.025000,0.025000},{0.468750,0.868750,0.050000,0.050000},{0.481250,0.868750,0.025000,0.025000},{0.481250,0.868750,0.050000,0.050000},{0.493750,0.868750,0.025000,0.025000},{0.493750,0.868750,0.050000,0.050000},{0.506250,0.868750,0.025000,0.025000},{0.506250,0.868750,0.050000,0.050000},{0.518750,0.868750,0.025000,0.025000},{0.518750,0.868750,0.050000,0.050000},{0.531250,0.868750,0.025000,0.025000},{0.531250,0.868750,0.050000,0.050000},{0.543750,0.868750,0.025000,0.025000},{0.543750,0.868750,0.050000,0.050000},{0.556250,0.868750,0.025000,0.025000},{0.556250,0.868750,0.050000,0.050000},{0.568750,0.868750,0.025000,0.025000},{0.568750,0.868750,0.050000,0.050000},{0.581250,0.868750,0.025000,0.025000},{0.581250,0.868750,0.050000,0.050000},{0.593750,0.868750,0.025000,0.025000},{0.593750,0.868750,0.050000,0.050000},{0.606250,0.868750,0.025000,0.025000},{0.606250,0.868750,0.050000,0.050000},{0.618750,0.868750,0.025000,0.025000},{0.618750,0.868750,0.050000,0.050000},{0.631250,0.868750,0.025000,0.025000},{0.631250,0.868750,0.050000,0.050000},{0.643750,0.868750,0.025000,0.025000},{0.643750,0.868750,0.050000,0.050000},{0.656250,0.868750,0.025000,0.025000},{0.656250,0.868750,0.050000,0.050000},{0.668750,0.868750,0.025000,0.025000},{0.668750,0.868750,0.050000,0.050000},{0.681250,0.868750,0.025000,0.025000},{0.681250,0.868750,0.050000,0.050000},{0.693750,0.868750,0.025000,0.025000},{0.693750,0.868750,0.050000,0.050000},{0.706250,0.868750,0.025000,0.025000},{0.706250,0.868750,0.050000,0.050000},{0.718750,0.868750,0.025000,0.025000},{0.718750,0.868750,0.050000,0.050000},{0.731250,0.868750,0.025000,0.025000},{0.731250,0.868750,0.050000,0.050000},{0.743750,0.868750,0.025000,0.025000},{0.743750,0.868750,0.050000,0.050000},{0.756250,0.868750,0.025000,0.025000},{0.756250,0.868750,0.050000,0.050000},{0.768750,0.868750,0.025000,0.025000},{0.768750,0.868750,0.050000,0.050000},{0.781250,0.868750,0.025000,0.025000},{0.781250,0.868750,0.050000,0.050000},{0.793750,0.868750,0.025000,0.025000},{0.793750,0.868750,0.050000,0.050000},{0.806250,0.868750,0.025000,0.025000},{0.806250,0.868750,0.050000,0.050000},{0.818750,0.868750,0.025000,0.025000},{0.818750,0.868750,0.050000,0.050000},{0.831250,0.868750,0.025000,0.025000},{0.831250,0.868750,0.050000,0.050000},{0.843750,0.868750,0.025000,0.025000},{0.843750,0.868750,0.050000,0.050000},{0.856250,0.868750,0.025000,0.025000},{0.856250,0.868750,0.050000,0.050000},{0.868750,0.868750,0.025000,0.025000},{0.868750,0.868750,0.050000,0.050000},{0.881250,0.868750,0.025000,0.025000},{0.881250,0.868750,0.050000,0.050000},{0.893750,0.868750,0.025000,0.025000},{0.893750,0.868750,0.050000,0.050000},{0.906250,0.868750,0.025000,0.025000},{0.906250,0.868750,0.050000,0.050000},{0.918750,0.868750,0.025000,0.025000},{0.918750,0.868750,0.050000,0.050000},{0.931250,0.868750,0.025000,0.025000},{0.931250,0.868750,0.050000,0.050000},{0.943750,0.868750,0.025000,0.025000},{0.943750,0.868750,0.050000,0.050000},{0.956250,0.868750,0.025000,0.025000},{0.956250,0.868750,0.050000,0.050000},{0.968750,0.868750,0.025000,0.025000},{0.968750,0.868750,0.050000,0.050000},{0.981250,0.868750,0.025000,0.025000},{0.981250,0.868750,0.050000,0.050000},{0.993750,0.868750,0.025000,0.025000},{0.993750,0.868750,0.050000,0.050000},{0.006250,0.881250,0.025000,0.025000},{0.006250,0.881250,0.050000,0.050000},{0.018750,0.881250,0.025000,0.025000},{0.018750,0.881250,0.050000,0.050000},{0.031250,0.881250,0.025000,0.025000},{0.031250,0.881250,0.050000,0.050000},{0.043750,0.881250,0.025000,0.025000},{0.043750,0.881250,0.050000,0.050000},{0.056250,0.881250,0.025000,0.025000},{0.056250,0.881250,0.050000,0.050000},{0.068750,0.881250,0.025000,0.025000},{0.068750,0.881250,0.050000,0.050000},{0.081250,0.881250,0.025000,0.025000},{0.081250,0.881250,0.050000,0.050000},{0.093750,0.881250,0.025000,0.025000},{0.093750,0.881250,0.050000,0.050000},{0.106250,0.881250,0.025000,0.025000},{0.106250,0.881250,0.050000,0.050000},{0.118750,0.881250,0.025000,0.025000},{0.118750,0.881250,0.050000,0.050000},{0.131250,0.881250,0.025000,0.025000},{0.131250,0.881250,0.050000,0.050000},{0.143750,0.881250,0.025000,0.025000},{0.143750,0.881250,0.050000,0.050000},{0.156250,0.881250,0.025000,0.025000},{0.156250,0.881250,0.050000,0.050000},{0.168750,0.881250,0.025000,0.025000},{0.168750,0.881250,0.050000,0.050000},{0.181250,0.881250,0.025000,0.025000},{0.181250,0.881250,0.050000,0.050000},{0.193750,0.881250,0.025000,0.025000},{0.193750,0.881250,0.050000,0.050000},{0.206250,0.881250,0.025000,0.025000},{0.206250,0.881250,0.050000,0.050000},{0.218750,0.881250,0.025000,0.025000},{0.218750,0.881250,0.050000,0.050000},{0.231250,0.881250,0.025000,0.025000},{0.231250,0.881250,0.050000,0.050000},{0.243750,0.881250,0.025000,0.025000},{0.243750,0.881250,0.050000,0.050000},{0.256250,0.881250,0.025000,0.025000},{0.256250,0.881250,0.050000,0.050000},{0.268750,0.881250,0.025000,0.025000},{0.268750,0.881250,0.050000,0.050000},{0.281250,0.881250,0.025000,0.025000},{0.281250,0.881250,0.050000,0.050000},{0.293750,0.881250,0.025000,0.025000},{0.293750,0.881250,0.050000,0.050000},{0.306250,0.881250,0.025000,0.025000},{0.306250,0.881250,0.050000,0.050000},{0.318750,0.881250,0.025000,0.025000},{0.318750,0.881250,0.050000,0.050000},{0.331250,0.881250,0.025000,0.025000},{0.331250,0.881250,0.050000,0.050000},{0.343750,0.881250,0.025000,0.025000},{0.343750,0.881250,0.050000,0.050000},{0.356250,0.881250,0.025000,0.025000},{0.356250,0.881250,0.050000,0.050000},{0.368750,0.881250,0.025000,0.025000},{0.368750,0.881250,0.050000,0.050000},{0.381250,0.881250,0.025000,0.025000},{0.381250,0.881250,0.050000,0.050000},{0.393750,0.881250,0.025000,0.025000},{0.393750,0.881250,0.050000,0.050000},{0.406250,0.881250,0.025000,0.025000},{0.406250,0.881250,0.050000,0.050000},{0.418750,0.881250,0.025000,0.025000},{0.418750,0.881250,0.050000,0.050000},{0.431250,0.881250,0.025000,0.025000},{0.431250,0.881250,0.050000,0.050000},{0.443750,0.881250,0.025000,0.025000},{0.443750,0.881250,0.050000,0.050000},{0.456250,0.881250,0.025000,0.025000},{0.456250,0.881250,0.050000,0.050000},{0.468750,0.881250,0.025000,0.025000},{0.468750,0.881250,0.050000,0.050000},{0.481250,0.881250,0.025000,0.025000},{0.481250,0.881250,0.050000,0.050000},{0.493750,0.881250,0.025000,0.025000},{0.493750,0.881250,0.050000,0.050000},{0.506250,0.881250,0.025000,0.025000},{0.506250,0.881250,0.050000,0.050000},{0.518750,0.881250,0.025000,0.025000},{0.518750,0.881250,0.050000,0.050000},{0.531250,0.881250,0.025000,0.025000},{0.531250,0.881250,0.050000,0.050000},{0.543750,0.881250,0.025000,0.025000},{0.543750,0.881250,0.050000,0.050000},{0.556250,0.881250,0.025000,0.025000},{0.556250,0.881250,0.050000,0.050000},{0.568750,0.881250,0.025000,0.025000},{0.568750,0.881250,0.050000,0.050000},{0.581250,0.881250,0.025000,0.025000},{0.581250,0.881250,0.050000,0.050000},{0.593750,0.881250,0.025000,0.025000},{0.593750,0.881250,0.050000,0.050000},{0.606250,0.881250,0.025000,0.025000},{0.606250,0.881250,0.050000,0.050000},{0.618750,0.881250,0.025000,0.025000},{0.618750,0.881250,0.050000,0.050000},{0.631250,0.881250,0.025000,0.025000},{0.631250,0.881250,0.050000,0.050000},{0.643750,0.881250,0.025000,0.025000},{0.643750,0.881250,0.050000,0.050000},{0.656250,0.881250,0.025000,0.025000},{0.656250,0.881250,0.050000,0.050000},{0.668750,0.881250,0.025000,0.025000},{0.668750,0.881250,0.050000,0.050000},{0.681250,0.881250,0.025000,0.025000},{0.681250,0.881250,0.050000,0.050000},{0.693750,0.881250,0.025000,0.025000},{0.693750,0.881250,0.050000,0.050000},{0.706250,0.881250,0.025000,0.025000},{0.706250,0.881250,0.050000,0.050000},{0.718750,0.881250,0.025000,0.025000},{0.718750,0.881250,0.050000,0.050000},{0.731250,0.881250,0.025000,0.025000},{0.731250,0.881250,0.050000,0.050000},{0.743750,0.881250,0.025000,0.025000},{0.743750,0.881250,0.050000,0.050000},{0.756250,0.881250,0.025000,0.025000},{0.756250,0.881250,0.050000,0.050000},{0.768750,0.881250,0.025000,0.025000},{0.768750,0.881250,0.050000,0.050000},{0.781250,0.881250,0.025000,0.025000},{0.781250,0.881250,0.050000,0.050000},{0.793750,0.881250,0.025000,0.025000},{0.793750,0.881250,0.050000,0.050000},{0.806250,0.881250,0.025000,0.025000},{0.806250,0.881250,0.050000,0.050000},{0.818750,0.881250,0.025000,0.025000},{0.818750,0.881250,0.050000,0.050000},{0.831250,0.881250,0.025000,0.025000},{0.831250,0.881250,0.050000,0.050000},{0.843750,0.881250,0.025000,0.025000},{0.843750,0.881250,0.050000,0.050000},{0.856250,0.881250,0.025000,0.025000},{0.856250,0.881250,0.050000,0.050000},{0.868750,0.881250,0.025000,0.025000},{0.868750,0.881250,0.050000,0.050000},{0.881250,0.881250,0.025000,0.025000},{0.881250,0.881250,0.050000,0.050000},{0.893750,0.881250,0.025000,0.025000},{0.893750,0.881250,0.050000,0.050000},{0.906250,0.881250,0.025000,0.025000},{0.906250,0.881250,0.050000,0.050000},{0.918750,0.881250,0.025000,0.025000},{0.918750,0.881250,0.050000,0.050000},{0.931250,0.881250,0.025000,0.025000},{0.931250,0.881250,0.050000,0.050000},{0.943750,0.881250,0.025000,0.025000},{0.943750,0.881250,0.050000,0.050000},{0.956250,0.881250,0.025000,0.025000},{0.956250,0.881250,0.050000,0.050000},{0.968750,0.881250,0.025000,0.025000},{0.968750,0.881250,0.050000,0.050000},{0.981250,0.881250,0.025000,0.025000},{0.981250,0.881250,0.050000,0.050000},{0.993750,0.881250,0.025000,0.025000},{0.993750,0.881250,0.050000,0.050000},{0.006250,0.893750,0.025000,0.025000},{0.006250,0.893750,0.050000,0.050000},{0.018750,0.893750,0.025000,0.025000},{0.018750,0.893750,0.050000,0.050000},{0.031250,0.893750,0.025000,0.025000},{0.031250,0.893750,0.050000,0.050000},{0.043750,0.893750,0.025000,0.025000},{0.043750,0.893750,0.050000,0.050000},{0.056250,0.893750,0.025000,0.025000},{0.056250,0.893750,0.050000,0.050000},{0.068750,0.893750,0.025000,0.025000},{0.068750,0.893750,0.050000,0.050000},{0.081250,0.893750,0.025000,0.025000},{0.081250,0.893750,0.050000,0.050000},{0.093750,0.893750,0.025000,0.025000},{0.093750,0.893750,0.050000,0.050000},{0.106250,0.893750,0.025000,0.025000},{0.106250,0.893750,0.050000,0.050000},{0.118750,0.893750,0.025000,0.025000},{0.118750,0.893750,0.050000,0.050000},{0.131250,0.893750,0.025000,0.025000},{0.131250,0.893750,0.050000,0.050000},{0.143750,0.893750,0.025000,0.025000},{0.143750,0.893750,0.050000,0.050000},{0.156250,0.893750,0.025000,0.025000},{0.156250,0.893750,0.050000,0.050000},{0.168750,0.893750,0.025000,0.025000},{0.168750,0.893750,0.050000,0.050000},{0.181250,0.893750,0.025000,0.025000},{0.181250,0.893750,0.050000,0.050000},{0.193750,0.893750,0.025000,0.025000},{0.193750,0.893750,0.050000,0.050000},{0.206250,0.893750,0.025000,0.025000},{0.206250,0.893750,0.050000,0.050000},{0.218750,0.893750,0.025000,0.025000},{0.218750,0.893750,0.050000,0.050000},{0.231250,0.893750,0.025000,0.025000},{0.231250,0.893750,0.050000,0.050000},{0.243750,0.893750,0.025000,0.025000},{0.243750,0.893750,0.050000,0.050000},{0.256250,0.893750,0.025000,0.025000},{0.256250,0.893750,0.050000,0.050000},{0.268750,0.893750,0.025000,0.025000},{0.268750,0.893750,0.050000,0.050000},{0.281250,0.893750,0.025000,0.025000},{0.281250,0.893750,0.050000,0.050000},{0.293750,0.893750,0.025000,0.025000},{0.293750,0.893750,0.050000,0.050000},{0.306250,0.893750,0.025000,0.025000},{0.306250,0.893750,0.050000,0.050000},{0.318750,0.893750,0.025000,0.025000},{0.318750,0.893750,0.050000,0.050000},{0.331250,0.893750,0.025000,0.025000},{0.331250,0.893750,0.050000,0.050000},{0.343750,0.893750,0.025000,0.025000},{0.343750,0.893750,0.050000,0.050000},{0.356250,0.893750,0.025000,0.025000},{0.356250,0.893750,0.050000,0.050000},{0.368750,0.893750,0.025000,0.025000},{0.368750,0.893750,0.050000,0.050000},{0.381250,0.893750,0.025000,0.025000},{0.381250,0.893750,0.050000,0.050000},{0.393750,0.893750,0.025000,0.025000},{0.393750,0.893750,0.050000,0.050000},{0.406250,0.893750,0.025000,0.025000},{0.406250,0.893750,0.050000,0.050000},{0.418750,0.893750,0.025000,0.025000},{0.418750,0.893750,0.050000,0.050000},{0.431250,0.893750,0.025000,0.025000},{0.431250,0.893750,0.050000,0.050000},{0.443750,0.893750,0.025000,0.025000},{0.443750,0.893750,0.050000,0.050000},{0.456250,0.893750,0.025000,0.025000},{0.456250,0.893750,0.050000,0.050000},{0.468750,0.893750,0.025000,0.025000},{0.468750,0.893750,0.050000,0.050000},{0.481250,0.893750,0.025000,0.025000},{0.481250,0.893750,0.050000,0.050000},{0.493750,0.893750,0.025000,0.025000},{0.493750,0.893750,0.050000,0.050000},{0.506250,0.893750,0.025000,0.025000},{0.506250,0.893750,0.050000,0.050000},{0.518750,0.893750,0.025000,0.025000},{0.518750,0.893750,0.050000,0.050000},{0.531250,0.893750,0.025000,0.025000},{0.531250,0.893750,0.050000,0.050000},{0.543750,0.893750,0.025000,0.025000},{0.543750,0.893750,0.050000,0.050000},{0.556250,0.893750,0.025000,0.025000},{0.556250,0.893750,0.050000,0.050000},{0.568750,0.893750,0.025000,0.025000},{0.568750,0.893750,0.050000,0.050000},{0.581250,0.893750,0.025000,0.025000},{0.581250,0.893750,0.050000,0.050000},{0.593750,0.893750,0.025000,0.025000},{0.593750,0.893750,0.050000,0.050000},{0.606250,0.893750,0.025000,0.025000},{0.606250,0.893750,0.050000,0.050000},{0.618750,0.893750,0.025000,0.025000},{0.618750,0.893750,0.050000,0.050000},{0.631250,0.893750,0.025000,0.025000},{0.631250,0.893750,0.050000,0.050000},{0.643750,0.893750,0.025000,0.025000},{0.643750,0.893750,0.050000,0.050000},{0.656250,0.893750,0.025000,0.025000},{0.656250,0.893750,0.050000,0.050000},{0.668750,0.893750,0.025000,0.025000},{0.668750,0.893750,0.050000,0.050000},{0.681250,0.893750,0.025000,0.025000},{0.681250,0.893750,0.050000,0.050000},{0.693750,0.893750,0.025000,0.025000},{0.693750,0.893750,0.050000,0.050000},{0.706250,0.893750,0.025000,0.025000},{0.706250,0.893750,0.050000,0.050000},{0.718750,0.893750,0.025000,0.025000},{0.718750,0.893750,0.050000,0.050000},{0.731250,0.893750,0.025000,0.025000},{0.731250,0.893750,0.050000,0.050000},{0.743750,0.893750,0.025000,0.025000},{0.743750,0.893750,0.050000,0.050000},{0.756250,0.893750,0.025000,0.025000},{0.756250,0.893750,0.050000,0.050000},{0.768750,0.893750,0.025000,0.025000},{0.768750,0.893750,0.050000,0.050000},{0.781250,0.893750,0.025000,0.025000},{0.781250,0.893750,0.050000,0.050000},{0.793750,0.893750,0.025000,0.025000},{0.793750,0.893750,0.050000,0.050000},{0.806250,0.893750,0.025000,0.025000},{0.806250,0.893750,0.050000,0.050000},{0.818750,0.893750,0.025000,0.025000},{0.818750,0.893750,0.050000,0.050000},{0.831250,0.893750,0.025000,0.025000},{0.831250,0.893750,0.050000,0.050000},{0.843750,0.893750,0.025000,0.025000},{0.843750,0.893750,0.050000,0.050000},{0.856250,0.893750,0.025000,0.025000},{0.856250,0.893750,0.050000,0.050000},{0.868750,0.893750,0.025000,0.025000},{0.868750,0.893750,0.050000,0.050000},{0.881250,0.893750,0.025000,0.025000},{0.881250,0.893750,0.050000,0.050000},{0.893750,0.893750,0.025000,0.025000},{0.893750,0.893750,0.050000,0.050000},{0.906250,0.893750,0.025000,0.025000},{0.906250,0.893750,0.050000,0.050000},{0.918750,0.893750,0.025000,0.025000},{0.918750,0.893750,0.050000,0.050000},{0.931250,0.893750,0.025000,0.025000},{0.931250,0.893750,0.050000,0.050000},{0.943750,0.893750,0.025000,0.025000},{0.943750,0.893750,0.050000,0.050000},{0.956250,0.893750,0.025000,0.025000},{0.956250,0.893750,0.050000,0.050000},{0.968750,0.893750,0.025000,0.025000},{0.968750,0.893750,0.050000,0.050000},{0.981250,0.893750,0.025000,0.025000},{0.981250,0.893750,0.050000,0.050000},{0.993750,0.893750,0.025000,0.025000},{0.993750,0.893750,0.050000,0.050000},{0.006250,0.906250,0.025000,0.025000},{0.006250,0.906250,0.050000,0.050000},{0.018750,0.906250,0.025000,0.025000},{0.018750,0.906250,0.050000,0.050000},{0.031250,0.906250,0.025000,0.025000},{0.031250,0.906250,0.050000,0.050000},{0.043750,0.906250,0.025000,0.025000},{0.043750,0.906250,0.050000,0.050000},{0.056250,0.906250,0.025000,0.025000},{0.056250,0.906250,0.050000,0.050000},{0.068750,0.906250,0.025000,0.025000},{0.068750,0.906250,0.050000,0.050000},{0.081250,0.906250,0.025000,0.025000},{0.081250,0.906250,0.050000,0.050000},{0.093750,0.906250,0.025000,0.025000},{0.093750,0.906250,0.050000,0.050000},{0.106250,0.906250,0.025000,0.025000},{0.106250,0.906250,0.050000,0.050000},{0.118750,0.906250,0.025000,0.025000},{0.118750,0.906250,0.050000,0.050000},{0.131250,0.906250,0.025000,0.025000},{0.131250,0.906250,0.050000,0.050000},{0.143750,0.906250,0.025000,0.025000},{0.143750,0.906250,0.050000,0.050000},{0.156250,0.906250,0.025000,0.025000},{0.156250,0.906250,0.050000,0.050000},{0.168750,0.906250,0.025000,0.025000},{0.168750,0.906250,0.050000,0.050000},{0.181250,0.906250,0.025000,0.025000},{0.181250,0.906250,0.050000,0.050000},{0.193750,0.906250,0.025000,0.025000},{0.193750,0.906250,0.050000,0.050000},{0.206250,0.906250,0.025000,0.025000},{0.206250,0.906250,0.050000,0.050000},{0.218750,0.906250,0.025000,0.025000},{0.218750,0.906250,0.050000,0.050000},{0.231250,0.906250,0.025000,0.025000},{0.231250,0.906250,0.050000,0.050000},{0.243750,0.906250,0.025000,0.025000},{0.243750,0.906250,0.050000,0.050000},{0.256250,0.906250,0.025000,0.025000},{0.256250,0.906250,0.050000,0.050000},{0.268750,0.906250,0.025000,0.025000},{0.268750,0.906250,0.050000,0.050000},{0.281250,0.906250,0.025000,0.025000},{0.281250,0.906250,0.050000,0.050000},{0.293750,0.906250,0.025000,0.025000},{0.293750,0.906250,0.050000,0.050000},{0.306250,0.906250,0.025000,0.025000},{0.306250,0.906250,0.050000,0.050000},{0.318750,0.906250,0.025000,0.025000},{0.318750,0.906250,0.050000,0.050000},{0.331250,0.906250,0.025000,0.025000},{0.331250,0.906250,0.050000,0.050000},{0.343750,0.906250,0.025000,0.025000},{0.343750,0.906250,0.050000,0.050000},{0.356250,0.906250,0.025000,0.025000},{0.356250,0.906250,0.050000,0.050000},{0.368750,0.906250,0.025000,0.025000},{0.368750,0.906250,0.050000,0.050000},{0.381250,0.906250,0.025000,0.025000},{0.381250,0.906250,0.050000,0.050000},{0.393750,0.906250,0.025000,0.025000},{0.393750,0.906250,0.050000,0.050000},{0.406250,0.906250,0.025000,0.025000},{0.406250,0.906250,0.050000,0.050000},{0.418750,0.906250,0.025000,0.025000},{0.418750,0.906250,0.050000,0.050000},{0.431250,0.906250,0.025000,0.025000},{0.431250,0.906250,0.050000,0.050000},{0.443750,0.906250,0.025000,0.025000},{0.443750,0.906250,0.050000,0.050000},{0.456250,0.906250,0.025000,0.025000},{0.456250,0.906250,0.050000,0.050000},{0.468750,0.906250,0.025000,0.025000},{0.468750,0.906250,0.050000,0.050000},{0.481250,0.906250,0.025000,0.025000},{0.481250,0.906250,0.050000,0.050000},{0.493750,0.906250,0.025000,0.025000},{0.493750,0.906250,0.050000,0.050000},{0.506250,0.906250,0.025000,0.025000},{0.506250,0.906250,0.050000,0.050000},{0.518750,0.906250,0.025000,0.025000},{0.518750,0.906250,0.050000,0.050000},{0.531250,0.906250,0.025000,0.025000},{0.531250,0.906250,0.050000,0.050000},{0.543750,0.906250,0.025000,0.025000},{0.543750,0.906250,0.050000,0.050000},{0.556250,0.906250,0.025000,0.025000},{0.556250,0.906250,0.050000,0.050000},{0.568750,0.906250,0.025000,0.025000},{0.568750,0.906250,0.050000,0.050000},{0.581250,0.906250,0.025000,0.025000},{0.581250,0.906250,0.050000,0.050000},{0.593750,0.906250,0.025000,0.025000},{0.593750,0.906250,0.050000,0.050000},{0.606250,0.906250,0.025000,0.025000},{0.606250,0.906250,0.050000,0.050000},{0.618750,0.906250,0.025000,0.025000},{0.618750,0.906250,0.050000,0.050000},{0.631250,0.906250,0.025000,0.025000},{0.631250,0.906250,0.050000,0.050000},{0.643750,0.906250,0.025000,0.025000},{0.643750,0.906250,0.050000,0.050000},{0.656250,0.906250,0.025000,0.025000},{0.656250,0.906250,0.050000,0.050000},{0.668750,0.906250,0.025000,0.025000},{0.668750,0.906250,0.050000,0.050000},{0.681250,0.906250,0.025000,0.025000},{0.681250,0.906250,0.050000,0.050000},{0.693750,0.906250,0.025000,0.025000},{0.693750,0.906250,0.050000,0.050000},{0.706250,0.906250,0.025000,0.025000},{0.706250,0.906250,0.050000,0.050000},{0.718750,0.906250,0.025000,0.025000},{0.718750,0.906250,0.050000,0.050000},{0.731250,0.906250,0.025000,0.025000},{0.731250,0.906250,0.050000,0.050000},{0.743750,0.906250,0.025000,0.025000},{0.743750,0.906250,0.050000,0.050000},{0.756250,0.906250,0.025000,0.025000},{0.756250,0.906250,0.050000,0.050000},{0.768750,0.906250,0.025000,0.025000},{0.768750,0.906250,0.050000,0.050000},{0.781250,0.906250,0.025000,0.025000},{0.781250,0.906250,0.050000,0.050000},{0.793750,0.906250,0.025000,0.025000},{0.793750,0.906250,0.050000,0.050000},{0.806250,0.906250,0.025000,0.025000},{0.806250,0.906250,0.050000,0.050000},{0.818750,0.906250,0.025000,0.025000},{0.818750,0.906250,0.050000,0.050000},{0.831250,0.906250,0.025000,0.025000},{0.831250,0.906250,0.050000,0.050000},{0.843750,0.906250,0.025000,0.025000},{0.843750,0.906250,0.050000,0.050000},{0.856250,0.906250,0.025000,0.025000},{0.856250,0.906250,0.050000,0.050000},{0.868750,0.906250,0.025000,0.025000},{0.868750,0.906250,0.050000,0.050000},{0.881250,0.906250,0.025000,0.025000},{0.881250,0.906250,0.050000,0.050000},{0.893750,0.906250,0.025000,0.025000},{0.893750,0.906250,0.050000,0.050000},{0.906250,0.906250,0.025000,0.025000},{0.906250,0.906250,0.050000,0.050000},{0.918750,0.906250,0.025000,0.025000},{0.918750,0.906250,0.050000,0.050000},{0.931250,0.906250,0.025000,0.025000},{0.931250,0.906250,0.050000,0.050000},{0.943750,0.906250,0.025000,0.025000},{0.943750,0.906250,0.050000,0.050000},{0.956250,0.906250,0.025000,0.025000},{0.956250,0.906250,0.050000,0.050000},{0.968750,0.906250,0.025000,0.025000},{0.968750,0.906250,0.050000,0.050000},{0.981250,0.906250,0.025000,0.025000},{0.981250,0.906250,0.050000,0.050000},{0.993750,0.906250,0.025000,0.025000},{0.993750,0.906250,0.050000,0.050000},{0.006250,0.918750,0.025000,0.025000},{0.006250,0.918750,0.050000,0.050000},{0.018750,0.918750,0.025000,0.025000},{0.018750,0.918750,0.050000,0.050000},{0.031250,0.918750,0.025000,0.025000},{0.031250,0.918750,0.050000,0.050000},{0.043750,0.918750,0.025000,0.025000},{0.043750,0.918750,0.050000,0.050000},{0.056250,0.918750,0.025000,0.025000},{0.056250,0.918750,0.050000,0.050000},{0.068750,0.918750,0.025000,0.025000},{0.068750,0.918750,0.050000,0.050000},{0.081250,0.918750,0.025000,0.025000},{0.081250,0.918750,0.050000,0.050000},{0.093750,0.918750,0.025000,0.025000},{0.093750,0.918750,0.050000,0.050000},{0.106250,0.918750,0.025000,0.025000},{0.106250,0.918750,0.050000,0.050000},{0.118750,0.918750,0.025000,0.025000},{0.118750,0.918750,0.050000,0.050000},{0.131250,0.918750,0.025000,0.025000},{0.131250,0.918750,0.050000,0.050000},{0.143750,0.918750,0.025000,0.025000},{0.143750,0.918750,0.050000,0.050000},{0.156250,0.918750,0.025000,0.025000},{0.156250,0.918750,0.050000,0.050000},{0.168750,0.918750,0.025000,0.025000},{0.168750,0.918750,0.050000,0.050000},{0.181250,0.918750,0.025000,0.025000},{0.181250,0.918750,0.050000,0.050000},{0.193750,0.918750,0.025000,0.025000},{0.193750,0.918750,0.050000,0.050000},{0.206250,0.918750,0.025000,0.025000},{0.206250,0.918750,0.050000,0.050000},{0.218750,0.918750,0.025000,0.025000},{0.218750,0.918750,0.050000,0.050000},{0.231250,0.918750,0.025000,0.025000},{0.231250,0.918750,0.050000,0.050000},{0.243750,0.918750,0.025000,0.025000},{0.243750,0.918750,0.050000,0.050000},{0.256250,0.918750,0.025000,0.025000},{0.256250,0.918750,0.050000,0.050000},{0.268750,0.918750,0.025000,0.025000},{0.268750,0.918750,0.050000,0.050000},{0.281250,0.918750,0.025000,0.025000},{0.281250,0.918750,0.050000,0.050000},{0.293750,0.918750,0.025000,0.025000},{0.293750,0.918750,0.050000,0.050000},{0.306250,0.918750,0.025000,0.025000},{0.306250,0.918750,0.050000,0.050000},{0.318750,0.918750,0.025000,0.025000},{0.318750,0.918750,0.050000,0.050000},{0.331250,0.918750,0.025000,0.025000},{0.331250,0.918750,0.050000,0.050000},{0.343750,0.918750,0.025000,0.025000},{0.343750,0.918750,0.050000,0.050000},{0.356250,0.918750,0.025000,0.025000},{0.356250,0.918750,0.050000,0.050000},{0.368750,0.918750,0.025000,0.025000},{0.368750,0.918750,0.050000,0.050000},{0.381250,0.918750,0.025000,0.025000},{0.381250,0.918750,0.050000,0.050000},{0.393750,0.918750,0.025000,0.025000},{0.393750,0.918750,0.050000,0.050000},{0.406250,0.918750,0.025000,0.025000},{0.406250,0.918750,0.050000,0.050000},{0.418750,0.918750,0.025000,0.025000},{0.418750,0.918750,0.050000,0.050000},{0.431250,0.918750,0.025000,0.025000},{0.431250,0.918750,0.050000,0.050000},{0.443750,0.918750,0.025000,0.025000},{0.443750,0.918750,0.050000,0.050000},{0.456250,0.918750,0.025000,0.025000},{0.456250,0.918750,0.050000,0.050000},{0.468750,0.918750,0.025000,0.025000},{0.468750,0.918750,0.050000,0.050000},{0.481250,0.918750,0.025000,0.025000},{0.481250,0.918750,0.050000,0.050000},{0.493750,0.918750,0.025000,0.025000},{0.493750,0.918750,0.050000,0.050000},{0.506250,0.918750,0.025000,0.025000},{0.506250,0.918750,0.050000,0.050000},{0.518750,0.918750,0.025000,0.025000},{0.518750,0.918750,0.050000,0.050000},{0.531250,0.918750,0.025000,0.025000},{0.531250,0.918750,0.050000,0.050000},{0.543750,0.918750,0.025000,0.025000},{0.543750,0.918750,0.050000,0.050000},{0.556250,0.918750,0.025000,0.025000},{0.556250,0.918750,0.050000,0.050000},{0.568750,0.918750,0.025000,0.025000},{0.568750,0.918750,0.050000,0.050000},{0.581250,0.918750,0.025000,0.025000},{0.581250,0.918750,0.050000,0.050000},{0.593750,0.918750,0.025000,0.025000},{0.593750,0.918750,0.050000,0.050000},{0.606250,0.918750,0.025000,0.025000},{0.606250,0.918750,0.050000,0.050000},{0.618750,0.918750,0.025000,0.025000},{0.618750,0.918750,0.050000,0.050000},{0.631250,0.918750,0.025000,0.025000},{0.631250,0.918750,0.050000,0.050000},{0.643750,0.918750,0.025000,0.025000},{0.643750,0.918750,0.050000,0.050000},{0.656250,0.918750,0.025000,0.025000},{0.656250,0.918750,0.050000,0.050000},{0.668750,0.918750,0.025000,0.025000},{0.668750,0.918750,0.050000,0.050000},{0.681250,0.918750,0.025000,0.025000},{0.681250,0.918750,0.050000,0.050000},{0.693750,0.918750,0.025000,0.025000},{0.693750,0.918750,0.050000,0.050000},{0.706250,0.918750,0.025000,0.025000},{0.706250,0.918750,0.050000,0.050000},{0.718750,0.918750,0.025000,0.025000},{0.718750,0.918750,0.050000,0.050000},{0.731250,0.918750,0.025000,0.025000},{0.731250,0.918750,0.050000,0.050000},{0.743750,0.918750,0.025000,0.025000},{0.743750,0.918750,0.050000,0.050000},{0.756250,0.918750,0.025000,0.025000},{0.756250,0.918750,0.050000,0.050000},{0.768750,0.918750,0.025000,0.025000},{0.768750,0.918750,0.050000,0.050000},{0.781250,0.918750,0.025000,0.025000},{0.781250,0.918750,0.050000,0.050000},{0.793750,0.918750,0.025000,0.025000},{0.793750,0.918750,0.050000,0.050000},{0.806250,0.918750,0.025000,0.025000},{0.806250,0.918750,0.050000,0.050000},{0.818750,0.918750,0.025000,0.025000},{0.818750,0.918750,0.050000,0.050000},{0.831250,0.918750,0.025000,0.025000},{0.831250,0.918750,0.050000,0.050000},{0.843750,0.918750,0.025000,0.025000},{0.843750,0.918750,0.050000,0.050000},{0.856250,0.918750,0.025000,0.025000},{0.856250,0.918750,0.050000,0.050000},{0.868750,0.918750,0.025000,0.025000},{0.868750,0.918750,0.050000,0.050000},{0.881250,0.918750,0.025000,0.025000},{0.881250,0.918750,0.050000,0.050000},{0.893750,0.918750,0.025000,0.025000},{0.893750,0.918750,0.050000,0.050000},{0.906250,0.918750,0.025000,0.025000},{0.906250,0.918750,0.050000,0.050000},{0.918750,0.918750,0.025000,0.025000},{0.918750,0.918750,0.050000,0.050000},{0.931250,0.918750,0.025000,0.025000},{0.931250,0.918750,0.050000,0.050000},{0.943750,0.918750,0.025000,0.025000},{0.943750,0.918750,0.050000,0.050000},{0.956250,0.918750,0.025000,0.025000},{0.956250,0.918750,0.050000,0.050000},{0.968750,0.918750,0.025000,0.025000},{0.968750,0.918750,0.050000,0.050000},{0.981250,0.918750,0.025000,0.025000},{0.981250,0.918750,0.050000,0.050000},{0.993750,0.918750,0.025000,0.025000},{0.993750,0.918750,0.050000,0.050000},{0.006250,0.931250,0.025000,0.025000},{0.006250,0.931250,0.050000,0.050000},{0.018750,0.931250,0.025000,0.025000},{0.018750,0.931250,0.050000,0.050000},{0.031250,0.931250,0.025000,0.025000},{0.031250,0.931250,0.050000,0.050000},{0.043750,0.931250,0.025000,0.025000},{0.043750,0.931250,0.050000,0.050000},{0.056250,0.931250,0.025000,0.025000},{0.056250,0.931250,0.050000,0.050000},{0.068750,0.931250,0.025000,0.025000},{0.068750,0.931250,0.050000,0.050000},{0.081250,0.931250,0.025000,0.025000},{0.081250,0.931250,0.050000,0.050000},{0.093750,0.931250,0.025000,0.025000},{0.093750,0.931250,0.050000,0.050000},{0.106250,0.931250,0.025000,0.025000},{0.106250,0.931250,0.050000,0.050000},{0.118750,0.931250,0.025000,0.025000},{0.118750,0.931250,0.050000,0.050000},{0.131250,0.931250,0.025000,0.025000},{0.131250,0.931250,0.050000,0.050000},{0.143750,0.931250,0.025000,0.025000},{0.143750,0.931250,0.050000,0.050000},{0.156250,0.931250,0.025000,0.025000},{0.156250,0.931250,0.050000,0.050000},{0.168750,0.931250,0.025000,0.025000},{0.168750,0.931250,0.050000,0.050000},{0.181250,0.931250,0.025000,0.025000},{0.181250,0.931250,0.050000,0.050000},{0.193750,0.931250,0.025000,0.025000},{0.193750,0.931250,0.050000,0.050000},{0.206250,0.931250,0.025000,0.025000},{0.206250,0.931250,0.050000,0.050000},{0.218750,0.931250,0.025000,0.025000},{0.218750,0.931250,0.050000,0.050000},{0.231250,0.931250,0.025000,0.025000},{0.231250,0.931250,0.050000,0.050000},{0.243750,0.931250,0.025000,0.025000},{0.243750,0.931250,0.050000,0.050000},{0.256250,0.931250,0.025000,0.025000},{0.256250,0.931250,0.050000,0.050000},{0.268750,0.931250,0.025000,0.025000},{0.268750,0.931250,0.050000,0.050000},{0.281250,0.931250,0.025000,0.025000},{0.281250,0.931250,0.050000,0.050000},{0.293750,0.931250,0.025000,0.025000},{0.293750,0.931250,0.050000,0.050000},{0.306250,0.931250,0.025000,0.025000},{0.306250,0.931250,0.050000,0.050000},{0.318750,0.931250,0.025000,0.025000},{0.318750,0.931250,0.050000,0.050000},{0.331250,0.931250,0.025000,0.025000},{0.331250,0.931250,0.050000,0.050000},{0.343750,0.931250,0.025000,0.025000},{0.343750,0.931250,0.050000,0.050000},{0.356250,0.931250,0.025000,0.025000},{0.356250,0.931250,0.050000,0.050000},{0.368750,0.931250,0.025000,0.025000},{0.368750,0.931250,0.050000,0.050000},{0.381250,0.931250,0.025000,0.025000},{0.381250,0.931250,0.050000,0.050000},{0.393750,0.931250,0.025000,0.025000},{0.393750,0.931250,0.050000,0.050000},{0.406250,0.931250,0.025000,0.025000},{0.406250,0.931250,0.050000,0.050000},{0.418750,0.931250,0.025000,0.025000},{0.418750,0.931250,0.050000,0.050000},{0.431250,0.931250,0.025000,0.025000},{0.431250,0.931250,0.050000,0.050000},{0.443750,0.931250,0.025000,0.025000},{0.443750,0.931250,0.050000,0.050000},{0.456250,0.931250,0.025000,0.025000},{0.456250,0.931250,0.050000,0.050000},{0.468750,0.931250,0.025000,0.025000},{0.468750,0.931250,0.050000,0.050000},{0.481250,0.931250,0.025000,0.025000},{0.481250,0.931250,0.050000,0.050000},{0.493750,0.931250,0.025000,0.025000},{0.493750,0.931250,0.050000,0.050000},{0.506250,0.931250,0.025000,0.025000},{0.506250,0.931250,0.050000,0.050000},{0.518750,0.931250,0.025000,0.025000},{0.518750,0.931250,0.050000,0.050000},{0.531250,0.931250,0.025000,0.025000},{0.531250,0.931250,0.050000,0.050000},{0.543750,0.931250,0.025000,0.025000},{0.543750,0.931250,0.050000,0.050000},{0.556250,0.931250,0.025000,0.025000},{0.556250,0.931250,0.050000,0.050000},{0.568750,0.931250,0.025000,0.025000},{0.568750,0.931250,0.050000,0.050000},{0.581250,0.931250,0.025000,0.025000},{0.581250,0.931250,0.050000,0.050000},{0.593750,0.931250,0.025000,0.025000},{0.593750,0.931250,0.050000,0.050000},{0.606250,0.931250,0.025000,0.025000},{0.606250,0.931250,0.050000,0.050000},{0.618750,0.931250,0.025000,0.025000},{0.618750,0.931250,0.050000,0.050000},{0.631250,0.931250,0.025000,0.025000},{0.631250,0.931250,0.050000,0.050000},{0.643750,0.931250,0.025000,0.025000},{0.643750,0.931250,0.050000,0.050000},{0.656250,0.931250,0.025000,0.025000},{0.656250,0.931250,0.050000,0.050000},{0.668750,0.931250,0.025000,0.025000},{0.668750,0.931250,0.050000,0.050000},{0.681250,0.931250,0.025000,0.025000},{0.681250,0.931250,0.050000,0.050000},{0.693750,0.931250,0.025000,0.025000},{0.693750,0.931250,0.050000,0.050000},{0.706250,0.931250,0.025000,0.025000},{0.706250,0.931250,0.050000,0.050000},{0.718750,0.931250,0.025000,0.025000},{0.718750,0.931250,0.050000,0.050000},{0.731250,0.931250,0.025000,0.025000},{0.731250,0.931250,0.050000,0.050000},{0.743750,0.931250,0.025000,0.025000},{0.743750,0.931250,0.050000,0.050000},{0.756250,0.931250,0.025000,0.025000},{0.756250,0.931250,0.050000,0.050000},{0.768750,0.931250,0.025000,0.025000},{0.768750,0.931250,0.050000,0.050000},{0.781250,0.931250,0.025000,0.025000},{0.781250,0.931250,0.050000,0.050000},{0.793750,0.931250,0.025000,0.025000},{0.793750,0.931250,0.050000,0.050000},{0.806250,0.931250,0.025000,0.025000},{0.806250,0.931250,0.050000,0.050000},{0.818750,0.931250,0.025000,0.025000},{0.818750,0.931250,0.050000,0.050000},{0.831250,0.931250,0.025000,0.025000},{0.831250,0.931250,0.050000,0.050000},{0.843750,0.931250,0.025000,0.025000},{0.843750,0.931250,0.050000,0.050000},{0.856250,0.931250,0.025000,0.025000},{0.856250,0.931250,0.050000,0.050000},{0.868750,0.931250,0.025000,0.025000},{0.868750,0.931250,0.050000,0.050000},{0.881250,0.931250,0.025000,0.025000},{0.881250,0.931250,0.050000,0.050000},{0.893750,0.931250,0.025000,0.025000},{0.893750,0.931250,0.050000,0.050000},{0.906250,0.931250,0.025000,0.025000},{0.906250,0.931250,0.050000,0.050000},{0.918750,0.931250,0.025000,0.025000},{0.918750,0.931250,0.050000,0.050000},{0.931250,0.931250,0.025000,0.025000},{0.931250,0.931250,0.050000,0.050000},{0.943750,0.931250,0.025000,0.025000},{0.943750,0.931250,0.050000,0.050000},{0.956250,0.931250,0.025000,0.025000},{0.956250,0.931250,0.050000,0.050000},{0.968750,0.931250,0.025000,0.025000},{0.968750,0.931250,0.050000,0.050000},{0.981250,0.931250,0.025000,0.025000},{0.981250,0.931250,0.050000,0.050000},{0.993750,0.931250,0.025000,0.025000},{0.993750,0.931250,0.050000,0.050000},{0.006250,0.943750,0.025000,0.025000},{0.006250,0.943750,0.050000,0.050000},{0.018750,0.943750,0.025000,0.025000},{0.018750,0.943750,0.050000,0.050000},{0.031250,0.943750,0.025000,0.025000},{0.031250,0.943750,0.050000,0.050000},{0.043750,0.943750,0.025000,0.025000},{0.043750,0.943750,0.050000,0.050000},{0.056250,0.943750,0.025000,0.025000},{0.056250,0.943750,0.050000,0.050000},{0.068750,0.943750,0.025000,0.025000},{0.068750,0.943750,0.050000,0.050000},{0.081250,0.943750,0.025000,0.025000},{0.081250,0.943750,0.050000,0.050000},{0.093750,0.943750,0.025000,0.025000},{0.093750,0.943750,0.050000,0.050000},{0.106250,0.943750,0.025000,0.025000},{0.106250,0.943750,0.050000,0.050000},{0.118750,0.943750,0.025000,0.025000},{0.118750,0.943750,0.050000,0.050000},{0.131250,0.943750,0.025000,0.025000},{0.131250,0.943750,0.050000,0.050000},{0.143750,0.943750,0.025000,0.025000},{0.143750,0.943750,0.050000,0.050000},{0.156250,0.943750,0.025000,0.025000},{0.156250,0.943750,0.050000,0.050000},{0.168750,0.943750,0.025000,0.025000},{0.168750,0.943750,0.050000,0.050000},{0.181250,0.943750,0.025000,0.025000},{0.181250,0.943750,0.050000,0.050000},{0.193750,0.943750,0.025000,0.025000},{0.193750,0.943750,0.050000,0.050000},{0.206250,0.943750,0.025000,0.025000},{0.206250,0.943750,0.050000,0.050000},{0.218750,0.943750,0.025000,0.025000},{0.218750,0.943750,0.050000,0.050000},{0.231250,0.943750,0.025000,0.025000},{0.231250,0.943750,0.050000,0.050000},{0.243750,0.943750,0.025000,0.025000},{0.243750,0.943750,0.050000,0.050000},{0.256250,0.943750,0.025000,0.025000},{0.256250,0.943750,0.050000,0.050000},{0.268750,0.943750,0.025000,0.025000},{0.268750,0.943750,0.050000,0.050000},{0.281250,0.943750,0.025000,0.025000},{0.281250,0.943750,0.050000,0.050000},{0.293750,0.943750,0.025000,0.025000},{0.293750,0.943750,0.050000,0.050000},{0.306250,0.943750,0.025000,0.025000},{0.306250,0.943750,0.050000,0.050000},{0.318750,0.943750,0.025000,0.025000},{0.318750,0.943750,0.050000,0.050000},{0.331250,0.943750,0.025000,0.025000},{0.331250,0.943750,0.050000,0.050000},{0.343750,0.943750,0.025000,0.025000},{0.343750,0.943750,0.050000,0.050000},{0.356250,0.943750,0.025000,0.025000},{0.356250,0.943750,0.050000,0.050000},{0.368750,0.943750,0.025000,0.025000},{0.368750,0.943750,0.050000,0.050000},{0.381250,0.943750,0.025000,0.025000},{0.381250,0.943750,0.050000,0.050000},{0.393750,0.943750,0.025000,0.025000},{0.393750,0.943750,0.050000,0.050000},{0.406250,0.943750,0.025000,0.025000},{0.406250,0.943750,0.050000,0.050000},{0.418750,0.943750,0.025000,0.025000},{0.418750,0.943750,0.050000,0.050000},{0.431250,0.943750,0.025000,0.025000},{0.431250,0.943750,0.050000,0.050000},{0.443750,0.943750,0.025000,0.025000},{0.443750,0.943750,0.050000,0.050000},{0.456250,0.943750,0.025000,0.025000},{0.456250,0.943750,0.050000,0.050000},{0.468750,0.943750,0.025000,0.025000},{0.468750,0.943750,0.050000,0.050000},{0.481250,0.943750,0.025000,0.025000},{0.481250,0.943750,0.050000,0.050000},{0.493750,0.943750,0.025000,0.025000},{0.493750,0.943750,0.050000,0.050000},{0.506250,0.943750,0.025000,0.025000},{0.506250,0.943750,0.050000,0.050000},{0.518750,0.943750,0.025000,0.025000},{0.518750,0.943750,0.050000,0.050000},{0.531250,0.943750,0.025000,0.025000},{0.531250,0.943750,0.050000,0.050000},{0.543750,0.943750,0.025000,0.025000},{0.543750,0.943750,0.050000,0.050000},{0.556250,0.943750,0.025000,0.025000},{0.556250,0.943750,0.050000,0.050000},{0.568750,0.943750,0.025000,0.025000},{0.568750,0.943750,0.050000,0.050000},{0.581250,0.943750,0.025000,0.025000},{0.581250,0.943750,0.050000,0.050000},{0.593750,0.943750,0.025000,0.025000},{0.593750,0.943750,0.050000,0.050000},{0.606250,0.943750,0.025000,0.025000},{0.606250,0.943750,0.050000,0.050000},{0.618750,0.943750,0.025000,0.025000},{0.618750,0.943750,0.050000,0.050000},{0.631250,0.943750,0.025000,0.025000},{0.631250,0.943750,0.050000,0.050000},{0.643750,0.943750,0.025000,0.025000},{0.643750,0.943750,0.050000,0.050000},{0.656250,0.943750,0.025000,0.025000},{0.656250,0.943750,0.050000,0.050000},{0.668750,0.943750,0.025000,0.025000},{0.668750,0.943750,0.050000,0.050000},{0.681250,0.943750,0.025000,0.025000},{0.681250,0.943750,0.050000,0.050000},{0.693750,0.943750,0.025000,0.025000},{0.693750,0.943750,0.050000,0.050000},{0.706250,0.943750,0.025000,0.025000},{0.706250,0.943750,0.050000,0.050000},{0.718750,0.943750,0.025000,0.025000},{0.718750,0.943750,0.050000,0.050000},{0.731250,0.943750,0.025000,0.025000},{0.731250,0.943750,0.050000,0.050000},{0.743750,0.943750,0.025000,0.025000},{0.743750,0.943750,0.050000,0.050000},{0.756250,0.943750,0.025000,0.025000},{0.756250,0.943750,0.050000,0.050000},{0.768750,0.943750,0.025000,0.025000},{0.768750,0.943750,0.050000,0.050000},{0.781250,0.943750,0.025000,0.025000},{0.781250,0.943750,0.050000,0.050000},{0.793750,0.943750,0.025000,0.025000},{0.793750,0.943750,0.050000,0.050000},{0.806250,0.943750,0.025000,0.025000},{0.806250,0.943750,0.050000,0.050000},{0.818750,0.943750,0.025000,0.025000},{0.818750,0.943750,0.050000,0.050000},{0.831250,0.943750,0.025000,0.025000},{0.831250,0.943750,0.050000,0.050000},{0.843750,0.943750,0.025000,0.025000},{0.843750,0.943750,0.050000,0.050000},{0.856250,0.943750,0.025000,0.025000},{0.856250,0.943750,0.050000,0.050000},{0.868750,0.943750,0.025000,0.025000},{0.868750,0.943750,0.050000,0.050000},{0.881250,0.943750,0.025000,0.025000},{0.881250,0.943750,0.050000,0.050000},{0.893750,0.943750,0.025000,0.025000},{0.893750,0.943750,0.050000,0.050000},{0.906250,0.943750,0.025000,0.025000},{0.906250,0.943750,0.050000,0.050000},{0.918750,0.943750,0.025000,0.025000},{0.918750,0.943750,0.050000,0.050000},{0.931250,0.943750,0.025000,0.025000},{0.931250,0.943750,0.050000,0.050000},{0.943750,0.943750,0.025000,0.025000},{0.943750,0.943750,0.050000,0.050000},{0.956250,0.943750,0.025000,0.025000},{0.956250,0.943750,0.050000,0.050000},{0.968750,0.943750,0.025000,0.025000},{0.968750,0.943750,0.050000,0.050000},{0.981250,0.943750,0.025000,0.025000},{0.981250,0.943750,0.050000,0.050000},{0.993750,0.943750,0.025000,0.025000},{0.993750,0.943750,0.050000,0.050000},{0.006250,0.956250,0.025000,0.025000},{0.006250,0.956250,0.050000,0.050000},{0.018750,0.956250,0.025000,0.025000},{0.018750,0.956250,0.050000,0.050000},{0.031250,0.956250,0.025000,0.025000},{0.031250,0.956250,0.050000,0.050000},{0.043750,0.956250,0.025000,0.025000},{0.043750,0.956250,0.050000,0.050000},{0.056250,0.956250,0.025000,0.025000},{0.056250,0.956250,0.050000,0.050000},{0.068750,0.956250,0.025000,0.025000},{0.068750,0.956250,0.050000,0.050000},{0.081250,0.956250,0.025000,0.025000},{0.081250,0.956250,0.050000,0.050000},{0.093750,0.956250,0.025000,0.025000},{0.093750,0.956250,0.050000,0.050000},{0.106250,0.956250,0.025000,0.025000},{0.106250,0.956250,0.050000,0.050000},{0.118750,0.956250,0.025000,0.025000},{0.118750,0.956250,0.050000,0.050000},{0.131250,0.956250,0.025000,0.025000},{0.131250,0.956250,0.050000,0.050000},{0.143750,0.956250,0.025000,0.025000},{0.143750,0.956250,0.050000,0.050000},{0.156250,0.956250,0.025000,0.025000},{0.156250,0.956250,0.050000,0.050000},{0.168750,0.956250,0.025000,0.025000},{0.168750,0.956250,0.050000,0.050000},{0.181250,0.956250,0.025000,0.025000},{0.181250,0.956250,0.050000,0.050000},{0.193750,0.956250,0.025000,0.025000},{0.193750,0.956250,0.050000,0.050000},{0.206250,0.956250,0.025000,0.025000},{0.206250,0.956250,0.050000,0.050000},{0.218750,0.956250,0.025000,0.025000},{0.218750,0.956250,0.050000,0.050000},{0.231250,0.956250,0.025000,0.025000},{0.231250,0.956250,0.050000,0.050000},{0.243750,0.956250,0.025000,0.025000},{0.243750,0.956250,0.050000,0.050000},{0.256250,0.956250,0.025000,0.025000},{0.256250,0.956250,0.050000,0.050000},{0.268750,0.956250,0.025000,0.025000},{0.268750,0.956250,0.050000,0.050000},{0.281250,0.956250,0.025000,0.025000},{0.281250,0.956250,0.050000,0.050000},{0.293750,0.956250,0.025000,0.025000},{0.293750,0.956250,0.050000,0.050000},{0.306250,0.956250,0.025000,0.025000},{0.306250,0.956250,0.050000,0.050000},{0.318750,0.956250,0.025000,0.025000},{0.318750,0.956250,0.050000,0.050000},{0.331250,0.956250,0.025000,0.025000},{0.331250,0.956250,0.050000,0.050000},{0.343750,0.956250,0.025000,0.025000},{0.343750,0.956250,0.050000,0.050000},{0.356250,0.956250,0.025000,0.025000},{0.356250,0.956250,0.050000,0.050000},{0.368750,0.956250,0.025000,0.025000},{0.368750,0.956250,0.050000,0.050000},{0.381250,0.956250,0.025000,0.025000},{0.381250,0.956250,0.050000,0.050000},{0.393750,0.956250,0.025000,0.025000},{0.393750,0.956250,0.050000,0.050000},{0.406250,0.956250,0.025000,0.025000},{0.406250,0.956250,0.050000,0.050000},{0.418750,0.956250,0.025000,0.025000},{0.418750,0.956250,0.050000,0.050000},{0.431250,0.956250,0.025000,0.025000},{0.431250,0.956250,0.050000,0.050000},{0.443750,0.956250,0.025000,0.025000},{0.443750,0.956250,0.050000,0.050000},{0.456250,0.956250,0.025000,0.025000},{0.456250,0.956250,0.050000,0.050000},{0.468750,0.956250,0.025000,0.025000},{0.468750,0.956250,0.050000,0.050000},{0.481250,0.956250,0.025000,0.025000},{0.481250,0.956250,0.050000,0.050000},{0.493750,0.956250,0.025000,0.025000},{0.493750,0.956250,0.050000,0.050000},{0.506250,0.956250,0.025000,0.025000},{0.506250,0.956250,0.050000,0.050000},{0.518750,0.956250,0.025000,0.025000},{0.518750,0.956250,0.050000,0.050000},{0.531250,0.956250,0.025000,0.025000},{0.531250,0.956250,0.050000,0.050000},{0.543750,0.956250,0.025000,0.025000},{0.543750,0.956250,0.050000,0.050000},{0.556250,0.956250,0.025000,0.025000},{0.556250,0.956250,0.050000,0.050000},{0.568750,0.956250,0.025000,0.025000},{0.568750,0.956250,0.050000,0.050000},{0.581250,0.956250,0.025000,0.025000},{0.581250,0.956250,0.050000,0.050000},{0.593750,0.956250,0.025000,0.025000},{0.593750,0.956250,0.050000,0.050000},{0.606250,0.956250,0.025000,0.025000},{0.606250,0.956250,0.050000,0.050000},{0.618750,0.956250,0.025000,0.025000},{0.618750,0.956250,0.050000,0.050000},{0.631250,0.956250,0.025000,0.025000},{0.631250,0.956250,0.050000,0.050000},{0.643750,0.956250,0.025000,0.025000},{0.643750,0.956250,0.050000,0.050000},{0.656250,0.956250,0.025000,0.025000},{0.656250,0.956250,0.050000,0.050000},{0.668750,0.956250,0.025000,0.025000},{0.668750,0.956250,0.050000,0.050000},{0.681250,0.956250,0.025000,0.025000},{0.681250,0.956250,0.050000,0.050000},{0.693750,0.956250,0.025000,0.025000},{0.693750,0.956250,0.050000,0.050000},{0.706250,0.956250,0.025000,0.025000},{0.706250,0.956250,0.050000,0.050000},{0.718750,0.956250,0.025000,0.025000},{0.718750,0.956250,0.050000,0.050000},{0.731250,0.956250,0.025000,0.025000},{0.731250,0.956250,0.050000,0.050000},{0.743750,0.956250,0.025000,0.025000},{0.743750,0.956250,0.050000,0.050000},{0.756250,0.956250,0.025000,0.025000},{0.756250,0.956250,0.050000,0.050000},{0.768750,0.956250,0.025000,0.025000},{0.768750,0.956250,0.050000,0.050000},{0.781250,0.956250,0.025000,0.025000},{0.781250,0.956250,0.050000,0.050000},{0.793750,0.956250,0.025000,0.025000},{0.793750,0.956250,0.050000,0.050000},{0.806250,0.956250,0.025000,0.025000},{0.806250,0.956250,0.050000,0.050000},{0.818750,0.956250,0.025000,0.025000},{0.818750,0.956250,0.050000,0.050000},{0.831250,0.956250,0.025000,0.025000},{0.831250,0.956250,0.050000,0.050000},{0.843750,0.956250,0.025000,0.025000},{0.843750,0.956250,0.050000,0.050000},{0.856250,0.956250,0.025000,0.025000},{0.856250,0.956250,0.050000,0.050000},{0.868750,0.956250,0.025000,0.025000},{0.868750,0.956250,0.050000,0.050000},{0.881250,0.956250,0.025000,0.025000},{0.881250,0.956250,0.050000,0.050000},{0.893750,0.956250,0.025000,0.025000},{0.893750,0.956250,0.050000,0.050000},{0.906250,0.956250,0.025000,0.025000},{0.906250,0.956250,0.050000,0.050000},{0.918750,0.956250,0.025000,0.025000},{0.918750,0.956250,0.050000,0.050000},{0.931250,0.956250,0.025000,0.025000},{0.931250,0.956250,0.050000,0.050000},{0.943750,0.956250,0.025000,0.025000},{0.943750,0.956250,0.050000,0.050000},{0.956250,0.956250,0.025000,0.025000},{0.956250,0.956250,0.050000,0.050000},{0.968750,0.956250,0.025000,0.025000},{0.968750,0.956250,0.050000,0.050000},{0.981250,0.956250,0.025000,0.025000},{0.981250,0.956250,0.050000,0.050000},{0.993750,0.956250,0.025000,0.025000},{0.993750,0.956250,0.050000,0.050000},{0.006250,0.968750,0.025000,0.025000},{0.006250,0.968750,0.050000,0.050000},{0.018750,0.968750,0.025000,0.025000},{0.018750,0.968750,0.050000,0.050000},{0.031250,0.968750,0.025000,0.025000},{0.031250,0.968750,0.050000,0.050000},{0.043750,0.968750,0.025000,0.025000},{0.043750,0.968750,0.050000,0.050000},{0.056250,0.968750,0.025000,0.025000},{0.056250,0.968750,0.050000,0.050000},{0.068750,0.968750,0.025000,0.025000},{0.068750,0.968750,0.050000,0.050000},{0.081250,0.968750,0.025000,0.025000},{0.081250,0.968750,0.050000,0.050000},{0.093750,0.968750,0.025000,0.025000},{0.093750,0.968750,0.050000,0.050000},{0.106250,0.968750,0.025000,0.025000},{0.106250,0.968750,0.050000,0.050000},{0.118750,0.968750,0.025000,0.025000},{0.118750,0.968750,0.050000,0.050000},{0.131250,0.968750,0.025000,0.025000},{0.131250,0.968750,0.050000,0.050000},{0.143750,0.968750,0.025000,0.025000},{0.143750,0.968750,0.050000,0.050000},{0.156250,0.968750,0.025000,0.025000},{0.156250,0.968750,0.050000,0.050000},{0.168750,0.968750,0.025000,0.025000},{0.168750,0.968750,0.050000,0.050000},{0.181250,0.968750,0.025000,0.025000},{0.181250,0.968750,0.050000,0.050000},{0.193750,0.968750,0.025000,0.025000},{0.193750,0.968750,0.050000,0.050000},{0.206250,0.968750,0.025000,0.025000},{0.206250,0.968750,0.050000,0.050000},{0.218750,0.968750,0.025000,0.025000},{0.218750,0.968750,0.050000,0.050000},{0.231250,0.968750,0.025000,0.025000},{0.231250,0.968750,0.050000,0.050000},{0.243750,0.968750,0.025000,0.025000},{0.243750,0.968750,0.050000,0.050000},{0.256250,0.968750,0.025000,0.025000},{0.256250,0.968750,0.050000,0.050000},{0.268750,0.968750,0.025000,0.025000},{0.268750,0.968750,0.050000,0.050000},{0.281250,0.968750,0.025000,0.025000},{0.281250,0.968750,0.050000,0.050000},{0.293750,0.968750,0.025000,0.025000},{0.293750,0.968750,0.050000,0.050000},{0.306250,0.968750,0.025000,0.025000},{0.306250,0.968750,0.050000,0.050000},{0.318750,0.968750,0.025000,0.025000},{0.318750,0.968750,0.050000,0.050000},{0.331250,0.968750,0.025000,0.025000},{0.331250,0.968750,0.050000,0.050000},{0.343750,0.968750,0.025000,0.025000},{0.343750,0.968750,0.050000,0.050000},{0.356250,0.968750,0.025000,0.025000},{0.356250,0.968750,0.050000,0.050000},{0.368750,0.968750,0.025000,0.025000},{0.368750,0.968750,0.050000,0.050000},{0.381250,0.968750,0.025000,0.025000},{0.381250,0.968750,0.050000,0.050000},{0.393750,0.968750,0.025000,0.025000},{0.393750,0.968750,0.050000,0.050000},{0.406250,0.968750,0.025000,0.025000},{0.406250,0.968750,0.050000,0.050000},{0.418750,0.968750,0.025000,0.025000},{0.418750,0.968750,0.050000,0.050000},{0.431250,0.968750,0.025000,0.025000},{0.431250,0.968750,0.050000,0.050000},{0.443750,0.968750,0.025000,0.025000},{0.443750,0.968750,0.050000,0.050000},{0.456250,0.968750,0.025000,0.025000},{0.456250,0.968750,0.050000,0.050000},{0.468750,0.968750,0.025000,0.025000},{0.468750,0.968750,0.050000,0.050000},{0.481250,0.968750,0.025000,0.025000},{0.481250,0.968750,0.050000,0.050000},{0.493750,0.968750,0.025000,0.025000},{0.493750,0.968750,0.050000,0.050000},{0.506250,0.968750,0.025000,0.025000},{0.506250,0.968750,0.050000,0.050000},{0.518750,0.968750,0.025000,0.025000},{0.518750,0.968750,0.050000,0.050000},{0.531250,0.968750,0.025000,0.025000},{0.531250,0.968750,0.050000,0.050000},{0.543750,0.968750,0.025000,0.025000},{0.543750,0.968750,0.050000,0.050000},{0.556250,0.968750,0.025000,0.025000},{0.556250,0.968750,0.050000,0.050000},{0.568750,0.968750,0.025000,0.025000},{0.568750,0.968750,0.050000,0.050000},{0.581250,0.968750,0.025000,0.025000},{0.581250,0.968750,0.050000,0.050000},{0.593750,0.968750,0.025000,0.025000},{0.593750,0.968750,0.050000,0.050000},{0.606250,0.968750,0.025000,0.025000},{0.606250,0.968750,0.050000,0.050000},{0.618750,0.968750,0.025000,0.025000},{0.618750,0.968750,0.050000,0.050000},{0.631250,0.968750,0.025000,0.025000},{0.631250,0.968750,0.050000,0.050000},{0.643750,0.968750,0.025000,0.025000},{0.643750,0.968750,0.050000,0.050000},{0.656250,0.968750,0.025000,0.025000},{0.656250,0.968750,0.050000,0.050000},{0.668750,0.968750,0.025000,0.025000},{0.668750,0.968750,0.050000,0.050000},{0.681250,0.968750,0.025000,0.025000},{0.681250,0.968750,0.050000,0.050000},{0.693750,0.968750,0.025000,0.025000},{0.693750,0.968750,0.050000,0.050000},{0.706250,0.968750,0.025000,0.025000},{0.706250,0.968750,0.050000,0.050000},{0.718750,0.968750,0.025000,0.025000},{0.718750,0.968750,0.050000,0.050000},{0.731250,0.968750,0.025000,0.025000},{0.731250,0.968750,0.050000,0.050000},{0.743750,0.968750,0.025000,0.025000},{0.743750,0.968750,0.050000,0.050000},{0.756250,0.968750,0.025000,0.025000},{0.756250,0.968750,0.050000,0.050000},{0.768750,0.968750,0.025000,0.025000},{0.768750,0.968750,0.050000,0.050000},{0.781250,0.968750,0.025000,0.025000},{0.781250,0.968750,0.050000,0.050000},{0.793750,0.968750,0.025000,0.025000},{0.793750,0.968750,0.050000,0.050000},{0.806250,0.968750,0.025000,0.025000},{0.806250,0.968750,0.050000,0.050000},{0.818750,0.968750,0.025000,0.025000},{0.818750,0.968750,0.050000,0.050000},{0.831250,0.968750,0.025000,0.025000},{0.831250,0.968750,0.050000,0.050000},{0.843750,0.968750,0.025000,0.025000},{0.843750,0.968750,0.050000,0.050000},{0.856250,0.968750,0.025000,0.025000},{0.856250,0.968750,0.050000,0.050000},{0.868750,0.968750,0.025000,0.025000},{0.868750,0.968750,0.050000,0.050000},{0.881250,0.968750,0.025000,0.025000},{0.881250,0.968750,0.050000,0.050000},{0.893750,0.968750,0.025000,0.025000},{0.893750,0.968750,0.050000,0.050000},{0.906250,0.968750,0.025000,0.025000},{0.906250,0.968750,0.050000,0.050000},{0.918750,0.968750,0.025000,0.025000},{0.918750,0.968750,0.050000,0.050000},{0.931250,0.968750,0.025000,0.025000},{0.931250,0.968750,0.050000,0.050000},{0.943750,0.968750,0.025000,0.025000},{0.943750,0.968750,0.050000,0.050000},{0.956250,0.968750,0.025000,0.025000},{0.956250,0.968750,0.050000,0.050000},{0.968750,0.968750,0.025000,0.025000},{0.968750,0.968750,0.050000,0.050000},{0.981250,0.968750,0.025000,0.025000},{0.981250,0.968750,0.050000,0.050000},{0.993750,0.968750,0.025000,0.025000},{0.993750,0.968750,0.050000,0.050000},{0.006250,0.981250,0.025000,0.025000},{0.006250,0.981250,0.050000,0.050000},{0.018750,0.981250,0.025000,0.025000},{0.018750,0.981250,0.050000,0.050000},{0.031250,0.981250,0.025000,0.025000},{0.031250,0.981250,0.050000,0.050000},{0.043750,0.981250,0.025000,0.025000},{0.043750,0.981250,0.050000,0.050000},{0.056250,0.981250,0.025000,0.025000},{0.056250,0.981250,0.050000,0.050000},{0.068750,0.981250,0.025000,0.025000},{0.068750,0.981250,0.050000,0.050000},{0.081250,0.981250,0.025000,0.025000},{0.081250,0.981250,0.050000,0.050000},{0.093750,0.981250,0.025000,0.025000},{0.093750,0.981250,0.050000,0.050000},{0.106250,0.981250,0.025000,0.025000},{0.106250,0.981250,0.050000,0.050000},{0.118750,0.981250,0.025000,0.025000},{0.118750,0.981250,0.050000,0.050000},{0.131250,0.981250,0.025000,0.025000},{0.131250,0.981250,0.050000,0.050000},{0.143750,0.981250,0.025000,0.025000},{0.143750,0.981250,0.050000,0.050000},{0.156250,0.981250,0.025000,0.025000},{0.156250,0.981250,0.050000,0.050000},{0.168750,0.981250,0.025000,0.025000},{0.168750,0.981250,0.050000,0.050000},{0.181250,0.981250,0.025000,0.025000},{0.181250,0.981250,0.050000,0.050000},{0.193750,0.981250,0.025000,0.025000},{0.193750,0.981250,0.050000,0.050000},{0.206250,0.981250,0.025000,0.025000},{0.206250,0.981250,0.050000,0.050000},{0.218750,0.981250,0.025000,0.025000},{0.218750,0.981250,0.050000,0.050000},{0.231250,0.981250,0.025000,0.025000},{0.231250,0.981250,0.050000,0.050000},{0.243750,0.981250,0.025000,0.025000},{0.243750,0.981250,0.050000,0.050000},{0.256250,0.981250,0.025000,0.025000},{0.256250,0.981250,0.050000,0.050000},{0.268750,0.981250,0.025000,0.025000},{0.268750,0.981250,0.050000,0.050000},{0.281250,0.981250,0.025000,0.025000},{0.281250,0.981250,0.050000,0.050000},{0.293750,0.981250,0.025000,0.025000},{0.293750,0.981250,0.050000,0.050000},{0.306250,0.981250,0.025000,0.025000},{0.306250,0.981250,0.050000,0.050000},{0.318750,0.981250,0.025000,0.025000},{0.318750,0.981250,0.050000,0.050000},{0.331250,0.981250,0.025000,0.025000},{0.331250,0.981250,0.050000,0.050000},{0.343750,0.981250,0.025000,0.025000},{0.343750,0.981250,0.050000,0.050000},{0.356250,0.981250,0.025000,0.025000},{0.356250,0.981250,0.050000,0.050000},{0.368750,0.981250,0.025000,0.025000},{0.368750,0.981250,0.050000,0.050000},{0.381250,0.981250,0.025000,0.025000},{0.381250,0.981250,0.050000,0.050000},{0.393750,0.981250,0.025000,0.025000},{0.393750,0.981250,0.050000,0.050000},{0.406250,0.981250,0.025000,0.025000},{0.406250,0.981250,0.050000,0.050000},{0.418750,0.981250,0.025000,0.025000},{0.418750,0.981250,0.050000,0.050000},{0.431250,0.981250,0.025000,0.025000},{0.431250,0.981250,0.050000,0.050000},{0.443750,0.981250,0.025000,0.025000},{0.443750,0.981250,0.050000,0.050000},{0.456250,0.981250,0.025000,0.025000},{0.456250,0.981250,0.050000,0.050000},{0.468750,0.981250,0.025000,0.025000},{0.468750,0.981250,0.050000,0.050000},{0.481250,0.981250,0.025000,0.025000},{0.481250,0.981250,0.050000,0.050000},{0.493750,0.981250,0.025000,0.025000},{0.493750,0.981250,0.050000,0.050000},{0.506250,0.981250,0.025000,0.025000},{0.506250,0.981250,0.050000,0.050000},{0.518750,0.981250,0.025000,0.025000},{0.518750,0.981250,0.050000,0.050000},{0.531250,0.981250,0.025000,0.025000},{0.531250,0.981250,0.050000,0.050000},{0.543750,0.981250,0.025000,0.025000},{0.543750,0.981250,0.050000,0.050000},{0.556250,0.981250,0.025000,0.025000},{0.556250,0.981250,0.050000,0.050000},{0.568750,0.981250,0.025000,0.025000},{0.568750,0.981250,0.050000,0.050000},{0.581250,0.981250,0.025000,0.025000},{0.581250,0.981250,0.050000,0.050000},{0.593750,0.981250,0.025000,0.025000},{0.593750,0.981250,0.050000,0.050000},{0.606250,0.981250,0.025000,0.025000},{0.606250,0.981250,0.050000,0.050000},{0.618750,0.981250,0.025000,0.025000},{0.618750,0.981250,0.050000,0.050000},{0.631250,0.981250,0.025000,0.025000},{0.631250,0.981250,0.050000,0.050000},{0.643750,0.981250,0.025000,0.025000},{0.643750,0.981250,0.050000,0.050000},{0.656250,0.981250,0.025000,0.025000},{0.656250,0.981250,0.050000,0.050000},{0.668750,0.981250,0.025000,0.025000},{0.668750,0.981250,0.050000,0.050000},{0.681250,0.981250,0.025000,0.025000},{0.681250,0.981250,0.050000,0.050000},{0.693750,0.981250,0.025000,0.025000},{0.693750,0.981250,0.050000,0.050000},{0.706250,0.981250,0.025000,0.025000},{0.706250,0.981250,0.050000,0.050000},{0.718750,0.981250,0.025000,0.025000},{0.718750,0.981250,0.050000,0.050000},{0.731250,0.981250,0.025000,0.025000},{0.731250,0.981250,0.050000,0.050000},{0.743750,0.981250,0.025000,0.025000},{0.743750,0.981250,0.050000,0.050000},{0.756250,0.981250,0.025000,0.025000},{0.756250,0.981250,0.050000,0.050000},{0.768750,0.981250,0.025000,0.025000},{0.768750,0.981250,0.050000,0.050000},{0.781250,0.981250,0.025000,0.025000},{0.781250,0.981250,0.050000,0.050000},{0.793750,0.981250,0.025000,0.025000},{0.793750,0.981250,0.050000,0.050000},{0.806250,0.981250,0.025000,0.025000},{0.806250,0.981250,0.050000,0.050000},{0.818750,0.981250,0.025000,0.025000},{0.818750,0.981250,0.050000,0.050000},{0.831250,0.981250,0.025000,0.025000},{0.831250,0.981250,0.050000,0.050000},{0.843750,0.981250,0.025000,0.025000},{0.843750,0.981250,0.050000,0.050000},{0.856250,0.981250,0.025000,0.025000},{0.856250,0.981250,0.050000,0.050000},{0.868750,0.981250,0.025000,0.025000},{0.868750,0.981250,0.050000,0.050000},{0.881250,0.981250,0.025000,0.025000},{0.881250,0.981250,0.050000,0.050000},{0.893750,0.981250,0.025000,0.025000},{0.893750,0.981250,0.050000,0.050000},{0.906250,0.981250,0.025000,0.025000},{0.906250,0.981250,0.050000,0.050000},{0.918750,0.981250,0.025000,0.025000},{0.918750,0.981250,0.050000,0.050000},{0.931250,0.981250,0.025000,0.025000},{0.931250,0.981250,0.050000,0.050000},{0.943750,0.981250,0.025000,0.025000},{0.943750,0.981250,0.050000,0.050000},{0.956250,0.981250,0.025000,0.025000},{0.956250,0.981250,0.050000,0.050000},{0.968750,0.981250,0.025000,0.025000},{0.968750,0.981250,0.050000,0.050000},{0.981250,0.981250,0.025000,0.025000},{0.981250,0.981250,0.050000,0.050000},{0.993750,0.981250,0.025000,0.025000},{0.993750,0.981250,0.050000,0.050000},{0.006250,0.993750,0.025000,0.025000},{0.006250,0.993750,0.050000,0.050000},{0.018750,0.993750,0.025000,0.025000},{0.018750,0.993750,0.050000,0.050000},{0.031250,0.993750,0.025000,0.025000},{0.031250,0.993750,0.050000,0.050000},{0.043750,0.993750,0.025000,0.025000},{0.043750,0.993750,0.050000,0.050000},{0.056250,0.993750,0.025000,0.025000},{0.056250,0.993750,0.050000,0.050000},{0.068750,0.993750,0.025000,0.025000},{0.068750,0.993750,0.050000,0.050000},{0.081250,0.993750,0.025000,0.025000},{0.081250,0.993750,0.050000,0.050000},{0.093750,0.993750,0.025000,0.025000},{0.093750,0.993750,0.050000,0.050000},{0.106250,0.993750,0.025000,0.025000},{0.106250,0.993750,0.050000,0.050000},{0.118750,0.993750,0.025000,0.025000},{0.118750,0.993750,0.050000,0.050000},{0.131250,0.993750,0.025000,0.025000},{0.131250,0.993750,0.050000,0.050000},{0.143750,0.993750,0.025000,0.025000},{0.143750,0.993750,0.050000,0.050000},{0.156250,0.993750,0.025000,0.025000},{0.156250,0.993750,0.050000,0.050000},{0.168750,0.993750,0.025000,0.025000},{0.168750,0.993750,0.050000,0.050000},{0.181250,0.993750,0.025000,0.025000},{0.181250,0.993750,0.050000,0.050000},{0.193750,0.993750,0.025000,0.025000},{0.193750,0.993750,0.050000,0.050000},{0.206250,0.993750,0.025000,0.025000},{0.206250,0.993750,0.050000,0.050000},{0.218750,0.993750,0.025000,0.025000},{0.218750,0.993750,0.050000,0.050000},{0.231250,0.993750,0.025000,0.025000},{0.231250,0.993750,0.050000,0.050000},{0.243750,0.993750,0.025000,0.025000},{0.243750,0.993750,0.050000,0.050000},{0.256250,0.993750,0.025000,0.025000},{0.256250,0.993750,0.050000,0.050000},{0.268750,0.993750,0.025000,0.025000},{0.268750,0.993750,0.050000,0.050000},{0.281250,0.993750,0.025000,0.025000},{0.281250,0.993750,0.050000,0.050000},{0.293750,0.993750,0.025000,0.025000},{0.293750,0.993750,0.050000,0.050000},{0.306250,0.993750,0.025000,0.025000},{0.306250,0.993750,0.050000,0.050000},{0.318750,0.993750,0.025000,0.025000},{0.318750,0.993750,0.050000,0.050000},{0.331250,0.993750,0.025000,0.025000},{0.331250,0.993750,0.050000,0.050000},{0.343750,0.993750,0.025000,0.025000},{0.343750,0.993750,0.050000,0.050000},{0.356250,0.993750,0.025000,0.025000},{0.356250,0.993750,0.050000,0.050000},{0.368750,0.993750,0.025000,0.025000},{0.368750,0.993750,0.050000,0.050000},{0.381250,0.993750,0.025000,0.025000},{0.381250,0.993750,0.050000,0.050000},{0.393750,0.993750,0.025000,0.025000},{0.393750,0.993750,0.050000,0.050000},{0.406250,0.993750,0.025000,0.025000},{0.406250,0.993750,0.050000,0.050000},{0.418750,0.993750,0.025000,0.025000},{0.418750,0.993750,0.050000,0.050000},{0.431250,0.993750,0.025000,0.025000},{0.431250,0.993750,0.050000,0.050000},{0.443750,0.993750,0.025000,0.025000},{0.443750,0.993750,0.050000,0.050000},{0.456250,0.993750,0.025000,0.025000},{0.456250,0.993750,0.050000,0.050000},{0.468750,0.993750,0.025000,0.025000},{0.468750,0.993750,0.050000,0.050000},{0.481250,0.993750,0.025000,0.025000},{0.481250,0.993750,0.050000,0.050000},{0.493750,0.993750,0.025000,0.025000},{0.493750,0.993750,0.050000,0.050000},{0.506250,0.993750,0.025000,0.025000},{0.506250,0.993750,0.050000,0.050000},{0.518750,0.993750,0.025000,0.025000},{0.518750,0.993750,0.050000,0.050000},{0.531250,0.993750,0.025000,0.025000},{0.531250,0.993750,0.050000,0.050000},{0.543750,0.993750,0.025000,0.025000},{0.543750,0.993750,0.050000,0.050000},{0.556250,0.993750,0.025000,0.025000},{0.556250,0.993750,0.050000,0.050000},{0.568750,0.993750,0.025000,0.025000},{0.568750,0.993750,0.050000,0.050000},{0.581250,0.993750,0.025000,0.025000},{0.581250,0.993750,0.050000,0.050000},{0.593750,0.993750,0.025000,0.025000},{0.593750,0.993750,0.050000,0.050000},{0.606250,0.993750,0.025000,0.025000},{0.606250,0.993750,0.050000,0.050000},{0.618750,0.993750,0.025000,0.025000},{0.618750,0.993750,0.050000,0.050000},{0.631250,0.993750,0.025000,0.025000},{0.631250,0.993750,0.050000,0.050000},{0.643750,0.993750,0.025000,0.025000},{0.643750,0.993750,0.050000,0.050000},{0.656250,0.993750,0.025000,0.025000},{0.656250,0.993750,0.050000,0.050000},{0.668750,0.993750,0.025000,0.025000},{0.668750,0.993750,0.050000,0.050000},{0.681250,0.993750,0.025000,0.025000},{0.681250,0.993750,0.050000,0.050000},{0.693750,0.993750,0.025000,0.025000},{0.693750,0.993750,0.050000,0.050000},{0.706250,0.993750,0.025000,0.025000},{0.706250,0.993750,0.050000,0.050000},{0.718750,0.993750,0.025000,0.025000},{0.718750,0.993750,0.050000,0.050000},{0.731250,0.993750,0.025000,0.025000},{0.731250,0.993750,0.050000,0.050000},{0.743750,0.993750,0.025000,0.025000},{0.743750,0.993750,0.050000,0.050000},{0.756250,0.993750,0.025000,0.025000},{0.756250,0.993750,0.050000,0.050000},{0.768750,0.993750,0.025000,0.025000},{0.768750,0.993750,0.050000,0.050000},{0.781250,0.993750,0.025000,0.025000},{0.781250,0.993750,0.050000,0.050000},{0.793750,0.993750,0.025000,0.025000},{0.793750,0.993750,0.050000,0.050000},{0.806250,0.993750,0.025000,0.025000},{0.806250,0.993750,0.050000,0.050000},{0.818750,0.993750,0.025000,0.025000},{0.818750,0.993750,0.050000,0.050000},{0.831250,0.993750,0.025000,0.025000},{0.831250,0.993750,0.050000,0.050000},{0.843750,0.993750,0.025000,0.025000},{0.843750,0.993750,0.050000,0.050000},{0.856250,0.993750,0.025000,0.025000},{0.856250,0.993750,0.050000,0.050000},{0.868750,0.993750,0.025000,0.025000},{0.868750,0.993750,0.050000,0.050000},{0.881250,0.993750,0.025000,0.025000},{0.881250,0.993750,0.050000,0.050000},{0.893750,0.993750,0.025000,0.025000},{0.893750,0.993750,0.050000,0.050000},{0.906250,0.993750,0.025000,0.025000},{0.906250,0.993750,0.050000,0.050000},{0.918750,0.993750,0.025000,0.025000},{0.918750,0.993750,0.050000,0.050000},{0.931250,0.993750,0.025000,0.025000},{0.931250,0.993750,0.050000,0.050000},{0.943750,0.993750,0.025000,0.025000},{0.943750,0.993750,0.050000,0.050000},{0.956250,0.993750,0.025000,0.025000},{0.956250,0.993750,0.050000,0.050000},{0.968750,0.993750,0.025000,0.025000},{0.968750,0.993750,0.050000,0.050000},{0.981250,0.993750,0.025000,0.025000},{0.981250,0.993750,0.050000,0.050000},{0.993750,0.993750,0.025000,0.025000},{0.993750,0.993750,0.050000,0.050000},{0.012500,0.012500,0.100000,0.100000},{0.012500,0.012500,0.200000,0.200000},{0.037500,0.012500,0.100000,0.100000},{0.037500,0.012500,0.200000,0.200000},{0.062500,0.012500,0.100000,0.100000},{0.062500,0.012500,0.200000,0.200000},{0.087500,0.012500,0.100000,0.100000},{0.087500,0.012500,0.200000,0.200000},{0.112500,0.012500,0.100000,0.100000},{0.112500,0.012500,0.200000,0.200000},{0.137500,0.012500,0.100000,0.100000},{0.137500,0.012500,0.200000,0.200000},{0.162500,0.012500,0.100000,0.100000},{0.162500,0.012500,0.200000,0.200000},{0.187500,0.012500,0.100000,0.100000},{0.187500,0.012500,0.200000,0.200000},{0.212500,0.012500,0.100000,0.100000},{0.212500,0.012500,0.200000,0.200000},{0.237500,0.012500,0.100000,0.100000},{0.237500,0.012500,0.200000,0.200000},{0.262500,0.012500,0.100000,0.100000},{0.262500,0.012500,0.200000,0.200000},{0.287500,0.012500,0.100000,0.100000},{0.287500,0.012500,0.200000,0.200000},{0.312500,0.012500,0.100000,0.100000},{0.312500,0.012500,0.200000,0.200000},{0.337500,0.012500,0.100000,0.100000},{0.337500,0.012500,0.200000,0.200000},{0.362500,0.012500,0.100000,0.100000},{0.362500,0.012500,0.200000,0.200000},{0.387500,0.012500,0.100000,0.100000},{0.387500,0.012500,0.200000,0.200000},{0.412500,0.012500,0.100000,0.100000},{0.412500,0.012500,0.200000,0.200000},{0.437500,0.012500,0.100000,0.100000},{0.437500,0.012500,0.200000,0.200000},{0.462500,0.012500,0.100000,0.100000},{0.462500,0.012500,0.200000,0.200000},{0.487500,0.012500,0.100000,0.100000},{0.487500,0.012500,0.200000,0.200000},{0.512500,0.012500,0.100000,0.100000},{0.512500,0.012500,0.200000,0.200000},{0.537500,0.012500,0.100000,0.100000},{0.537500,0.012500,0.200000,0.200000},{0.562500,0.012500,0.100000,0.100000},{0.562500,0.012500,0.200000,0.200000},{0.587500,0.012500,0.100000,0.100000},{0.587500,0.012500,0.200000,0.200000},{0.612500,0.012500,0.100000,0.100000},{0.612500,0.012500,0.200000,0.200000},{0.637500,0.012500,0.100000,0.100000},{0.637500,0.012500,0.200000,0.200000},{0.662500,0.012500,0.100000,0.100000},{0.662500,0.012500,0.200000,0.200000},{0.687500,0.012500,0.100000,0.100000},{0.687500,0.012500,0.200000,0.200000},{0.712500,0.012500,0.100000,0.100000},{0.712500,0.012500,0.200000,0.200000},{0.737500,0.012500,0.100000,0.100000},{0.737500,0.012500,0.200000,0.200000},{0.762500,0.012500,0.100000,0.100000},{0.762500,0.012500,0.200000,0.200000},{0.787500,0.012500,0.100000,0.100000},{0.787500,0.012500,0.200000,0.200000},{0.812500,0.012500,0.100000,0.100000},{0.812500,0.012500,0.200000,0.200000},{0.837500,0.012500,0.100000,0.100000},{0.837500,0.012500,0.200000,0.200000},{0.862500,0.012500,0.100000,0.100000},{0.862500,0.012500,0.200000,0.200000},{0.887500,0.012500,0.100000,0.100000},{0.887500,0.012500,0.200000,0.200000},{0.912500,0.012500,0.100000,0.100000},{0.912500,0.012500,0.200000,0.200000},{0.937500,0.012500,0.100000,0.100000},{0.937500,0.012500,0.200000,0.200000},{0.962500,0.012500,0.100000,0.100000},{0.962500,0.012500,0.200000,0.200000},{0.987500,0.012500,0.100000,0.100000},{0.987500,0.012500,0.200000,0.200000},{0.012500,0.037500,0.100000,0.100000},{0.012500,0.037500,0.200000,0.200000},{0.037500,0.037500,0.100000,0.100000},{0.037500,0.037500,0.200000,0.200000},{0.062500,0.037500,0.100000,0.100000},{0.062500,0.037500,0.200000,0.200000},{0.087500,0.037500,0.100000,0.100000},{0.087500,0.037500,0.200000,0.200000},{0.112500,0.037500,0.100000,0.100000},{0.112500,0.037500,0.200000,0.200000},{0.137500,0.037500,0.100000,0.100000},{0.137500,0.037500,0.200000,0.200000},{0.162500,0.037500,0.100000,0.100000},{0.162500,0.037500,0.200000,0.200000},{0.187500,0.037500,0.100000,0.100000},{0.187500,0.037500,0.200000,0.200000},{0.212500,0.037500,0.100000,0.100000},{0.212500,0.037500,0.200000,0.200000},{0.237500,0.037500,0.100000,0.100000},{0.237500,0.037500,0.200000,0.200000},{0.262500,0.037500,0.100000,0.100000},{0.262500,0.037500,0.200000,0.200000},{0.287500,0.037500,0.100000,0.100000},{0.287500,0.037500,0.200000,0.200000},{0.312500,0.037500,0.100000,0.100000},{0.312500,0.037500,0.200000,0.200000},{0.337500,0.037500,0.100000,0.100000},{0.337500,0.037500,0.200000,0.200000},{0.362500,0.037500,0.100000,0.100000},{0.362500,0.037500,0.200000,0.200000},{0.387500,0.037500,0.100000,0.100000},{0.387500,0.037500,0.200000,0.200000},{0.412500,0.037500,0.100000,0.100000},{0.412500,0.037500,0.200000,0.200000},{0.437500,0.037500,0.100000,0.100000},{0.437500,0.037500,0.200000,0.200000},{0.462500,0.037500,0.100000,0.100000},{0.462500,0.037500,0.200000,0.200000},{0.487500,0.037500,0.100000,0.100000},{0.487500,0.037500,0.200000,0.200000},{0.512500,0.037500,0.100000,0.100000},{0.512500,0.037500,0.200000,0.200000},{0.537500,0.037500,0.100000,0.100000},{0.537500,0.037500,0.200000,0.200000},{0.562500,0.037500,0.100000,0.100000},{0.562500,0.037500,0.200000,0.200000},{0.587500,0.037500,0.100000,0.100000},{0.587500,0.037500,0.200000,0.200000},{0.612500,0.037500,0.100000,0.100000},{0.612500,0.037500,0.200000,0.200000},{0.637500,0.037500,0.100000,0.100000},{0.637500,0.037500,0.200000,0.200000},{0.662500,0.037500,0.100000,0.100000},{0.662500,0.037500,0.200000,0.200000},{0.687500,0.037500,0.100000,0.100000},{0.687500,0.037500,0.200000,0.200000},{0.712500,0.037500,0.100000,0.100000},{0.712500,0.037500,0.200000,0.200000},{0.737500,0.037500,0.100000,0.100000},{0.737500,0.037500,0.200000,0.200000},{0.762500,0.037500,0.100000,0.100000},{0.762500,0.037500,0.200000,0.200000},{0.787500,0.037500,0.100000,0.100000},{0.787500,0.037500,0.200000,0.200000},{0.812500,0.037500,0.100000,0.100000},{0.812500,0.037500,0.200000,0.200000},{0.837500,0.037500,0.100000,0.100000},{0.837500,0.037500,0.200000,0.200000},{0.862500,0.037500,0.100000,0.100000},{0.862500,0.037500,0.200000,0.200000},{0.887500,0.037500,0.100000,0.100000},{0.887500,0.037500,0.200000,0.200000},{0.912500,0.037500,0.100000,0.100000},{0.912500,0.037500,0.200000,0.200000},{0.937500,0.037500,0.100000,0.100000},{0.937500,0.037500,0.200000,0.200000},{0.962500,0.037500,0.100000,0.100000},{0.962500,0.037500,0.200000,0.200000},{0.987500,0.037500,0.100000,0.100000},{0.987500,0.037500,0.200000,0.200000},{0.012500,0.062500,0.100000,0.100000},{0.012500,0.062500,0.200000,0.200000},{0.037500,0.062500,0.100000,0.100000},{0.037500,0.062500,0.200000,0.200000},{0.062500,0.062500,0.100000,0.100000},{0.062500,0.062500,0.200000,0.200000},{0.087500,0.062500,0.100000,0.100000},{0.087500,0.062500,0.200000,0.200000},{0.112500,0.062500,0.100000,0.100000},{0.112500,0.062500,0.200000,0.200000},{0.137500,0.062500,0.100000,0.100000},{0.137500,0.062500,0.200000,0.200000},{0.162500,0.062500,0.100000,0.100000},{0.162500,0.062500,0.200000,0.200000},{0.187500,0.062500,0.100000,0.100000},{0.187500,0.062500,0.200000,0.200000},{0.212500,0.062500,0.100000,0.100000},{0.212500,0.062500,0.200000,0.200000},{0.237500,0.062500,0.100000,0.100000},{0.237500,0.062500,0.200000,0.200000},{0.262500,0.062500,0.100000,0.100000},{0.262500,0.062500,0.200000,0.200000},{0.287500,0.062500,0.100000,0.100000},{0.287500,0.062500,0.200000,0.200000},{0.312500,0.062500,0.100000,0.100000},{0.312500,0.062500,0.200000,0.200000},{0.337500,0.062500,0.100000,0.100000},{0.337500,0.062500,0.200000,0.200000},{0.362500,0.062500,0.100000,0.100000},{0.362500,0.062500,0.200000,0.200000},{0.387500,0.062500,0.100000,0.100000},{0.387500,0.062500,0.200000,0.200000},{0.412500,0.062500,0.100000,0.100000},{0.412500,0.062500,0.200000,0.200000},{0.437500,0.062500,0.100000,0.100000},{0.437500,0.062500,0.200000,0.200000},{0.462500,0.062500,0.100000,0.100000},{0.462500,0.062500,0.200000,0.200000},{0.487500,0.062500,0.100000,0.100000},{0.487500,0.062500,0.200000,0.200000},{0.512500,0.062500,0.100000,0.100000},{0.512500,0.062500,0.200000,0.200000},{0.537500,0.062500,0.100000,0.100000},{0.537500,0.062500,0.200000,0.200000},{0.562500,0.062500,0.100000,0.100000},{0.562500,0.062500,0.200000,0.200000},{0.587500,0.062500,0.100000,0.100000},{0.587500,0.062500,0.200000,0.200000},{0.612500,0.062500,0.100000,0.100000},{0.612500,0.062500,0.200000,0.200000},{0.637500,0.062500,0.100000,0.100000},{0.637500,0.062500,0.200000,0.200000},{0.662500,0.062500,0.100000,0.100000},{0.662500,0.062500,0.200000,0.200000},{0.687500,0.062500,0.100000,0.100000},{0.687500,0.062500,0.200000,0.200000},{0.712500,0.062500,0.100000,0.100000},{0.712500,0.062500,0.200000,0.200000},{0.737500,0.062500,0.100000,0.100000},{0.737500,0.062500,0.200000,0.200000},{0.762500,0.062500,0.100000,0.100000},{0.762500,0.062500,0.200000,0.200000},{0.787500,0.062500,0.100000,0.100000},{0.787500,0.062500,0.200000,0.200000},{0.812500,0.062500,0.100000,0.100000},{0.812500,0.062500,0.200000,0.200000},{0.837500,0.062500,0.100000,0.100000},{0.837500,0.062500,0.200000,0.200000},{0.862500,0.062500,0.100000,0.100000},{0.862500,0.062500,0.200000,0.200000},{0.887500,0.062500,0.100000,0.100000},{0.887500,0.062500,0.200000,0.200000},{0.912500,0.062500,0.100000,0.100000},{0.912500,0.062500,0.200000,0.200000},{0.937500,0.062500,0.100000,0.100000},{0.937500,0.062500,0.200000,0.200000},{0.962500,0.062500,0.100000,0.100000},{0.962500,0.062500,0.200000,0.200000},{0.987500,0.062500,0.100000,0.100000},{0.987500,0.062500,0.200000,0.200000},{0.012500,0.087500,0.100000,0.100000},{0.012500,0.087500,0.200000,0.200000},{0.037500,0.087500,0.100000,0.100000},{0.037500,0.087500,0.200000,0.200000},{0.062500,0.087500,0.100000,0.100000},{0.062500,0.087500,0.200000,0.200000},{0.087500,0.087500,0.100000,0.100000},{0.087500,0.087500,0.200000,0.200000},{0.112500,0.087500,0.100000,0.100000},{0.112500,0.087500,0.200000,0.200000},{0.137500,0.087500,0.100000,0.100000},{0.137500,0.087500,0.200000,0.200000},{0.162500,0.087500,0.100000,0.100000},{0.162500,0.087500,0.200000,0.200000},{0.187500,0.087500,0.100000,0.100000},{0.187500,0.087500,0.200000,0.200000},{0.212500,0.087500,0.100000,0.100000},{0.212500,0.087500,0.200000,0.200000},{0.237500,0.087500,0.100000,0.100000},{0.237500,0.087500,0.200000,0.200000},{0.262500,0.087500,0.100000,0.100000},{0.262500,0.087500,0.200000,0.200000},{0.287500,0.087500,0.100000,0.100000},{0.287500,0.087500,0.200000,0.200000},{0.312500,0.087500,0.100000,0.100000},{0.312500,0.087500,0.200000,0.200000},{0.337500,0.087500,0.100000,0.100000},{0.337500,0.087500,0.200000,0.200000},{0.362500,0.087500,0.100000,0.100000},{0.362500,0.087500,0.200000,0.200000},{0.387500,0.087500,0.100000,0.100000},{0.387500,0.087500,0.200000,0.200000},{0.412500,0.087500,0.100000,0.100000},{0.412500,0.087500,0.200000,0.200000},{0.437500,0.087500,0.100000,0.100000},{0.437500,0.087500,0.200000,0.200000},{0.462500,0.087500,0.100000,0.100000},{0.462500,0.087500,0.200000,0.200000},{0.487500,0.087500,0.100000,0.100000},{0.487500,0.087500,0.200000,0.200000},{0.512500,0.087500,0.100000,0.100000},{0.512500,0.087500,0.200000,0.200000},{0.537500,0.087500,0.100000,0.100000},{0.537500,0.087500,0.200000,0.200000},{0.562500,0.087500,0.100000,0.100000},{0.562500,0.087500,0.200000,0.200000},{0.587500,0.087500,0.100000,0.100000},{0.587500,0.087500,0.200000,0.200000},{0.612500,0.087500,0.100000,0.100000},{0.612500,0.087500,0.200000,0.200000},{0.637500,0.087500,0.100000,0.100000},{0.637500,0.087500,0.200000,0.200000},{0.662500,0.087500,0.100000,0.100000},{0.662500,0.087500,0.200000,0.200000},{0.687500,0.087500,0.100000,0.100000},{0.687500,0.087500,0.200000,0.200000},{0.712500,0.087500,0.100000,0.100000},{0.712500,0.087500,0.200000,0.200000},{0.737500,0.087500,0.100000,0.100000},{0.737500,0.087500,0.200000,0.200000},{0.762500,0.087500,0.100000,0.100000},{0.762500,0.087500,0.200000,0.200000},{0.787500,0.087500,0.100000,0.100000},{0.787500,0.087500,0.200000,0.200000},{0.812500,0.087500,0.100000,0.100000},{0.812500,0.087500,0.200000,0.200000},{0.837500,0.087500,0.100000,0.100000},{0.837500,0.087500,0.200000,0.200000},{0.862500,0.087500,0.100000,0.100000},{0.862500,0.087500,0.200000,0.200000},{0.887500,0.087500,0.100000,0.100000},{0.887500,0.087500,0.200000,0.200000},{0.912500,0.087500,0.100000,0.100000},{0.912500,0.087500,0.200000,0.200000},{0.937500,0.087500,0.100000,0.100000},{0.937500,0.087500,0.200000,0.200000},{0.962500,0.087500,0.100000,0.100000},{0.962500,0.087500,0.200000,0.200000},{0.987500,0.087500,0.100000,0.100000},{0.987500,0.087500,0.200000,0.200000},{0.012500,0.112500,0.100000,0.100000},{0.012500,0.112500,0.200000,0.200000},{0.037500,0.112500,0.100000,0.100000},{0.037500,0.112500,0.200000,0.200000},{0.062500,0.112500,0.100000,0.100000},{0.062500,0.112500,0.200000,0.200000},{0.087500,0.112500,0.100000,0.100000},{0.087500,0.112500,0.200000,0.200000},{0.112500,0.112500,0.100000,0.100000},{0.112500,0.112500,0.200000,0.200000},{0.137500,0.112500,0.100000,0.100000},{0.137500,0.112500,0.200000,0.200000},{0.162500,0.112500,0.100000,0.100000},{0.162500,0.112500,0.200000,0.200000},{0.187500,0.112500,0.100000,0.100000},{0.187500,0.112500,0.200000,0.200000},{0.212500,0.112500,0.100000,0.100000},{0.212500,0.112500,0.200000,0.200000},{0.237500,0.112500,0.100000,0.100000},{0.237500,0.112500,0.200000,0.200000},{0.262500,0.112500,0.100000,0.100000},{0.262500,0.112500,0.200000,0.200000},{0.287500,0.112500,0.100000,0.100000},{0.287500,0.112500,0.200000,0.200000},{0.312500,0.112500,0.100000,0.100000},{0.312500,0.112500,0.200000,0.200000},{0.337500,0.112500,0.100000,0.100000},{0.337500,0.112500,0.200000,0.200000},{0.362500,0.112500,0.100000,0.100000},{0.362500,0.112500,0.200000,0.200000},{0.387500,0.112500,0.100000,0.100000},{0.387500,0.112500,0.200000,0.200000},{0.412500,0.112500,0.100000,0.100000},{0.412500,0.112500,0.200000,0.200000},{0.437500,0.112500,0.100000,0.100000},{0.437500,0.112500,0.200000,0.200000},{0.462500,0.112500,0.100000,0.100000},{0.462500,0.112500,0.200000,0.200000},{0.487500,0.112500,0.100000,0.100000},{0.487500,0.112500,0.200000,0.200000},{0.512500,0.112500,0.100000,0.100000},{0.512500,0.112500,0.200000,0.200000},{0.537500,0.112500,0.100000,0.100000},{0.537500,0.112500,0.200000,0.200000},{0.562500,0.112500,0.100000,0.100000},{0.562500,0.112500,0.200000,0.200000},{0.587500,0.112500,0.100000,0.100000},{0.587500,0.112500,0.200000,0.200000},{0.612500,0.112500,0.100000,0.100000},{0.612500,0.112500,0.200000,0.200000},{0.637500,0.112500,0.100000,0.100000},{0.637500,0.112500,0.200000,0.200000},{0.662500,0.112500,0.100000,0.100000},{0.662500,0.112500,0.200000,0.200000},{0.687500,0.112500,0.100000,0.100000},{0.687500,0.112500,0.200000,0.200000},{0.712500,0.112500,0.100000,0.100000},{0.712500,0.112500,0.200000,0.200000},{0.737500,0.112500,0.100000,0.100000},{0.737500,0.112500,0.200000,0.200000},{0.762500,0.112500,0.100000,0.100000},{0.762500,0.112500,0.200000,0.200000},{0.787500,0.112500,0.100000,0.100000},{0.787500,0.112500,0.200000,0.200000},{0.812500,0.112500,0.100000,0.100000},{0.812500,0.112500,0.200000,0.200000},{0.837500,0.112500,0.100000,0.100000},{0.837500,0.112500,0.200000,0.200000},{0.862500,0.112500,0.100000,0.100000},{0.862500,0.112500,0.200000,0.200000},{0.887500,0.112500,0.100000,0.100000},{0.887500,0.112500,0.200000,0.200000},{0.912500,0.112500,0.100000,0.100000},{0.912500,0.112500,0.200000,0.200000},{0.937500,0.112500,0.100000,0.100000},{0.937500,0.112500,0.200000,0.200000},{0.962500,0.112500,0.100000,0.100000},{0.962500,0.112500,0.200000,0.200000},{0.987500,0.112500,0.100000,0.100000},{0.987500,0.112500,0.200000,0.200000},{0.012500,0.137500,0.100000,0.100000},{0.012500,0.137500,0.200000,0.200000},{0.037500,0.137500,0.100000,0.100000},{0.037500,0.137500,0.200000,0.200000},{0.062500,0.137500,0.100000,0.100000},{0.062500,0.137500,0.200000,0.200000},{0.087500,0.137500,0.100000,0.100000},{0.087500,0.137500,0.200000,0.200000},{0.112500,0.137500,0.100000,0.100000},{0.112500,0.137500,0.200000,0.200000},{0.137500,0.137500,0.100000,0.100000},{0.137500,0.137500,0.200000,0.200000},{0.162500,0.137500,0.100000,0.100000},{0.162500,0.137500,0.200000,0.200000},{0.187500,0.137500,0.100000,0.100000},{0.187500,0.137500,0.200000,0.200000},{0.212500,0.137500,0.100000,0.100000},{0.212500,0.137500,0.200000,0.200000},{0.237500,0.137500,0.100000,0.100000},{0.237500,0.137500,0.200000,0.200000},{0.262500,0.137500,0.100000,0.100000},{0.262500,0.137500,0.200000,0.200000},{0.287500,0.137500,0.100000,0.100000},{0.287500,0.137500,0.200000,0.200000},{0.312500,0.137500,0.100000,0.100000},{0.312500,0.137500,0.200000,0.200000},{0.337500,0.137500,0.100000,0.100000},{0.337500,0.137500,0.200000,0.200000},{0.362500,0.137500,0.100000,0.100000},{0.362500,0.137500,0.200000,0.200000},{0.387500,0.137500,0.100000,0.100000},{0.387500,0.137500,0.200000,0.200000},{0.412500,0.137500,0.100000,0.100000},{0.412500,0.137500,0.200000,0.200000},{0.437500,0.137500,0.100000,0.100000},{0.437500,0.137500,0.200000,0.200000},{0.462500,0.137500,0.100000,0.100000},{0.462500,0.137500,0.200000,0.200000},{0.487500,0.137500,0.100000,0.100000},{0.487500,0.137500,0.200000,0.200000},{0.512500,0.137500,0.100000,0.100000},{0.512500,0.137500,0.200000,0.200000},{0.537500,0.137500,0.100000,0.100000},{0.537500,0.137500,0.200000,0.200000},{0.562500,0.137500,0.100000,0.100000},{0.562500,0.137500,0.200000,0.200000},{0.587500,0.137500,0.100000,0.100000},{0.587500,0.137500,0.200000,0.200000},{0.612500,0.137500,0.100000,0.100000},{0.612500,0.137500,0.200000,0.200000},{0.637500,0.137500,0.100000,0.100000},{0.637500,0.137500,0.200000,0.200000},{0.662500,0.137500,0.100000,0.100000},{0.662500,0.137500,0.200000,0.200000},{0.687500,0.137500,0.100000,0.100000},{0.687500,0.137500,0.200000,0.200000},{0.712500,0.137500,0.100000,0.100000},{0.712500,0.137500,0.200000,0.200000},{0.737500,0.137500,0.100000,0.100000},{0.737500,0.137500,0.200000,0.200000},{0.762500,0.137500,0.100000,0.100000},{0.762500,0.137500,0.200000,0.200000},{0.787500,0.137500,0.100000,0.100000},{0.787500,0.137500,0.200000,0.200000},{0.812500,0.137500,0.100000,0.100000},{0.812500,0.137500,0.200000,0.200000},{0.837500,0.137500,0.100000,0.100000},{0.837500,0.137500,0.200000,0.200000},{0.862500,0.137500,0.100000,0.100000},{0.862500,0.137500,0.200000,0.200000},{0.887500,0.137500,0.100000,0.100000},{0.887500,0.137500,0.200000,0.200000},{0.912500,0.137500,0.100000,0.100000},{0.912500,0.137500,0.200000,0.200000},{0.937500,0.137500,0.100000,0.100000},{0.937500,0.137500,0.200000,0.200000},{0.962500,0.137500,0.100000,0.100000},{0.962500,0.137500,0.200000,0.200000},{0.987500,0.137500,0.100000,0.100000},{0.987500,0.137500,0.200000,0.200000},{0.012500,0.162500,0.100000,0.100000},{0.012500,0.162500,0.200000,0.200000},{0.037500,0.162500,0.100000,0.100000},{0.037500,0.162500,0.200000,0.200000},{0.062500,0.162500,0.100000,0.100000},{0.062500,0.162500,0.200000,0.200000},{0.087500,0.162500,0.100000,0.100000},{0.087500,0.162500,0.200000,0.200000},{0.112500,0.162500,0.100000,0.100000},{0.112500,0.162500,0.200000,0.200000},{0.137500,0.162500,0.100000,0.100000},{0.137500,0.162500,0.200000,0.200000},{0.162500,0.162500,0.100000,0.100000},{0.162500,0.162500,0.200000,0.200000},{0.187500,0.162500,0.100000,0.100000},{0.187500,0.162500,0.200000,0.200000},{0.212500,0.162500,0.100000,0.100000},{0.212500,0.162500,0.200000,0.200000},{0.237500,0.162500,0.100000,0.100000},{0.237500,0.162500,0.200000,0.200000},{0.262500,0.162500,0.100000,0.100000},{0.262500,0.162500,0.200000,0.200000},{0.287500,0.162500,0.100000,0.100000},{0.287500,0.162500,0.200000,0.200000},{0.312500,0.162500,0.100000,0.100000},{0.312500,0.162500,0.200000,0.200000},{0.337500,0.162500,0.100000,0.100000},{0.337500,0.162500,0.200000,0.200000},{0.362500,0.162500,0.100000,0.100000},{0.362500,0.162500,0.200000,0.200000},{0.387500,0.162500,0.100000,0.100000},{0.387500,0.162500,0.200000,0.200000},{0.412500,0.162500,0.100000,0.100000},{0.412500,0.162500,0.200000,0.200000},{0.437500,0.162500,0.100000,0.100000},{0.437500,0.162500,0.200000,0.200000},{0.462500,0.162500,0.100000,0.100000},{0.462500,0.162500,0.200000,0.200000},{0.487500,0.162500,0.100000,0.100000},{0.487500,0.162500,0.200000,0.200000},{0.512500,0.162500,0.100000,0.100000},{0.512500,0.162500,0.200000,0.200000},{0.537500,0.162500,0.100000,0.100000},{0.537500,0.162500,0.200000,0.200000},{0.562500,0.162500,0.100000,0.100000},{0.562500,0.162500,0.200000,0.200000},{0.587500,0.162500,0.100000,0.100000},{0.587500,0.162500,0.200000,0.200000},{0.612500,0.162500,0.100000,0.100000},{0.612500,0.162500,0.200000,0.200000},{0.637500,0.162500,0.100000,0.100000},{0.637500,0.162500,0.200000,0.200000},{0.662500,0.162500,0.100000,0.100000},{0.662500,0.162500,0.200000,0.200000},{0.687500,0.162500,0.100000,0.100000},{0.687500,0.162500,0.200000,0.200000},{0.712500,0.162500,0.100000,0.100000},{0.712500,0.162500,0.200000,0.200000},{0.737500,0.162500,0.100000,0.100000},{0.737500,0.162500,0.200000,0.200000},{0.762500,0.162500,0.100000,0.100000},{0.762500,0.162500,0.200000,0.200000},{0.787500,0.162500,0.100000,0.100000},{0.787500,0.162500,0.200000,0.200000},{0.812500,0.162500,0.100000,0.100000},{0.812500,0.162500,0.200000,0.200000},{0.837500,0.162500,0.100000,0.100000},{0.837500,0.162500,0.200000,0.200000},{0.862500,0.162500,0.100000,0.100000},{0.862500,0.162500,0.200000,0.200000},{0.887500,0.162500,0.100000,0.100000},{0.887500,0.162500,0.200000,0.200000},{0.912500,0.162500,0.100000,0.100000},{0.912500,0.162500,0.200000,0.200000},{0.937500,0.162500,0.100000,0.100000},{0.937500,0.162500,0.200000,0.200000},{0.962500,0.162500,0.100000,0.100000},{0.962500,0.162500,0.200000,0.200000},{0.987500,0.162500,0.100000,0.100000},{0.987500,0.162500,0.200000,0.200000},{0.012500,0.187500,0.100000,0.100000},{0.012500,0.187500,0.200000,0.200000},{0.037500,0.187500,0.100000,0.100000},{0.037500,0.187500,0.200000,0.200000},{0.062500,0.187500,0.100000,0.100000},{0.062500,0.187500,0.200000,0.200000},{0.087500,0.187500,0.100000,0.100000},{0.087500,0.187500,0.200000,0.200000},{0.112500,0.187500,0.100000,0.100000},{0.112500,0.187500,0.200000,0.200000},{0.137500,0.187500,0.100000,0.100000},{0.137500,0.187500,0.200000,0.200000},{0.162500,0.187500,0.100000,0.100000},{0.162500,0.187500,0.200000,0.200000},{0.187500,0.187500,0.100000,0.100000},{0.187500,0.187500,0.200000,0.200000},{0.212500,0.187500,0.100000,0.100000},{0.212500,0.187500,0.200000,0.200000},{0.237500,0.187500,0.100000,0.100000},{0.237500,0.187500,0.200000,0.200000},{0.262500,0.187500,0.100000,0.100000},{0.262500,0.187500,0.200000,0.200000},{0.287500,0.187500,0.100000,0.100000},{0.287500,0.187500,0.200000,0.200000},{0.312500,0.187500,0.100000,0.100000},{0.312500,0.187500,0.200000,0.200000},{0.337500,0.187500,0.100000,0.100000},{0.337500,0.187500,0.200000,0.200000},{0.362500,0.187500,0.100000,0.100000},{0.362500,0.187500,0.200000,0.200000},{0.387500,0.187500,0.100000,0.100000},{0.387500,0.187500,0.200000,0.200000},{0.412500,0.187500,0.100000,0.100000},{0.412500,0.187500,0.200000,0.200000},{0.437500,0.187500,0.100000,0.100000},{0.437500,0.187500,0.200000,0.200000},{0.462500,0.187500,0.100000,0.100000},{0.462500,0.187500,0.200000,0.200000},{0.487500,0.187500,0.100000,0.100000},{0.487500,0.187500,0.200000,0.200000},{0.512500,0.187500,0.100000,0.100000},{0.512500,0.187500,0.200000,0.200000},{0.537500,0.187500,0.100000,0.100000},{0.537500,0.187500,0.200000,0.200000},{0.562500,0.187500,0.100000,0.100000},{0.562500,0.187500,0.200000,0.200000},{0.587500,0.187500,0.100000,0.100000},{0.587500,0.187500,0.200000,0.200000},{0.612500,0.187500,0.100000,0.100000},{0.612500,0.187500,0.200000,0.200000},{0.637500,0.187500,0.100000,0.100000},{0.637500,0.187500,0.200000,0.200000},{0.662500,0.187500,0.100000,0.100000},{0.662500,0.187500,0.200000,0.200000},{0.687500,0.187500,0.100000,0.100000},{0.687500,0.187500,0.200000,0.200000},{0.712500,0.187500,0.100000,0.100000},{0.712500,0.187500,0.200000,0.200000},{0.737500,0.187500,0.100000,0.100000},{0.737500,0.187500,0.200000,0.200000},{0.762500,0.187500,0.100000,0.100000},{0.762500,0.187500,0.200000,0.200000},{0.787500,0.187500,0.100000,0.100000},{0.787500,0.187500,0.200000,0.200000},{0.812500,0.187500,0.100000,0.100000},{0.812500,0.187500,0.200000,0.200000},{0.837500,0.187500,0.100000,0.100000},{0.837500,0.187500,0.200000,0.200000},{0.862500,0.187500,0.100000,0.100000},{0.862500,0.187500,0.200000,0.200000},{0.887500,0.187500,0.100000,0.100000},{0.887500,0.187500,0.200000,0.200000},{0.912500,0.187500,0.100000,0.100000},{0.912500,0.187500,0.200000,0.200000},{0.937500,0.187500,0.100000,0.100000},{0.937500,0.187500,0.200000,0.200000},{0.962500,0.187500,0.100000,0.100000},{0.962500,0.187500,0.200000,0.200000},{0.987500,0.187500,0.100000,0.100000},{0.987500,0.187500,0.200000,0.200000},{0.012500,0.212500,0.100000,0.100000},{0.012500,0.212500,0.200000,0.200000},{0.037500,0.212500,0.100000,0.100000},{0.037500,0.212500,0.200000,0.200000},{0.062500,0.212500,0.100000,0.100000},{0.062500,0.212500,0.200000,0.200000},{0.087500,0.212500,0.100000,0.100000},{0.087500,0.212500,0.200000,0.200000},{0.112500,0.212500,0.100000,0.100000},{0.112500,0.212500,0.200000,0.200000},{0.137500,0.212500,0.100000,0.100000},{0.137500,0.212500,0.200000,0.200000},{0.162500,0.212500,0.100000,0.100000},{0.162500,0.212500,0.200000,0.200000},{0.187500,0.212500,0.100000,0.100000},{0.187500,0.212500,0.200000,0.200000},{0.212500,0.212500,0.100000,0.100000},{0.212500,0.212500,0.200000,0.200000},{0.237500,0.212500,0.100000,0.100000},{0.237500,0.212500,0.200000,0.200000},{0.262500,0.212500,0.100000,0.100000},{0.262500,0.212500,0.200000,0.200000},{0.287500,0.212500,0.100000,0.100000},{0.287500,0.212500,0.200000,0.200000},{0.312500,0.212500,0.100000,0.100000},{0.312500,0.212500,0.200000,0.200000},{0.337500,0.212500,0.100000,0.100000},{0.337500,0.212500,0.200000,0.200000},{0.362500,0.212500,0.100000,0.100000},{0.362500,0.212500,0.200000,0.200000},{0.387500,0.212500,0.100000,0.100000},{0.387500,0.212500,0.200000,0.200000},{0.412500,0.212500,0.100000,0.100000},{0.412500,0.212500,0.200000,0.200000},{0.437500,0.212500,0.100000,0.100000},{0.437500,0.212500,0.200000,0.200000},{0.462500,0.212500,0.100000,0.100000},{0.462500,0.212500,0.200000,0.200000},{0.487500,0.212500,0.100000,0.100000},{0.487500,0.212500,0.200000,0.200000},{0.512500,0.212500,0.100000,0.100000},{0.512500,0.212500,0.200000,0.200000},{0.537500,0.212500,0.100000,0.100000},{0.537500,0.212500,0.200000,0.200000},{0.562500,0.212500,0.100000,0.100000},{0.562500,0.212500,0.200000,0.200000},{0.587500,0.212500,0.100000,0.100000},{0.587500,0.212500,0.200000,0.200000},{0.612500,0.212500,0.100000,0.100000},{0.612500,0.212500,0.200000,0.200000},{0.637500,0.212500,0.100000,0.100000},{0.637500,0.212500,0.200000,0.200000},{0.662500,0.212500,0.100000,0.100000},{0.662500,0.212500,0.200000,0.200000},{0.687500,0.212500,0.100000,0.100000},{0.687500,0.212500,0.200000,0.200000},{0.712500,0.212500,0.100000,0.100000},{0.712500,0.212500,0.200000,0.200000},{0.737500,0.212500,0.100000,0.100000},{0.737500,0.212500,0.200000,0.200000},{0.762500,0.212500,0.100000,0.100000},{0.762500,0.212500,0.200000,0.200000},{0.787500,0.212500,0.100000,0.100000},{0.787500,0.212500,0.200000,0.200000},{0.812500,0.212500,0.100000,0.100000},{0.812500,0.212500,0.200000,0.200000},{0.837500,0.212500,0.100000,0.100000},{0.837500,0.212500,0.200000,0.200000},{0.862500,0.212500,0.100000,0.100000},{0.862500,0.212500,0.200000,0.200000},{0.887500,0.212500,0.100000,0.100000},{0.887500,0.212500,0.200000,0.200000},{0.912500,0.212500,0.100000,0.100000},{0.912500,0.212500,0.200000,0.200000},{0.937500,0.212500,0.100000,0.100000},{0.937500,0.212500,0.200000,0.200000},{0.962500,0.212500,0.100000,0.100000},{0.962500,0.212500,0.200000,0.200000},{0.987500,0.212500,0.100000,0.100000},{0.987500,0.212500,0.200000,0.200000},{0.012500,0.237500,0.100000,0.100000},{0.012500,0.237500,0.200000,0.200000},{0.037500,0.237500,0.100000,0.100000},{0.037500,0.237500,0.200000,0.200000},{0.062500,0.237500,0.100000,0.100000},{0.062500,0.237500,0.200000,0.200000},{0.087500,0.237500,0.100000,0.100000},{0.087500,0.237500,0.200000,0.200000},{0.112500,0.237500,0.100000,0.100000},{0.112500,0.237500,0.200000,0.200000},{0.137500,0.237500,0.100000,0.100000},{0.137500,0.237500,0.200000,0.200000},{0.162500,0.237500,0.100000,0.100000},{0.162500,0.237500,0.200000,0.200000},{0.187500,0.237500,0.100000,0.100000},{0.187500,0.237500,0.200000,0.200000},{0.212500,0.237500,0.100000,0.100000},{0.212500,0.237500,0.200000,0.200000},{0.237500,0.237500,0.100000,0.100000},{0.237500,0.237500,0.200000,0.200000},{0.262500,0.237500,0.100000,0.100000},{0.262500,0.237500,0.200000,0.200000},{0.287500,0.237500,0.100000,0.100000},{0.287500,0.237500,0.200000,0.200000},{0.312500,0.237500,0.100000,0.100000},{0.312500,0.237500,0.200000,0.200000},{0.337500,0.237500,0.100000,0.100000},{0.337500,0.237500,0.200000,0.200000},{0.362500,0.237500,0.100000,0.100000},{0.362500,0.237500,0.200000,0.200000},{0.387500,0.237500,0.100000,0.100000},{0.387500,0.237500,0.200000,0.200000},{0.412500,0.237500,0.100000,0.100000},{0.412500,0.237500,0.200000,0.200000},{0.437500,0.237500,0.100000,0.100000},{0.437500,0.237500,0.200000,0.200000},{0.462500,0.237500,0.100000,0.100000},{0.462500,0.237500,0.200000,0.200000},{0.487500,0.237500,0.100000,0.100000},{0.487500,0.237500,0.200000,0.200000},{0.512500,0.237500,0.100000,0.100000},{0.512500,0.237500,0.200000,0.200000},{0.537500,0.237500,0.100000,0.100000},{0.537500,0.237500,0.200000,0.200000},{0.562500,0.237500,0.100000,0.100000},{0.562500,0.237500,0.200000,0.200000},{0.587500,0.237500,0.100000,0.100000},{0.587500,0.237500,0.200000,0.200000},{0.612500,0.237500,0.100000,0.100000},{0.612500,0.237500,0.200000,0.200000},{0.637500,0.237500,0.100000,0.100000},{0.637500,0.237500,0.200000,0.200000},{0.662500,0.237500,0.100000,0.100000},{0.662500,0.237500,0.200000,0.200000},{0.687500,0.237500,0.100000,0.100000},{0.687500,0.237500,0.200000,0.200000},{0.712500,0.237500,0.100000,0.100000},{0.712500,0.237500,0.200000,0.200000},{0.737500,0.237500,0.100000,0.100000},{0.737500,0.237500,0.200000,0.200000},{0.762500,0.237500,0.100000,0.100000},{0.762500,0.237500,0.200000,0.200000},{0.787500,0.237500,0.100000,0.100000},{0.787500,0.237500,0.200000,0.200000},{0.812500,0.237500,0.100000,0.100000},{0.812500,0.237500,0.200000,0.200000},{0.837500,0.237500,0.100000,0.100000},{0.837500,0.237500,0.200000,0.200000},{0.862500,0.237500,0.100000,0.100000},{0.862500,0.237500,0.200000,0.200000},{0.887500,0.237500,0.100000,0.100000},{0.887500,0.237500,0.200000,0.200000},{0.912500,0.237500,0.100000,0.100000},{0.912500,0.237500,0.200000,0.200000},{0.937500,0.237500,0.100000,0.100000},{0.937500,0.237500,0.200000,0.200000},{0.962500,0.237500,0.100000,0.100000},{0.962500,0.237500,0.200000,0.200000},{0.987500,0.237500,0.100000,0.100000},{0.987500,0.237500,0.200000,0.200000},{0.012500,0.262500,0.100000,0.100000},{0.012500,0.262500,0.200000,0.200000},{0.037500,0.262500,0.100000,0.100000},{0.037500,0.262500,0.200000,0.200000},{0.062500,0.262500,0.100000,0.100000},{0.062500,0.262500,0.200000,0.200000},{0.087500,0.262500,0.100000,0.100000},{0.087500,0.262500,0.200000,0.200000},{0.112500,0.262500,0.100000,0.100000},{0.112500,0.262500,0.200000,0.200000},{0.137500,0.262500,0.100000,0.100000},{0.137500,0.262500,0.200000,0.200000},{0.162500,0.262500,0.100000,0.100000},{0.162500,0.262500,0.200000,0.200000},{0.187500,0.262500,0.100000,0.100000},{0.187500,0.262500,0.200000,0.200000},{0.212500,0.262500,0.100000,0.100000},{0.212500,0.262500,0.200000,0.200000},{0.237500,0.262500,0.100000,0.100000},{0.237500,0.262500,0.200000,0.200000},{0.262500,0.262500,0.100000,0.100000},{0.262500,0.262500,0.200000,0.200000},{0.287500,0.262500,0.100000,0.100000},{0.287500,0.262500,0.200000,0.200000},{0.312500,0.262500,0.100000,0.100000},{0.312500,0.262500,0.200000,0.200000},{0.337500,0.262500,0.100000,0.100000},{0.337500,0.262500,0.200000,0.200000},{0.362500,0.262500,0.100000,0.100000},{0.362500,0.262500,0.200000,0.200000},{0.387500,0.262500,0.100000,0.100000},{0.387500,0.262500,0.200000,0.200000},{0.412500,0.262500,0.100000,0.100000},{0.412500,0.262500,0.200000,0.200000},{0.437500,0.262500,0.100000,0.100000},{0.437500,0.262500,0.200000,0.200000},{0.462500,0.262500,0.100000,0.100000},{0.462500,0.262500,0.200000,0.200000},{0.487500,0.262500,0.100000,0.100000},{0.487500,0.262500,0.200000,0.200000},{0.512500,0.262500,0.100000,0.100000},{0.512500,0.262500,0.200000,0.200000},{0.537500,0.262500,0.100000,0.100000},{0.537500,0.262500,0.200000,0.200000},{0.562500,0.262500,0.100000,0.100000},{0.562500,0.262500,0.200000,0.200000},{0.587500,0.262500,0.100000,0.100000},{0.587500,0.262500,0.200000,0.200000},{0.612500,0.262500,0.100000,0.100000},{0.612500,0.262500,0.200000,0.200000},{0.637500,0.262500,0.100000,0.100000},{0.637500,0.262500,0.200000,0.200000},{0.662500,0.262500,0.100000,0.100000},{0.662500,0.262500,0.200000,0.200000},{0.687500,0.262500,0.100000,0.100000},{0.687500,0.262500,0.200000,0.200000},{0.712500,0.262500,0.100000,0.100000},{0.712500,0.262500,0.200000,0.200000},{0.737500,0.262500,0.100000,0.100000},{0.737500,0.262500,0.200000,0.200000},{0.762500,0.262500,0.100000,0.100000},{0.762500,0.262500,0.200000,0.200000},{0.787500,0.262500,0.100000,0.100000},{0.787500,0.262500,0.200000,0.200000},{0.812500,0.262500,0.100000,0.100000},{0.812500,0.262500,0.200000,0.200000},{0.837500,0.262500,0.100000,0.100000},{0.837500,0.262500,0.200000,0.200000},{0.862500,0.262500,0.100000,0.100000},{0.862500,0.262500,0.200000,0.200000},{0.887500,0.262500,0.100000,0.100000},{0.887500,0.262500,0.200000,0.200000},{0.912500,0.262500,0.100000,0.100000},{0.912500,0.262500,0.200000,0.200000},{0.937500,0.262500,0.100000,0.100000},{0.937500,0.262500,0.200000,0.200000},{0.962500,0.262500,0.100000,0.100000},{0.962500,0.262500,0.200000,0.200000},{0.987500,0.262500,0.100000,0.100000},{0.987500,0.262500,0.200000,0.200000},{0.012500,0.287500,0.100000,0.100000},{0.012500,0.287500,0.200000,0.200000},{0.037500,0.287500,0.100000,0.100000},{0.037500,0.287500,0.200000,0.200000},{0.062500,0.287500,0.100000,0.100000},{0.062500,0.287500,0.200000,0.200000},{0.087500,0.287500,0.100000,0.100000},{0.087500,0.287500,0.200000,0.200000},{0.112500,0.287500,0.100000,0.100000},{0.112500,0.287500,0.200000,0.200000},{0.137500,0.287500,0.100000,0.100000},{0.137500,0.287500,0.200000,0.200000},{0.162500,0.287500,0.100000,0.100000},{0.162500,0.287500,0.200000,0.200000},{0.187500,0.287500,0.100000,0.100000},{0.187500,0.287500,0.200000,0.200000},{0.212500,0.287500,0.100000,0.100000},{0.212500,0.287500,0.200000,0.200000},{0.237500,0.287500,0.100000,0.100000},{0.237500,0.287500,0.200000,0.200000},{0.262500,0.287500,0.100000,0.100000},{0.262500,0.287500,0.200000,0.200000},{0.287500,0.287500,0.100000,0.100000},{0.287500,0.287500,0.200000,0.200000},{0.312500,0.287500,0.100000,0.100000},{0.312500,0.287500,0.200000,0.200000},{0.337500,0.287500,0.100000,0.100000},{0.337500,0.287500,0.200000,0.200000},{0.362500,0.287500,0.100000,0.100000},{0.362500,0.287500,0.200000,0.200000},{0.387500,0.287500,0.100000,0.100000},{0.387500,0.287500,0.200000,0.200000},{0.412500,0.287500,0.100000,0.100000},{0.412500,0.287500,0.200000,0.200000},{0.437500,0.287500,0.100000,0.100000},{0.437500,0.287500,0.200000,0.200000},{0.462500,0.287500,0.100000,0.100000},{0.462500,0.287500,0.200000,0.200000},{0.487500,0.287500,0.100000,0.100000},{0.487500,0.287500,0.200000,0.200000},{0.512500,0.287500,0.100000,0.100000},{0.512500,0.287500,0.200000,0.200000},{0.537500,0.287500,0.100000,0.100000},{0.537500,0.287500,0.200000,0.200000},{0.562500,0.287500,0.100000,0.100000},{0.562500,0.287500,0.200000,0.200000},{0.587500,0.287500,0.100000,0.100000},{0.587500,0.287500,0.200000,0.200000},{0.612500,0.287500,0.100000,0.100000},{0.612500,0.287500,0.200000,0.200000},{0.637500,0.287500,0.100000,0.100000},{0.637500,0.287500,0.200000,0.200000},{0.662500,0.287500,0.100000,0.100000},{0.662500,0.287500,0.200000,0.200000},{0.687500,0.287500,0.100000,0.100000},{0.687500,0.287500,0.200000,0.200000},{0.712500,0.287500,0.100000,0.100000},{0.712500,0.287500,0.200000,0.200000},{0.737500,0.287500,0.100000,0.100000},{0.737500,0.287500,0.200000,0.200000},{0.762500,0.287500,0.100000,0.100000},{0.762500,0.287500,0.200000,0.200000},{0.787500,0.287500,0.100000,0.100000},{0.787500,0.287500,0.200000,0.200000},{0.812500,0.287500,0.100000,0.100000},{0.812500,0.287500,0.200000,0.200000},{0.837500,0.287500,0.100000,0.100000},{0.837500,0.287500,0.200000,0.200000},{0.862500,0.287500,0.100000,0.100000},{0.862500,0.287500,0.200000,0.200000},{0.887500,0.287500,0.100000,0.100000},{0.887500,0.287500,0.200000,0.200000},{0.912500,0.287500,0.100000,0.100000},{0.912500,0.287500,0.200000,0.200000},{0.937500,0.287500,0.100000,0.100000},{0.937500,0.287500,0.200000,0.200000},{0.962500,0.287500,0.100000,0.100000},{0.962500,0.287500,0.200000,0.200000},{0.987500,0.287500,0.100000,0.100000},{0.987500,0.287500,0.200000,0.200000},{0.012500,0.312500,0.100000,0.100000},{0.012500,0.312500,0.200000,0.200000},{0.037500,0.312500,0.100000,0.100000},{0.037500,0.312500,0.200000,0.200000},{0.062500,0.312500,0.100000,0.100000},{0.062500,0.312500,0.200000,0.200000},{0.087500,0.312500,0.100000,0.100000},{0.087500,0.312500,0.200000,0.200000},{0.112500,0.312500,0.100000,0.100000},{0.112500,0.312500,0.200000,0.200000},{0.137500,0.312500,0.100000,0.100000},{0.137500,0.312500,0.200000,0.200000},{0.162500,0.312500,0.100000,0.100000},{0.162500,0.312500,0.200000,0.200000},{0.187500,0.312500,0.100000,0.100000},{0.187500,0.312500,0.200000,0.200000},{0.212500,0.312500,0.100000,0.100000},{0.212500,0.312500,0.200000,0.200000},{0.237500,0.312500,0.100000,0.100000},{0.237500,0.312500,0.200000,0.200000},{0.262500,0.312500,0.100000,0.100000},{0.262500,0.312500,0.200000,0.200000},{0.287500,0.312500,0.100000,0.100000},{0.287500,0.312500,0.200000,0.200000},{0.312500,0.312500,0.100000,0.100000},{0.312500,0.312500,0.200000,0.200000},{0.337500,0.312500,0.100000,0.100000},{0.337500,0.312500,0.200000,0.200000},{0.362500,0.312500,0.100000,0.100000},{0.362500,0.312500,0.200000,0.200000},{0.387500,0.312500,0.100000,0.100000},{0.387500,0.312500,0.200000,0.200000},{0.412500,0.312500,0.100000,0.100000},{0.412500,0.312500,0.200000,0.200000},{0.437500,0.312500,0.100000,0.100000},{0.437500,0.312500,0.200000,0.200000},{0.462500,0.312500,0.100000,0.100000},{0.462500,0.312500,0.200000,0.200000},{0.487500,0.312500,0.100000,0.100000},{0.487500,0.312500,0.200000,0.200000},{0.512500,0.312500,0.100000,0.100000},{0.512500,0.312500,0.200000,0.200000},{0.537500,0.312500,0.100000,0.100000},{0.537500,0.312500,0.200000,0.200000},{0.562500,0.312500,0.100000,0.100000},{0.562500,0.312500,0.200000,0.200000},{0.587500,0.312500,0.100000,0.100000},{0.587500,0.312500,0.200000,0.200000},{0.612500,0.312500,0.100000,0.100000},{0.612500,0.312500,0.200000,0.200000},{0.637500,0.312500,0.100000,0.100000},{0.637500,0.312500,0.200000,0.200000},{0.662500,0.312500,0.100000,0.100000},{0.662500,0.312500,0.200000,0.200000},{0.687500,0.312500,0.100000,0.100000},{0.687500,0.312500,0.200000,0.200000},{0.712500,0.312500,0.100000,0.100000},{0.712500,0.312500,0.200000,0.200000},{0.737500,0.312500,0.100000,0.100000},{0.737500,0.312500,0.200000,0.200000},{0.762500,0.312500,0.100000,0.100000},{0.762500,0.312500,0.200000,0.200000},{0.787500,0.312500,0.100000,0.100000},{0.787500,0.312500,0.200000,0.200000},{0.812500,0.312500,0.100000,0.100000},{0.812500,0.312500,0.200000,0.200000},{0.837500,0.312500,0.100000,0.100000},{0.837500,0.312500,0.200000,0.200000},{0.862500,0.312500,0.100000,0.100000},{0.862500,0.312500,0.200000,0.200000},{0.887500,0.312500,0.100000,0.100000},{0.887500,0.312500,0.200000,0.200000},{0.912500,0.312500,0.100000,0.100000},{0.912500,0.312500,0.200000,0.200000},{0.937500,0.312500,0.100000,0.100000},{0.937500,0.312500,0.200000,0.200000},{0.962500,0.312500,0.100000,0.100000},{0.962500,0.312500,0.200000,0.200000},{0.987500,0.312500,0.100000,0.100000},{0.987500,0.312500,0.200000,0.200000},{0.012500,0.337500,0.100000,0.100000},{0.012500,0.337500,0.200000,0.200000},{0.037500,0.337500,0.100000,0.100000},{0.037500,0.337500,0.200000,0.200000},{0.062500,0.337500,0.100000,0.100000},{0.062500,0.337500,0.200000,0.200000},{0.087500,0.337500,0.100000,0.100000},{0.087500,0.337500,0.200000,0.200000},{0.112500,0.337500,0.100000,0.100000},{0.112500,0.337500,0.200000,0.200000},{0.137500,0.337500,0.100000,0.100000},{0.137500,0.337500,0.200000,0.200000},{0.162500,0.337500,0.100000,0.100000},{0.162500,0.337500,0.200000,0.200000},{0.187500,0.337500,0.100000,0.100000},{0.187500,0.337500,0.200000,0.200000},{0.212500,0.337500,0.100000,0.100000},{0.212500,0.337500,0.200000,0.200000},{0.237500,0.337500,0.100000,0.100000},{0.237500,0.337500,0.200000,0.200000},{0.262500,0.337500,0.100000,0.100000},{0.262500,0.337500,0.200000,0.200000},{0.287500,0.337500,0.100000,0.100000},{0.287500,0.337500,0.200000,0.200000},{0.312500,0.337500,0.100000,0.100000},{0.312500,0.337500,0.200000,0.200000},{0.337500,0.337500,0.100000,0.100000},{0.337500,0.337500,0.200000,0.200000},{0.362500,0.337500,0.100000,0.100000},{0.362500,0.337500,0.200000,0.200000},{0.387500,0.337500,0.100000,0.100000},{0.387500,0.337500,0.200000,0.200000},{0.412500,0.337500,0.100000,0.100000},{0.412500,0.337500,0.200000,0.200000},{0.437500,0.337500,0.100000,0.100000},{0.437500,0.337500,0.200000,0.200000},{0.462500,0.337500,0.100000,0.100000},{0.462500,0.337500,0.200000,0.200000},{0.487500,0.337500,0.100000,0.100000},{0.487500,0.337500,0.200000,0.200000},{0.512500,0.337500,0.100000,0.100000},{0.512500,0.337500,0.200000,0.200000},{0.537500,0.337500,0.100000,0.100000},{0.537500,0.337500,0.200000,0.200000},{0.562500,0.337500,0.100000,0.100000},{0.562500,0.337500,0.200000,0.200000},{0.587500,0.337500,0.100000,0.100000},{0.587500,0.337500,0.200000,0.200000},{0.612500,0.337500,0.100000,0.100000},{0.612500,0.337500,0.200000,0.200000},{0.637500,0.337500,0.100000,0.100000},{0.637500,0.337500,0.200000,0.200000},{0.662500,0.337500,0.100000,0.100000},{0.662500,0.337500,0.200000,0.200000},{0.687500,0.337500,0.100000,0.100000},{0.687500,0.337500,0.200000,0.200000},{0.712500,0.337500,0.100000,0.100000},{0.712500,0.337500,0.200000,0.200000},{0.737500,0.337500,0.100000,0.100000},{0.737500,0.337500,0.200000,0.200000},{0.762500,0.337500,0.100000,0.100000},{0.762500,0.337500,0.200000,0.200000},{0.787500,0.337500,0.100000,0.100000},{0.787500,0.337500,0.200000,0.200000},{0.812500,0.337500,0.100000,0.100000},{0.812500,0.337500,0.200000,0.200000},{0.837500,0.337500,0.100000,0.100000},{0.837500,0.337500,0.200000,0.200000},{0.862500,0.337500,0.100000,0.100000},{0.862500,0.337500,0.200000,0.200000},{0.887500,0.337500,0.100000,0.100000},{0.887500,0.337500,0.200000,0.200000},{0.912500,0.337500,0.100000,0.100000},{0.912500,0.337500,0.200000,0.200000},{0.937500,0.337500,0.100000,0.100000},{0.937500,0.337500,0.200000,0.200000},{0.962500,0.337500,0.100000,0.100000},{0.962500,0.337500,0.200000,0.200000},{0.987500,0.337500,0.100000,0.100000},{0.987500,0.337500,0.200000,0.200000},{0.012500,0.362500,0.100000,0.100000},{0.012500,0.362500,0.200000,0.200000},{0.037500,0.362500,0.100000,0.100000},{0.037500,0.362500,0.200000,0.200000},{0.062500,0.362500,0.100000,0.100000},{0.062500,0.362500,0.200000,0.200000},{0.087500,0.362500,0.100000,0.100000},{0.087500,0.362500,0.200000,0.200000},{0.112500,0.362500,0.100000,0.100000},{0.112500,0.362500,0.200000,0.200000},{0.137500,0.362500,0.100000,0.100000},{0.137500,0.362500,0.200000,0.200000},{0.162500,0.362500,0.100000,0.100000},{0.162500,0.362500,0.200000,0.200000},{0.187500,0.362500,0.100000,0.100000},{0.187500,0.362500,0.200000,0.200000},{0.212500,0.362500,0.100000,0.100000},{0.212500,0.362500,0.200000,0.200000},{0.237500,0.362500,0.100000,0.100000},{0.237500,0.362500,0.200000,0.200000},{0.262500,0.362500,0.100000,0.100000},{0.262500,0.362500,0.200000,0.200000},{0.287500,0.362500,0.100000,0.100000},{0.287500,0.362500,0.200000,0.200000},{0.312500,0.362500,0.100000,0.100000},{0.312500,0.362500,0.200000,0.200000},{0.337500,0.362500,0.100000,0.100000},{0.337500,0.362500,0.200000,0.200000},{0.362500,0.362500,0.100000,0.100000},{0.362500,0.362500,0.200000,0.200000},{0.387500,0.362500,0.100000,0.100000},{0.387500,0.362500,0.200000,0.200000},{0.412500,0.362500,0.100000,0.100000},{0.412500,0.362500,0.200000,0.200000},{0.437500,0.362500,0.100000,0.100000},{0.437500,0.362500,0.200000,0.200000},{0.462500,0.362500,0.100000,0.100000},{0.462500,0.362500,0.200000,0.200000},{0.487500,0.362500,0.100000,0.100000},{0.487500,0.362500,0.200000,0.200000},{0.512500,0.362500,0.100000,0.100000},{0.512500,0.362500,0.200000,0.200000},{0.537500,0.362500,0.100000,0.100000},{0.537500,0.362500,0.200000,0.200000},{0.562500,0.362500,0.100000,0.100000},{0.562500,0.362500,0.200000,0.200000},{0.587500,0.362500,0.100000,0.100000},{0.587500,0.362500,0.200000,0.200000},{0.612500,0.362500,0.100000,0.100000},{0.612500,0.362500,0.200000,0.200000},{0.637500,0.362500,0.100000,0.100000},{0.637500,0.362500,0.200000,0.200000},{0.662500,0.362500,0.100000,0.100000},{0.662500,0.362500,0.200000,0.200000},{0.687500,0.362500,0.100000,0.100000},{0.687500,0.362500,0.200000,0.200000},{0.712500,0.362500,0.100000,0.100000},{0.712500,0.362500,0.200000,0.200000},{0.737500,0.362500,0.100000,0.100000},{0.737500,0.362500,0.200000,0.200000},{0.762500,0.362500,0.100000,0.100000},{0.762500,0.362500,0.200000,0.200000},{0.787500,0.362500,0.100000,0.100000},{0.787500,0.362500,0.200000,0.200000},{0.812500,0.362500,0.100000,0.100000},{0.812500,0.362500,0.200000,0.200000},{0.837500,0.362500,0.100000,0.100000},{0.837500,0.362500,0.200000,0.200000},{0.862500,0.362500,0.100000,0.100000},{0.862500,0.362500,0.200000,0.200000},{0.887500,0.362500,0.100000,0.100000},{0.887500,0.362500,0.200000,0.200000},{0.912500,0.362500,0.100000,0.100000},{0.912500,0.362500,0.200000,0.200000},{0.937500,0.362500,0.100000,0.100000},{0.937500,0.362500,0.200000,0.200000},{0.962500,0.362500,0.100000,0.100000},{0.962500,0.362500,0.200000,0.200000},{0.987500,0.362500,0.100000,0.100000},{0.987500,0.362500,0.200000,0.200000},{0.012500,0.387500,0.100000,0.100000},{0.012500,0.387500,0.200000,0.200000},{0.037500,0.387500,0.100000,0.100000},{0.037500,0.387500,0.200000,0.200000},{0.062500,0.387500,0.100000,0.100000},{0.062500,0.387500,0.200000,0.200000},{0.087500,0.387500,0.100000,0.100000},{0.087500,0.387500,0.200000,0.200000},{0.112500,0.387500,0.100000,0.100000},{0.112500,0.387500,0.200000,0.200000},{0.137500,0.387500,0.100000,0.100000},{0.137500,0.387500,0.200000,0.200000},{0.162500,0.387500,0.100000,0.100000},{0.162500,0.387500,0.200000,0.200000},{0.187500,0.387500,0.100000,0.100000},{0.187500,0.387500,0.200000,0.200000},{0.212500,0.387500,0.100000,0.100000},{0.212500,0.387500,0.200000,0.200000},{0.237500,0.387500,0.100000,0.100000},{0.237500,0.387500,0.200000,0.200000},{0.262500,0.387500,0.100000,0.100000},{0.262500,0.387500,0.200000,0.200000},{0.287500,0.387500,0.100000,0.100000},{0.287500,0.387500,0.200000,0.200000},{0.312500,0.387500,0.100000,0.100000},{0.312500,0.387500,0.200000,0.200000},{0.337500,0.387500,0.100000,0.100000},{0.337500,0.387500,0.200000,0.200000},{0.362500,0.387500,0.100000,0.100000},{0.362500,0.387500,0.200000,0.200000},{0.387500,0.387500,0.100000,0.100000},{0.387500,0.387500,0.200000,0.200000},{0.412500,0.387500,0.100000,0.100000},{0.412500,0.387500,0.200000,0.200000},{0.437500,0.387500,0.100000,0.100000},{0.437500,0.387500,0.200000,0.200000},{0.462500,0.387500,0.100000,0.100000},{0.462500,0.387500,0.200000,0.200000},{0.487500,0.387500,0.100000,0.100000},{0.487500,0.387500,0.200000,0.200000},{0.512500,0.387500,0.100000,0.100000},{0.512500,0.387500,0.200000,0.200000},{0.537500,0.387500,0.100000,0.100000},{0.537500,0.387500,0.200000,0.200000},{0.562500,0.387500,0.100000,0.100000},{0.562500,0.387500,0.200000,0.200000},{0.587500,0.387500,0.100000,0.100000},{0.587500,0.387500,0.200000,0.200000},{0.612500,0.387500,0.100000,0.100000},{0.612500,0.387500,0.200000,0.200000},{0.637500,0.387500,0.100000,0.100000},{0.637500,0.387500,0.200000,0.200000},{0.662500,0.387500,0.100000,0.100000},{0.662500,0.387500,0.200000,0.200000},{0.687500,0.387500,0.100000,0.100000},{0.687500,0.387500,0.200000,0.200000},{0.712500,0.387500,0.100000,0.100000},{0.712500,0.387500,0.200000,0.200000},{0.737500,0.387500,0.100000,0.100000},{0.737500,0.387500,0.200000,0.200000},{0.762500,0.387500,0.100000,0.100000},{0.762500,0.387500,0.200000,0.200000},{0.787500,0.387500,0.100000,0.100000},{0.787500,0.387500,0.200000,0.200000},{0.812500,0.387500,0.100000,0.100000},{0.812500,0.387500,0.200000,0.200000},{0.837500,0.387500,0.100000,0.100000},{0.837500,0.387500,0.200000,0.200000},{0.862500,0.387500,0.100000,0.100000},{0.862500,0.387500,0.200000,0.200000},{0.887500,0.387500,0.100000,0.100000},{0.887500,0.387500,0.200000,0.200000},{0.912500,0.387500,0.100000,0.100000},{0.912500,0.387500,0.200000,0.200000},{0.937500,0.387500,0.100000,0.100000},{0.937500,0.387500,0.200000,0.200000},{0.962500,0.387500,0.100000,0.100000},{0.962500,0.387500,0.200000,0.200000},{0.987500,0.387500,0.100000,0.100000},{0.987500,0.387500,0.200000,0.200000},{0.012500,0.412500,0.100000,0.100000},{0.012500,0.412500,0.200000,0.200000},{0.037500,0.412500,0.100000,0.100000},{0.037500,0.412500,0.200000,0.200000},{0.062500,0.412500,0.100000,0.100000},{0.062500,0.412500,0.200000,0.200000},{0.087500,0.412500,0.100000,0.100000},{0.087500,0.412500,0.200000,0.200000},{0.112500,0.412500,0.100000,0.100000},{0.112500,0.412500,0.200000,0.200000},{0.137500,0.412500,0.100000,0.100000},{0.137500,0.412500,0.200000,0.200000},{0.162500,0.412500,0.100000,0.100000},{0.162500,0.412500,0.200000,0.200000},{0.187500,0.412500,0.100000,0.100000},{0.187500,0.412500,0.200000,0.200000},{0.212500,0.412500,0.100000,0.100000},{0.212500,0.412500,0.200000,0.200000},{0.237500,0.412500,0.100000,0.100000},{0.237500,0.412500,0.200000,0.200000},{0.262500,0.412500,0.100000,0.100000},{0.262500,0.412500,0.200000,0.200000},{0.287500,0.412500,0.100000,0.100000},{0.287500,0.412500,0.200000,0.200000},{0.312500,0.412500,0.100000,0.100000},{0.312500,0.412500,0.200000,0.200000},{0.337500,0.412500,0.100000,0.100000},{0.337500,0.412500,0.200000,0.200000},{0.362500,0.412500,0.100000,0.100000},{0.362500,0.412500,0.200000,0.200000},{0.387500,0.412500,0.100000,0.100000},{0.387500,0.412500,0.200000,0.200000},{0.412500,0.412500,0.100000,0.100000},{0.412500,0.412500,0.200000,0.200000},{0.437500,0.412500,0.100000,0.100000},{0.437500,0.412500,0.200000,0.200000},{0.462500,0.412500,0.100000,0.100000},{0.462500,0.412500,0.200000,0.200000},{0.487500,0.412500,0.100000,0.100000},{0.487500,0.412500,0.200000,0.200000},{0.512500,0.412500,0.100000,0.100000},{0.512500,0.412500,0.200000,0.200000},{0.537500,0.412500,0.100000,0.100000},{0.537500,0.412500,0.200000,0.200000},{0.562500,0.412500,0.100000,0.100000},{0.562500,0.412500,0.200000,0.200000},{0.587500,0.412500,0.100000,0.100000},{0.587500,0.412500,0.200000,0.200000},{0.612500,0.412500,0.100000,0.100000},{0.612500,0.412500,0.200000,0.200000},{0.637500,0.412500,0.100000,0.100000},{0.637500,0.412500,0.200000,0.200000},{0.662500,0.412500,0.100000,0.100000},{0.662500,0.412500,0.200000,0.200000},{0.687500,0.412500,0.100000,0.100000},{0.687500,0.412500,0.200000,0.200000},{0.712500,0.412500,0.100000,0.100000},{0.712500,0.412500,0.200000,0.200000},{0.737500,0.412500,0.100000,0.100000},{0.737500,0.412500,0.200000,0.200000},{0.762500,0.412500,0.100000,0.100000},{0.762500,0.412500,0.200000,0.200000},{0.787500,0.412500,0.100000,0.100000},{0.787500,0.412500,0.200000,0.200000},{0.812500,0.412500,0.100000,0.100000},{0.812500,0.412500,0.200000,0.200000},{0.837500,0.412500,0.100000,0.100000},{0.837500,0.412500,0.200000,0.200000},{0.862500,0.412500,0.100000,0.100000},{0.862500,0.412500,0.200000,0.200000},{0.887500,0.412500,0.100000,0.100000},{0.887500,0.412500,0.200000,0.200000},{0.912500,0.412500,0.100000,0.100000},{0.912500,0.412500,0.200000,0.200000},{0.937500,0.412500,0.100000,0.100000},{0.937500,0.412500,0.200000,0.200000},{0.962500,0.412500,0.100000,0.100000},{0.962500,0.412500,0.200000,0.200000},{0.987500,0.412500,0.100000,0.100000},{0.987500,0.412500,0.200000,0.200000},{0.012500,0.437500,0.100000,0.100000},{0.012500,0.437500,0.200000,0.200000},{0.037500,0.437500,0.100000,0.100000},{0.037500,0.437500,0.200000,0.200000},{0.062500,0.437500,0.100000,0.100000},{0.062500,0.437500,0.200000,0.200000},{0.087500,0.437500,0.100000,0.100000},{0.087500,0.437500,0.200000,0.200000},{0.112500,0.437500,0.100000,0.100000},{0.112500,0.437500,0.200000,0.200000},{0.137500,0.437500,0.100000,0.100000},{0.137500,0.437500,0.200000,0.200000},{0.162500,0.437500,0.100000,0.100000},{0.162500,0.437500,0.200000,0.200000},{0.187500,0.437500,0.100000,0.100000},{0.187500,0.437500,0.200000,0.200000},{0.212500,0.437500,0.100000,0.100000},{0.212500,0.437500,0.200000,0.200000},{0.237500,0.437500,0.100000,0.100000},{0.237500,0.437500,0.200000,0.200000},{0.262500,0.437500,0.100000,0.100000},{0.262500,0.437500,0.200000,0.200000},{0.287500,0.437500,0.100000,0.100000},{0.287500,0.437500,0.200000,0.200000},{0.312500,0.437500,0.100000,0.100000},{0.312500,0.437500,0.200000,0.200000},{0.337500,0.437500,0.100000,0.100000},{0.337500,0.437500,0.200000,0.200000},{0.362500,0.437500,0.100000,0.100000},{0.362500,0.437500,0.200000,0.200000},{0.387500,0.437500,0.100000,0.100000},{0.387500,0.437500,0.200000,0.200000},{0.412500,0.437500,0.100000,0.100000},{0.412500,0.437500,0.200000,0.200000},{0.437500,0.437500,0.100000,0.100000},{0.437500,0.437500,0.200000,0.200000},{0.462500,0.437500,0.100000,0.100000},{0.462500,0.437500,0.200000,0.200000},{0.487500,0.437500,0.100000,0.100000},{0.487500,0.437500,0.200000,0.200000},{0.512500,0.437500,0.100000,0.100000},{0.512500,0.437500,0.200000,0.200000},{0.537500,0.437500,0.100000,0.100000},{0.537500,0.437500,0.200000,0.200000},{0.562500,0.437500,0.100000,0.100000},{0.562500,0.437500,0.200000,0.200000},{0.587500,0.437500,0.100000,0.100000},{0.587500,0.437500,0.200000,0.200000},{0.612500,0.437500,0.100000,0.100000},{0.612500,0.437500,0.200000,0.200000},{0.637500,0.437500,0.100000,0.100000},{0.637500,0.437500,0.200000,0.200000},{0.662500,0.437500,0.100000,0.100000},{0.662500,0.437500,0.200000,0.200000},{0.687500,0.437500,0.100000,0.100000},{0.687500,0.437500,0.200000,0.200000},{0.712500,0.437500,0.100000,0.100000},{0.712500,0.437500,0.200000,0.200000},{0.737500,0.437500,0.100000,0.100000},{0.737500,0.437500,0.200000,0.200000},{0.762500,0.437500,0.100000,0.100000},{0.762500,0.437500,0.200000,0.200000},{0.787500,0.437500,0.100000,0.100000},{0.787500,0.437500,0.200000,0.200000},{0.812500,0.437500,0.100000,0.100000},{0.812500,0.437500,0.200000,0.200000},{0.837500,0.437500,0.100000,0.100000},{0.837500,0.437500,0.200000,0.200000},{0.862500,0.437500,0.100000,0.100000},{0.862500,0.437500,0.200000,0.200000},{0.887500,0.437500,0.100000,0.100000},{0.887500,0.437500,0.200000,0.200000},{0.912500,0.437500,0.100000,0.100000},{0.912500,0.437500,0.200000,0.200000},{0.937500,0.437500,0.100000,0.100000},{0.937500,0.437500,0.200000,0.200000},{0.962500,0.437500,0.100000,0.100000},{0.962500,0.437500,0.200000,0.200000},{0.987500,0.437500,0.100000,0.100000},{0.987500,0.437500,0.200000,0.200000},{0.012500,0.462500,0.100000,0.100000},{0.012500,0.462500,0.200000,0.200000},{0.037500,0.462500,0.100000,0.100000},{0.037500,0.462500,0.200000,0.200000},{0.062500,0.462500,0.100000,0.100000},{0.062500,0.462500,0.200000,0.200000},{0.087500,0.462500,0.100000,0.100000},{0.087500,0.462500,0.200000,0.200000},{0.112500,0.462500,0.100000,0.100000},{0.112500,0.462500,0.200000,0.200000},{0.137500,0.462500,0.100000,0.100000},{0.137500,0.462500,0.200000,0.200000},{0.162500,0.462500,0.100000,0.100000},{0.162500,0.462500,0.200000,0.200000},{0.187500,0.462500,0.100000,0.100000},{0.187500,0.462500,0.200000,0.200000},{0.212500,0.462500,0.100000,0.100000},{0.212500,0.462500,0.200000,0.200000},{0.237500,0.462500,0.100000,0.100000},{0.237500,0.462500,0.200000,0.200000},{0.262500,0.462500,0.100000,0.100000},{0.262500,0.462500,0.200000,0.200000},{0.287500,0.462500,0.100000,0.100000},{0.287500,0.462500,0.200000,0.200000},{0.312500,0.462500,0.100000,0.100000},{0.312500,0.462500,0.200000,0.200000},{0.337500,0.462500,0.100000,0.100000},{0.337500,0.462500,0.200000,0.200000},{0.362500,0.462500,0.100000,0.100000},{0.362500,0.462500,0.200000,0.200000},{0.387500,0.462500,0.100000,0.100000},{0.387500,0.462500,0.200000,0.200000},{0.412500,0.462500,0.100000,0.100000},{0.412500,0.462500,0.200000,0.200000},{0.437500,0.462500,0.100000,0.100000},{0.437500,0.462500,0.200000,0.200000},{0.462500,0.462500,0.100000,0.100000},{0.462500,0.462500,0.200000,0.200000},{0.487500,0.462500,0.100000,0.100000},{0.487500,0.462500,0.200000,0.200000},{0.512500,0.462500,0.100000,0.100000},{0.512500,0.462500,0.200000,0.200000},{0.537500,0.462500,0.100000,0.100000},{0.537500,0.462500,0.200000,0.200000},{0.562500,0.462500,0.100000,0.100000},{0.562500,0.462500,0.200000,0.200000},{0.587500,0.462500,0.100000,0.100000},{0.587500,0.462500,0.200000,0.200000},{0.612500,0.462500,0.100000,0.100000},{0.612500,0.462500,0.200000,0.200000},{0.637500,0.462500,0.100000,0.100000},{0.637500,0.462500,0.200000,0.200000},{0.662500,0.462500,0.100000,0.100000},{0.662500,0.462500,0.200000,0.200000},{0.687500,0.462500,0.100000,0.100000},{0.687500,0.462500,0.200000,0.200000},{0.712500,0.462500,0.100000,0.100000},{0.712500,0.462500,0.200000,0.200000},{0.737500,0.462500,0.100000,0.100000},{0.737500,0.462500,0.200000,0.200000},{0.762500,0.462500,0.100000,0.100000},{0.762500,0.462500,0.200000,0.200000},{0.787500,0.462500,0.100000,0.100000},{0.787500,0.462500,0.200000,0.200000},{0.812500,0.462500,0.100000,0.100000},{0.812500,0.462500,0.200000,0.200000},{0.837500,0.462500,0.100000,0.100000},{0.837500,0.462500,0.200000,0.200000},{0.862500,0.462500,0.100000,0.100000},{0.862500,0.462500,0.200000,0.200000},{0.887500,0.462500,0.100000,0.100000},{0.887500,0.462500,0.200000,0.200000},{0.912500,0.462500,0.100000,0.100000},{0.912500,0.462500,0.200000,0.200000},{0.937500,0.462500,0.100000,0.100000},{0.937500,0.462500,0.200000,0.200000},{0.962500,0.462500,0.100000,0.100000},{0.962500,0.462500,0.200000,0.200000},{0.987500,0.462500,0.100000,0.100000},{0.987500,0.462500,0.200000,0.200000},{0.012500,0.487500,0.100000,0.100000},{0.012500,0.487500,0.200000,0.200000},{0.037500,0.487500,0.100000,0.100000},{0.037500,0.487500,0.200000,0.200000},{0.062500,0.487500,0.100000,0.100000},{0.062500,0.487500,0.200000,0.200000},{0.087500,0.487500,0.100000,0.100000},{0.087500,0.487500,0.200000,0.200000},{0.112500,0.487500,0.100000,0.100000},{0.112500,0.487500,0.200000,0.200000},{0.137500,0.487500,0.100000,0.100000},{0.137500,0.487500,0.200000,0.200000},{0.162500,0.487500,0.100000,0.100000},{0.162500,0.487500,0.200000,0.200000},{0.187500,0.487500,0.100000,0.100000},{0.187500,0.487500,0.200000,0.200000},{0.212500,0.487500,0.100000,0.100000},{0.212500,0.487500,0.200000,0.200000},{0.237500,0.487500,0.100000,0.100000},{0.237500,0.487500,0.200000,0.200000},{0.262500,0.487500,0.100000,0.100000},{0.262500,0.487500,0.200000,0.200000},{0.287500,0.487500,0.100000,0.100000},{0.287500,0.487500,0.200000,0.200000},{0.312500,0.487500,0.100000,0.100000},{0.312500,0.487500,0.200000,0.200000},{0.337500,0.487500,0.100000,0.100000},{0.337500,0.487500,0.200000,0.200000},{0.362500,0.487500,0.100000,0.100000},{0.362500,0.487500,0.200000,0.200000},{0.387500,0.487500,0.100000,0.100000},{0.387500,0.487500,0.200000,0.200000},{0.412500,0.487500,0.100000,0.100000},{0.412500,0.487500,0.200000,0.200000},{0.437500,0.487500,0.100000,0.100000},{0.437500,0.487500,0.200000,0.200000},{0.462500,0.487500,0.100000,0.100000},{0.462500,0.487500,0.200000,0.200000},{0.487500,0.487500,0.100000,0.100000},{0.487500,0.487500,0.200000,0.200000},{0.512500,0.487500,0.100000,0.100000},{0.512500,0.487500,0.200000,0.200000},{0.537500,0.487500,0.100000,0.100000},{0.537500,0.487500,0.200000,0.200000},{0.562500,0.487500,0.100000,0.100000},{0.562500,0.487500,0.200000,0.200000},{0.587500,0.487500,0.100000,0.100000},{0.587500,0.487500,0.200000,0.200000},{0.612500,0.487500,0.100000,0.100000},{0.612500,0.487500,0.200000,0.200000},{0.637500,0.487500,0.100000,0.100000},{0.637500,0.487500,0.200000,0.200000},{0.662500,0.487500,0.100000,0.100000},{0.662500,0.487500,0.200000,0.200000},{0.687500,0.487500,0.100000,0.100000},{0.687500,0.487500,0.200000,0.200000},{0.712500,0.487500,0.100000,0.100000},{0.712500,0.487500,0.200000,0.200000},{0.737500,0.487500,0.100000,0.100000},{0.737500,0.487500,0.200000,0.200000},{0.762500,0.487500,0.100000,0.100000},{0.762500,0.487500,0.200000,0.200000},{0.787500,0.487500,0.100000,0.100000},{0.787500,0.487500,0.200000,0.200000},{0.812500,0.487500,0.100000,0.100000},{0.812500,0.487500,0.200000,0.200000},{0.837500,0.487500,0.100000,0.100000},{0.837500,0.487500,0.200000,0.200000},{0.862500,0.487500,0.100000,0.100000},{0.862500,0.487500,0.200000,0.200000},{0.887500,0.487500,0.100000,0.100000},{0.887500,0.487500,0.200000,0.200000},{0.912500,0.487500,0.100000,0.100000},{0.912500,0.487500,0.200000,0.200000},{0.937500,0.487500,0.100000,0.100000},{0.937500,0.487500,0.200000,0.200000},{0.962500,0.487500,0.100000,0.100000},{0.962500,0.487500,0.200000,0.200000},{0.987500,0.487500,0.100000,0.100000},{0.987500,0.487500,0.200000,0.200000},{0.012500,0.512500,0.100000,0.100000},{0.012500,0.512500,0.200000,0.200000},{0.037500,0.512500,0.100000,0.100000},{0.037500,0.512500,0.200000,0.200000},{0.062500,0.512500,0.100000,0.100000},{0.062500,0.512500,0.200000,0.200000},{0.087500,0.512500,0.100000,0.100000},{0.087500,0.512500,0.200000,0.200000},{0.112500,0.512500,0.100000,0.100000},{0.112500,0.512500,0.200000,0.200000},{0.137500,0.512500,0.100000,0.100000},{0.137500,0.512500,0.200000,0.200000},{0.162500,0.512500,0.100000,0.100000},{0.162500,0.512500,0.200000,0.200000},{0.187500,0.512500,0.100000,0.100000},{0.187500,0.512500,0.200000,0.200000},{0.212500,0.512500,0.100000,0.100000},{0.212500,0.512500,0.200000,0.200000},{0.237500,0.512500,0.100000,0.100000},{0.237500,0.512500,0.200000,0.200000},{0.262500,0.512500,0.100000,0.100000},{0.262500,0.512500,0.200000,0.200000},{0.287500,0.512500,0.100000,0.100000},{0.287500,0.512500,0.200000,0.200000},{0.312500,0.512500,0.100000,0.100000},{0.312500,0.512500,0.200000,0.200000},{0.337500,0.512500,0.100000,0.100000},{0.337500,0.512500,0.200000,0.200000},{0.362500,0.512500,0.100000,0.100000},{0.362500,0.512500,0.200000,0.200000},{0.387500,0.512500,0.100000,0.100000},{0.387500,0.512500,0.200000,0.200000},{0.412500,0.512500,0.100000,0.100000},{0.412500,0.512500,0.200000,0.200000},{0.437500,0.512500,0.100000,0.100000},{0.437500,0.512500,0.200000,0.200000},{0.462500,0.512500,0.100000,0.100000},{0.462500,0.512500,0.200000,0.200000},{0.487500,0.512500,0.100000,0.100000},{0.487500,0.512500,0.200000,0.200000},{0.512500,0.512500,0.100000,0.100000},{0.512500,0.512500,0.200000,0.200000},{0.537500,0.512500,0.100000,0.100000},{0.537500,0.512500,0.200000,0.200000},{0.562500,0.512500,0.100000,0.100000},{0.562500,0.512500,0.200000,0.200000},{0.587500,0.512500,0.100000,0.100000},{0.587500,0.512500,0.200000,0.200000},{0.612500,0.512500,0.100000,0.100000},{0.612500,0.512500,0.200000,0.200000},{0.637500,0.512500,0.100000,0.100000},{0.637500,0.512500,0.200000,0.200000},{0.662500,0.512500,0.100000,0.100000},{0.662500,0.512500,0.200000,0.200000},{0.687500,0.512500,0.100000,0.100000},{0.687500,0.512500,0.200000,0.200000},{0.712500,0.512500,0.100000,0.100000},{0.712500,0.512500,0.200000,0.200000},{0.737500,0.512500,0.100000,0.100000},{0.737500,0.512500,0.200000,0.200000},{0.762500,0.512500,0.100000,0.100000},{0.762500,0.512500,0.200000,0.200000},{0.787500,0.512500,0.100000,0.100000},{0.787500,0.512500,0.200000,0.200000},{0.812500,0.512500,0.100000,0.100000},{0.812500,0.512500,0.200000,0.200000},{0.837500,0.512500,0.100000,0.100000},{0.837500,0.512500,0.200000,0.200000},{0.862500,0.512500,0.100000,0.100000},{0.862500,0.512500,0.200000,0.200000},{0.887500,0.512500,0.100000,0.100000},{0.887500,0.512500,0.200000,0.200000},{0.912500,0.512500,0.100000,0.100000},{0.912500,0.512500,0.200000,0.200000},{0.937500,0.512500,0.100000,0.100000},{0.937500,0.512500,0.200000,0.200000},{0.962500,0.512500,0.100000,0.100000},{0.962500,0.512500,0.200000,0.200000},{0.987500,0.512500,0.100000,0.100000},{0.987500,0.512500,0.200000,0.200000},{0.012500,0.537500,0.100000,0.100000},{0.012500,0.537500,0.200000,0.200000},{0.037500,0.537500,0.100000,0.100000},{0.037500,0.537500,0.200000,0.200000},{0.062500,0.537500,0.100000,0.100000},{0.062500,0.537500,0.200000,0.200000},{0.087500,0.537500,0.100000,0.100000},{0.087500,0.537500,0.200000,0.200000},{0.112500,0.537500,0.100000,0.100000},{0.112500,0.537500,0.200000,0.200000},{0.137500,0.537500,0.100000,0.100000},{0.137500,0.537500,0.200000,0.200000},{0.162500,0.537500,0.100000,0.100000},{0.162500,0.537500,0.200000,0.200000},{0.187500,0.537500,0.100000,0.100000},{0.187500,0.537500,0.200000,0.200000},{0.212500,0.537500,0.100000,0.100000},{0.212500,0.537500,0.200000,0.200000},{0.237500,0.537500,0.100000,0.100000},{0.237500,0.537500,0.200000,0.200000},{0.262500,0.537500,0.100000,0.100000},{0.262500,0.537500,0.200000,0.200000},{0.287500,0.537500,0.100000,0.100000},{0.287500,0.537500,0.200000,0.200000},{0.312500,0.537500,0.100000,0.100000},{0.312500,0.537500,0.200000,0.200000},{0.337500,0.537500,0.100000,0.100000},{0.337500,0.537500,0.200000,0.200000},{0.362500,0.537500,0.100000,0.100000},{0.362500,0.537500,0.200000,0.200000},{0.387500,0.537500,0.100000,0.100000},{0.387500,0.537500,0.200000,0.200000},{0.412500,0.537500,0.100000,0.100000},{0.412500,0.537500,0.200000,0.200000},{0.437500,0.537500,0.100000,0.100000},{0.437500,0.537500,0.200000,0.200000},{0.462500,0.537500,0.100000,0.100000},{0.462500,0.537500,0.200000,0.200000},{0.487500,0.537500,0.100000,0.100000},{0.487500,0.537500,0.200000,0.200000},{0.512500,0.537500,0.100000,0.100000},{0.512500,0.537500,0.200000,0.200000},{0.537500,0.537500,0.100000,0.100000},{0.537500,0.537500,0.200000,0.200000},{0.562500,0.537500,0.100000,0.100000},{0.562500,0.537500,0.200000,0.200000},{0.587500,0.537500,0.100000,0.100000},{0.587500,0.537500,0.200000,0.200000},{0.612500,0.537500,0.100000,0.100000},{0.612500,0.537500,0.200000,0.200000},{0.637500,0.537500,0.100000,0.100000},{0.637500,0.537500,0.200000,0.200000},{0.662500,0.537500,0.100000,0.100000},{0.662500,0.537500,0.200000,0.200000},{0.687500,0.537500,0.100000,0.100000},{0.687500,0.537500,0.200000,0.200000},{0.712500,0.537500,0.100000,0.100000},{0.712500,0.537500,0.200000,0.200000},{0.737500,0.537500,0.100000,0.100000},{0.737500,0.537500,0.200000,0.200000},{0.762500,0.537500,0.100000,0.100000},{0.762500,0.537500,0.200000,0.200000},{0.787500,0.537500,0.100000,0.100000},{0.787500,0.537500,0.200000,0.200000},{0.812500,0.537500,0.100000,0.100000},{0.812500,0.537500,0.200000,0.200000},{0.837500,0.537500,0.100000,0.100000},{0.837500,0.537500,0.200000,0.200000},{0.862500,0.537500,0.100000,0.100000},{0.862500,0.537500,0.200000,0.200000},{0.887500,0.537500,0.100000,0.100000},{0.887500,0.537500,0.200000,0.200000},{0.912500,0.537500,0.100000,0.100000},{0.912500,0.537500,0.200000,0.200000},{0.937500,0.537500,0.100000,0.100000},{0.937500,0.537500,0.200000,0.200000},{0.962500,0.537500,0.100000,0.100000},{0.962500,0.537500,0.200000,0.200000},{0.987500,0.537500,0.100000,0.100000},{0.987500,0.537500,0.200000,0.200000},{0.012500,0.562500,0.100000,0.100000},{0.012500,0.562500,0.200000,0.200000},{0.037500,0.562500,0.100000,0.100000},{0.037500,0.562500,0.200000,0.200000},{0.062500,0.562500,0.100000,0.100000},{0.062500,0.562500,0.200000,0.200000},{0.087500,0.562500,0.100000,0.100000},{0.087500,0.562500,0.200000,0.200000},{0.112500,0.562500,0.100000,0.100000},{0.112500,0.562500,0.200000,0.200000},{0.137500,0.562500,0.100000,0.100000},{0.137500,0.562500,0.200000,0.200000},{0.162500,0.562500,0.100000,0.100000},{0.162500,0.562500,0.200000,0.200000},{0.187500,0.562500,0.100000,0.100000},{0.187500,0.562500,0.200000,0.200000},{0.212500,0.562500,0.100000,0.100000},{0.212500,0.562500,0.200000,0.200000},{0.237500,0.562500,0.100000,0.100000},{0.237500,0.562500,0.200000,0.200000},{0.262500,0.562500,0.100000,0.100000},{0.262500,0.562500,0.200000,0.200000},{0.287500,0.562500,0.100000,0.100000},{0.287500,0.562500,0.200000,0.200000},{0.312500,0.562500,0.100000,0.100000},{0.312500,0.562500,0.200000,0.200000},{0.337500,0.562500,0.100000,0.100000},{0.337500,0.562500,0.200000,0.200000},{0.362500,0.562500,0.100000,0.100000},{0.362500,0.562500,0.200000,0.200000},{0.387500,0.562500,0.100000,0.100000},{0.387500,0.562500,0.200000,0.200000},{0.412500,0.562500,0.100000,0.100000},{0.412500,0.562500,0.200000,0.200000},{0.437500,0.562500,0.100000,0.100000},{0.437500,0.562500,0.200000,0.200000},{0.462500,0.562500,0.100000,0.100000},{0.462500,0.562500,0.200000,0.200000},{0.487500,0.562500,0.100000,0.100000},{0.487500,0.562500,0.200000,0.200000},{0.512500,0.562500,0.100000,0.100000},{0.512500,0.562500,0.200000,0.200000},{0.537500,0.562500,0.100000,0.100000},{0.537500,0.562500,0.200000,0.200000},{0.562500,0.562500,0.100000,0.100000},{0.562500,0.562500,0.200000,0.200000},{0.587500,0.562500,0.100000,0.100000},{0.587500,0.562500,0.200000,0.200000},{0.612500,0.562500,0.100000,0.100000},{0.612500,0.562500,0.200000,0.200000},{0.637500,0.562500,0.100000,0.100000},{0.637500,0.562500,0.200000,0.200000},{0.662500,0.562500,0.100000,0.100000},{0.662500,0.562500,0.200000,0.200000},{0.687500,0.562500,0.100000,0.100000},{0.687500,0.562500,0.200000,0.200000},{0.712500,0.562500,0.100000,0.100000},{0.712500,0.562500,0.200000,0.200000},{0.737500,0.562500,0.100000,0.100000},{0.737500,0.562500,0.200000,0.200000},{0.762500,0.562500,0.100000,0.100000},{0.762500,0.562500,0.200000,0.200000},{0.787500,0.562500,0.100000,0.100000},{0.787500,0.562500,0.200000,0.200000},{0.812500,0.562500,0.100000,0.100000},{0.812500,0.562500,0.200000,0.200000},{0.837500,0.562500,0.100000,0.100000},{0.837500,0.562500,0.200000,0.200000},{0.862500,0.562500,0.100000,0.100000},{0.862500,0.562500,0.200000,0.200000},{0.887500,0.562500,0.100000,0.100000},{0.887500,0.562500,0.200000,0.200000},{0.912500,0.562500,0.100000,0.100000},{0.912500,0.562500,0.200000,0.200000},{0.937500,0.562500,0.100000,0.100000},{0.937500,0.562500,0.200000,0.200000},{0.962500,0.562500,0.100000,0.100000},{0.962500,0.562500,0.200000,0.200000},{0.987500,0.562500,0.100000,0.100000},{0.987500,0.562500,0.200000,0.200000},{0.012500,0.587500,0.100000,0.100000},{0.012500,0.587500,0.200000,0.200000},{0.037500,0.587500,0.100000,0.100000},{0.037500,0.587500,0.200000,0.200000},{0.062500,0.587500,0.100000,0.100000},{0.062500,0.587500,0.200000,0.200000},{0.087500,0.587500,0.100000,0.100000},{0.087500,0.587500,0.200000,0.200000},{0.112500,0.587500,0.100000,0.100000},{0.112500,0.587500,0.200000,0.200000},{0.137500,0.587500,0.100000,0.100000},{0.137500,0.587500,0.200000,0.200000},{0.162500,0.587500,0.100000,0.100000},{0.162500,0.587500,0.200000,0.200000},{0.187500,0.587500,0.100000,0.100000},{0.187500,0.587500,0.200000,0.200000},{0.212500,0.587500,0.100000,0.100000},{0.212500,0.587500,0.200000,0.200000},{0.237500,0.587500,0.100000,0.100000},{0.237500,0.587500,0.200000,0.200000},{0.262500,0.587500,0.100000,0.100000},{0.262500,0.587500,0.200000,0.200000},{0.287500,0.587500,0.100000,0.100000},{0.287500,0.587500,0.200000,0.200000},{0.312500,0.587500,0.100000,0.100000},{0.312500,0.587500,0.200000,0.200000},{0.337500,0.587500,0.100000,0.100000},{0.337500,0.587500,0.200000,0.200000},{0.362500,0.587500,0.100000,0.100000},{0.362500,0.587500,0.200000,0.200000},{0.387500,0.587500,0.100000,0.100000},{0.387500,0.587500,0.200000,0.200000},{0.412500,0.587500,0.100000,0.100000},{0.412500,0.587500,0.200000,0.200000},{0.437500,0.587500,0.100000,0.100000},{0.437500,0.587500,0.200000,0.200000},{0.462500,0.587500,0.100000,0.100000},{0.462500,0.587500,0.200000,0.200000},{0.487500,0.587500,0.100000,0.100000},{0.487500,0.587500,0.200000,0.200000},{0.512500,0.587500,0.100000,0.100000},{0.512500,0.587500,0.200000,0.200000},{0.537500,0.587500,0.100000,0.100000},{0.537500,0.587500,0.200000,0.200000},{0.562500,0.587500,0.100000,0.100000},{0.562500,0.587500,0.200000,0.200000},{0.587500,0.587500,0.100000,0.100000},{0.587500,0.587500,0.200000,0.200000},{0.612500,0.587500,0.100000,0.100000},{0.612500,0.587500,0.200000,0.200000},{0.637500,0.587500,0.100000,0.100000},{0.637500,0.587500,0.200000,0.200000},{0.662500,0.587500,0.100000,0.100000},{0.662500,0.587500,0.200000,0.200000},{0.687500,0.587500,0.100000,0.100000},{0.687500,0.587500,0.200000,0.200000},{0.712500,0.587500,0.100000,0.100000},{0.712500,0.587500,0.200000,0.200000},{0.737500,0.587500,0.100000,0.100000},{0.737500,0.587500,0.200000,0.200000},{0.762500,0.587500,0.100000,0.100000},{0.762500,0.587500,0.200000,0.200000},{0.787500,0.587500,0.100000,0.100000},{0.787500,0.587500,0.200000,0.200000},{0.812500,0.587500,0.100000,0.100000},{0.812500,0.587500,0.200000,0.200000},{0.837500,0.587500,0.100000,0.100000},{0.837500,0.587500,0.200000,0.200000},{0.862500,0.587500,0.100000,0.100000},{0.862500,0.587500,0.200000,0.200000},{0.887500,0.587500,0.100000,0.100000},{0.887500,0.587500,0.200000,0.200000},{0.912500,0.587500,0.100000,0.100000},{0.912500,0.587500,0.200000,0.200000},{0.937500,0.587500,0.100000,0.100000},{0.937500,0.587500,0.200000,0.200000},{0.962500,0.587500,0.100000,0.100000},{0.962500,0.587500,0.200000,0.200000},{0.987500,0.587500,0.100000,0.100000},{0.987500,0.587500,0.200000,0.200000},{0.012500,0.612500,0.100000,0.100000},{0.012500,0.612500,0.200000,0.200000},{0.037500,0.612500,0.100000,0.100000},{0.037500,0.612500,0.200000,0.200000},{0.062500,0.612500,0.100000,0.100000},{0.062500,0.612500,0.200000,0.200000},{0.087500,0.612500,0.100000,0.100000},{0.087500,0.612500,0.200000,0.200000},{0.112500,0.612500,0.100000,0.100000},{0.112500,0.612500,0.200000,0.200000},{0.137500,0.612500,0.100000,0.100000},{0.137500,0.612500,0.200000,0.200000},{0.162500,0.612500,0.100000,0.100000},{0.162500,0.612500,0.200000,0.200000},{0.187500,0.612500,0.100000,0.100000},{0.187500,0.612500,0.200000,0.200000},{0.212500,0.612500,0.100000,0.100000},{0.212500,0.612500,0.200000,0.200000},{0.237500,0.612500,0.100000,0.100000},{0.237500,0.612500,0.200000,0.200000},{0.262500,0.612500,0.100000,0.100000},{0.262500,0.612500,0.200000,0.200000},{0.287500,0.612500,0.100000,0.100000},{0.287500,0.612500,0.200000,0.200000},{0.312500,0.612500,0.100000,0.100000},{0.312500,0.612500,0.200000,0.200000},{0.337500,0.612500,0.100000,0.100000},{0.337500,0.612500,0.200000,0.200000},{0.362500,0.612500,0.100000,0.100000},{0.362500,0.612500,0.200000,0.200000},{0.387500,0.612500,0.100000,0.100000},{0.387500,0.612500,0.200000,0.200000},{0.412500,0.612500,0.100000,0.100000},{0.412500,0.612500,0.200000,0.200000},{0.437500,0.612500,0.100000,0.100000},{0.437500,0.612500,0.200000,0.200000},{0.462500,0.612500,0.100000,0.100000},{0.462500,0.612500,0.200000,0.200000},{0.487500,0.612500,0.100000,0.100000},{0.487500,0.612500,0.200000,0.200000},{0.512500,0.612500,0.100000,0.100000},{0.512500,0.612500,0.200000,0.200000},{0.537500,0.612500,0.100000,0.100000},{0.537500,0.612500,0.200000,0.200000},{0.562500,0.612500,0.100000,0.100000},{0.562500,0.612500,0.200000,0.200000},{0.587500,0.612500,0.100000,0.100000},{0.587500,0.612500,0.200000,0.200000},{0.612500,0.612500,0.100000,0.100000},{0.612500,0.612500,0.200000,0.200000},{0.637500,0.612500,0.100000,0.100000},{0.637500,0.612500,0.200000,0.200000},{0.662500,0.612500,0.100000,0.100000},{0.662500,0.612500,0.200000,0.200000},{0.687500,0.612500,0.100000,0.100000},{0.687500,0.612500,0.200000,0.200000},{0.712500,0.612500,0.100000,0.100000},{0.712500,0.612500,0.200000,0.200000},{0.737500,0.612500,0.100000,0.100000},{0.737500,0.612500,0.200000,0.200000},{0.762500,0.612500,0.100000,0.100000},{0.762500,0.612500,0.200000,0.200000},{0.787500,0.612500,0.100000,0.100000},{0.787500,0.612500,0.200000,0.200000},{0.812500,0.612500,0.100000,0.100000},{0.812500,0.612500,0.200000,0.200000},{0.837500,0.612500,0.100000,0.100000},{0.837500,0.612500,0.200000,0.200000},{0.862500,0.612500,0.100000,0.100000},{0.862500,0.612500,0.200000,0.200000},{0.887500,0.612500,0.100000,0.100000},{0.887500,0.612500,0.200000,0.200000},{0.912500,0.612500,0.100000,0.100000},{0.912500,0.612500,0.200000,0.200000},{0.937500,0.612500,0.100000,0.100000},{0.937500,0.612500,0.200000,0.200000},{0.962500,0.612500,0.100000,0.100000},{0.962500,0.612500,0.200000,0.200000},{0.987500,0.612500,0.100000,0.100000},{0.987500,0.612500,0.200000,0.200000},{0.012500,0.637500,0.100000,0.100000},{0.012500,0.637500,0.200000,0.200000},{0.037500,0.637500,0.100000,0.100000},{0.037500,0.637500,0.200000,0.200000},{0.062500,0.637500,0.100000,0.100000},{0.062500,0.637500,0.200000,0.200000},{0.087500,0.637500,0.100000,0.100000},{0.087500,0.637500,0.200000,0.200000},{0.112500,0.637500,0.100000,0.100000},{0.112500,0.637500,0.200000,0.200000},{0.137500,0.637500,0.100000,0.100000},{0.137500,0.637500,0.200000,0.200000},{0.162500,0.637500,0.100000,0.100000},{0.162500,0.637500,0.200000,0.200000},{0.187500,0.637500,0.100000,0.100000},{0.187500,0.637500,0.200000,0.200000},{0.212500,0.637500,0.100000,0.100000},{0.212500,0.637500,0.200000,0.200000},{0.237500,0.637500,0.100000,0.100000},{0.237500,0.637500,0.200000,0.200000},{0.262500,0.637500,0.100000,0.100000},{0.262500,0.637500,0.200000,0.200000},{0.287500,0.637500,0.100000,0.100000},{0.287500,0.637500,0.200000,0.200000},{0.312500,0.637500,0.100000,0.100000},{0.312500,0.637500,0.200000,0.200000},{0.337500,0.637500,0.100000,0.100000},{0.337500,0.637500,0.200000,0.200000},{0.362500,0.637500,0.100000,0.100000},{0.362500,0.637500,0.200000,0.200000},{0.387500,0.637500,0.100000,0.100000},{0.387500,0.637500,0.200000,0.200000},{0.412500,0.637500,0.100000,0.100000},{0.412500,0.637500,0.200000,0.200000},{0.437500,0.637500,0.100000,0.100000},{0.437500,0.637500,0.200000,0.200000},{0.462500,0.637500,0.100000,0.100000},{0.462500,0.637500,0.200000,0.200000},{0.487500,0.637500,0.100000,0.100000},{0.487500,0.637500,0.200000,0.200000},{0.512500,0.637500,0.100000,0.100000},{0.512500,0.637500,0.200000,0.200000},{0.537500,0.637500,0.100000,0.100000},{0.537500,0.637500,0.200000,0.200000},{0.562500,0.637500,0.100000,0.100000},{0.562500,0.637500,0.200000,0.200000},{0.587500,0.637500,0.100000,0.100000},{0.587500,0.637500,0.200000,0.200000},{0.612500,0.637500,0.100000,0.100000},{0.612500,0.637500,0.200000,0.200000},{0.637500,0.637500,0.100000,0.100000},{0.637500,0.637500,0.200000,0.200000},{0.662500,0.637500,0.100000,0.100000},{0.662500,0.637500,0.200000,0.200000},{0.687500,0.637500,0.100000,0.100000},{0.687500,0.637500,0.200000,0.200000},{0.712500,0.637500,0.100000,0.100000},{0.712500,0.637500,0.200000,0.200000},{0.737500,0.637500,0.100000,0.100000},{0.737500,0.637500,0.200000,0.200000},{0.762500,0.637500,0.100000,0.100000},{0.762500,0.637500,0.200000,0.200000},{0.787500,0.637500,0.100000,0.100000},{0.787500,0.637500,0.200000,0.200000},{0.812500,0.637500,0.100000,0.100000},{0.812500,0.637500,0.200000,0.200000},{0.837500,0.637500,0.100000,0.100000},{0.837500,0.637500,0.200000,0.200000},{0.862500,0.637500,0.100000,0.100000},{0.862500,0.637500,0.200000,0.200000},{0.887500,0.637500,0.100000,0.100000},{0.887500,0.637500,0.200000,0.200000},{0.912500,0.637500,0.100000,0.100000},{0.912500,0.637500,0.200000,0.200000},{0.937500,0.637500,0.100000,0.100000},{0.937500,0.637500,0.200000,0.200000},{0.962500,0.637500,0.100000,0.100000},{0.962500,0.637500,0.200000,0.200000},{0.987500,0.637500,0.100000,0.100000},{0.987500,0.637500,0.200000,0.200000},{0.012500,0.662500,0.100000,0.100000},{0.012500,0.662500,0.200000,0.200000},{0.037500,0.662500,0.100000,0.100000},{0.037500,0.662500,0.200000,0.200000},{0.062500,0.662500,0.100000,0.100000},{0.062500,0.662500,0.200000,0.200000},{0.087500,0.662500,0.100000,0.100000},{0.087500,0.662500,0.200000,0.200000},{0.112500,0.662500,0.100000,0.100000},{0.112500,0.662500,0.200000,0.200000},{0.137500,0.662500,0.100000,0.100000},{0.137500,0.662500,0.200000,0.200000},{0.162500,0.662500,0.100000,0.100000},{0.162500,0.662500,0.200000,0.200000},{0.187500,0.662500,0.100000,0.100000},{0.187500,0.662500,0.200000,0.200000},{0.212500,0.662500,0.100000,0.100000},{0.212500,0.662500,0.200000,0.200000},{0.237500,0.662500,0.100000,0.100000},{0.237500,0.662500,0.200000,0.200000},{0.262500,0.662500,0.100000,0.100000},{0.262500,0.662500,0.200000,0.200000},{0.287500,0.662500,0.100000,0.100000},{0.287500,0.662500,0.200000,0.200000},{0.312500,0.662500,0.100000,0.100000},{0.312500,0.662500,0.200000,0.200000},{0.337500,0.662500,0.100000,0.100000},{0.337500,0.662500,0.200000,0.200000},{0.362500,0.662500,0.100000,0.100000},{0.362500,0.662500,0.200000,0.200000},{0.387500,0.662500,0.100000,0.100000},{0.387500,0.662500,0.200000,0.200000},{0.412500,0.662500,0.100000,0.100000},{0.412500,0.662500,0.200000,0.200000},{0.437500,0.662500,0.100000,0.100000},{0.437500,0.662500,0.200000,0.200000},{0.462500,0.662500,0.100000,0.100000},{0.462500,0.662500,0.200000,0.200000},{0.487500,0.662500,0.100000,0.100000},{0.487500,0.662500,0.200000,0.200000},{0.512500,0.662500,0.100000,0.100000},{0.512500,0.662500,0.200000,0.200000},{0.537500,0.662500,0.100000,0.100000},{0.537500,0.662500,0.200000,0.200000},{0.562500,0.662500,0.100000,0.100000},{0.562500,0.662500,0.200000,0.200000},{0.587500,0.662500,0.100000,0.100000},{0.587500,0.662500,0.200000,0.200000},{0.612500,0.662500,0.100000,0.100000},{0.612500,0.662500,0.200000,0.200000},{0.637500,0.662500,0.100000,0.100000},{0.637500,0.662500,0.200000,0.200000},{0.662500,0.662500,0.100000,0.100000},{0.662500,0.662500,0.200000,0.200000},{0.687500,0.662500,0.100000,0.100000},{0.687500,0.662500,0.200000,0.200000},{0.712500,0.662500,0.100000,0.100000},{0.712500,0.662500,0.200000,0.200000},{0.737500,0.662500,0.100000,0.100000},{0.737500,0.662500,0.200000,0.200000},{0.762500,0.662500,0.100000,0.100000},{0.762500,0.662500,0.200000,0.200000},{0.787500,0.662500,0.100000,0.100000},{0.787500,0.662500,0.200000,0.200000},{0.812500,0.662500,0.100000,0.100000},{0.812500,0.662500,0.200000,0.200000},{0.837500,0.662500,0.100000,0.100000},{0.837500,0.662500,0.200000,0.200000},{0.862500,0.662500,0.100000,0.100000},{0.862500,0.662500,0.200000,0.200000},{0.887500,0.662500,0.100000,0.100000},{0.887500,0.662500,0.200000,0.200000},{0.912500,0.662500,0.100000,0.100000},{0.912500,0.662500,0.200000,0.200000},{0.937500,0.662500,0.100000,0.100000},{0.937500,0.662500,0.200000,0.200000},{0.962500,0.662500,0.100000,0.100000},{0.962500,0.662500,0.200000,0.200000},{0.987500,0.662500,0.100000,0.100000},{0.987500,0.662500,0.200000,0.200000},{0.012500,0.687500,0.100000,0.100000},{0.012500,0.687500,0.200000,0.200000},{0.037500,0.687500,0.100000,0.100000},{0.037500,0.687500,0.200000,0.200000},{0.062500,0.687500,0.100000,0.100000},{0.062500,0.687500,0.200000,0.200000},{0.087500,0.687500,0.100000,0.100000},{0.087500,0.687500,0.200000,0.200000},{0.112500,0.687500,0.100000,0.100000},{0.112500,0.687500,0.200000,0.200000},{0.137500,0.687500,0.100000,0.100000},{0.137500,0.687500,0.200000,0.200000},{0.162500,0.687500,0.100000,0.100000},{0.162500,0.687500,0.200000,0.200000},{0.187500,0.687500,0.100000,0.100000},{0.187500,0.687500,0.200000,0.200000},{0.212500,0.687500,0.100000,0.100000},{0.212500,0.687500,0.200000,0.200000},{0.237500,0.687500,0.100000,0.100000},{0.237500,0.687500,0.200000,0.200000},{0.262500,0.687500,0.100000,0.100000},{0.262500,0.687500,0.200000,0.200000},{0.287500,0.687500,0.100000,0.100000},{0.287500,0.687500,0.200000,0.200000},{0.312500,0.687500,0.100000,0.100000},{0.312500,0.687500,0.200000,0.200000},{0.337500,0.687500,0.100000,0.100000},{0.337500,0.687500,0.200000,0.200000},{0.362500,0.687500,0.100000,0.100000},{0.362500,0.687500,0.200000,0.200000},{0.387500,0.687500,0.100000,0.100000},{0.387500,0.687500,0.200000,0.200000},{0.412500,0.687500,0.100000,0.100000},{0.412500,0.687500,0.200000,0.200000},{0.437500,0.687500,0.100000,0.100000},{0.437500,0.687500,0.200000,0.200000},{0.462500,0.687500,0.100000,0.100000},{0.462500,0.687500,0.200000,0.200000},{0.487500,0.687500,0.100000,0.100000},{0.487500,0.687500,0.200000,0.200000},{0.512500,0.687500,0.100000,0.100000},{0.512500,0.687500,0.200000,0.200000},{0.537500,0.687500,0.100000,0.100000},{0.537500,0.687500,0.200000,0.200000},{0.562500,0.687500,0.100000,0.100000},{0.562500,0.687500,0.200000,0.200000},{0.587500,0.687500,0.100000,0.100000},{0.587500,0.687500,0.200000,0.200000},{0.612500,0.687500,0.100000,0.100000},{0.612500,0.687500,0.200000,0.200000},{0.637500,0.687500,0.100000,0.100000},{0.637500,0.687500,0.200000,0.200000},{0.662500,0.687500,0.100000,0.100000},{0.662500,0.687500,0.200000,0.200000},{0.687500,0.687500,0.100000,0.100000},{0.687500,0.687500,0.200000,0.200000},{0.712500,0.687500,0.100000,0.100000},{0.712500,0.687500,0.200000,0.200000},{0.737500,0.687500,0.100000,0.100000},{0.737500,0.687500,0.200000,0.200000},{0.762500,0.687500,0.100000,0.100000},{0.762500,0.687500,0.200000,0.200000},{0.787500,0.687500,0.100000,0.100000},{0.787500,0.687500,0.200000,0.200000},{0.812500,0.687500,0.100000,0.100000},{0.812500,0.687500,0.200000,0.200000},{0.837500,0.687500,0.100000,0.100000},{0.837500,0.687500,0.200000,0.200000},{0.862500,0.687500,0.100000,0.100000},{0.862500,0.687500,0.200000,0.200000},{0.887500,0.687500,0.100000,0.100000},{0.887500,0.687500,0.200000,0.200000},{0.912500,0.687500,0.100000,0.100000},{0.912500,0.687500,0.200000,0.200000},{0.937500,0.687500,0.100000,0.100000},{0.937500,0.687500,0.200000,0.200000},{0.962500,0.687500,0.100000,0.100000},{0.962500,0.687500,0.200000,0.200000},{0.987500,0.687500,0.100000,0.100000},{0.987500,0.687500,0.200000,0.200000},{0.012500,0.712500,0.100000,0.100000},{0.012500,0.712500,0.200000,0.200000},{0.037500,0.712500,0.100000,0.100000},{0.037500,0.712500,0.200000,0.200000},{0.062500,0.712500,0.100000,0.100000},{0.062500,0.712500,0.200000,0.200000},{0.087500,0.712500,0.100000,0.100000},{0.087500,0.712500,0.200000,0.200000},{0.112500,0.712500,0.100000,0.100000},{0.112500,0.712500,0.200000,0.200000},{0.137500,0.712500,0.100000,0.100000},{0.137500,0.712500,0.200000,0.200000},{0.162500,0.712500,0.100000,0.100000},{0.162500,0.712500,0.200000,0.200000},{0.187500,0.712500,0.100000,0.100000},{0.187500,0.712500,0.200000,0.200000},{0.212500,0.712500,0.100000,0.100000},{0.212500,0.712500,0.200000,0.200000},{0.237500,0.712500,0.100000,0.100000},{0.237500,0.712500,0.200000,0.200000},{0.262500,0.712500,0.100000,0.100000},{0.262500,0.712500,0.200000,0.200000},{0.287500,0.712500,0.100000,0.100000},{0.287500,0.712500,0.200000,0.200000},{0.312500,0.712500,0.100000,0.100000},{0.312500,0.712500,0.200000,0.200000},{0.337500,0.712500,0.100000,0.100000},{0.337500,0.712500,0.200000,0.200000},{0.362500,0.712500,0.100000,0.100000},{0.362500,0.712500,0.200000,0.200000},{0.387500,0.712500,0.100000,0.100000},{0.387500,0.712500,0.200000,0.200000},{0.412500,0.712500,0.100000,0.100000},{0.412500,0.712500,0.200000,0.200000},{0.437500,0.712500,0.100000,0.100000},{0.437500,0.712500,0.200000,0.200000},{0.462500,0.712500,0.100000,0.100000},{0.462500,0.712500,0.200000,0.200000},{0.487500,0.712500,0.100000,0.100000},{0.487500,0.712500,0.200000,0.200000},{0.512500,0.712500,0.100000,0.100000},{0.512500,0.712500,0.200000,0.200000},{0.537500,0.712500,0.100000,0.100000},{0.537500,0.712500,0.200000,0.200000},{0.562500,0.712500,0.100000,0.100000},{0.562500,0.712500,0.200000,0.200000},{0.587500,0.712500,0.100000,0.100000},{0.587500,0.712500,0.200000,0.200000},{0.612500,0.712500,0.100000,0.100000},{0.612500,0.712500,0.200000,0.200000},{0.637500,0.712500,0.100000,0.100000},{0.637500,0.712500,0.200000,0.200000},{0.662500,0.712500,0.100000,0.100000},{0.662500,0.712500,0.200000,0.200000},{0.687500,0.712500,0.100000,0.100000},{0.687500,0.712500,0.200000,0.200000},{0.712500,0.712500,0.100000,0.100000},{0.712500,0.712500,0.200000,0.200000},{0.737500,0.712500,0.100000,0.100000},{0.737500,0.712500,0.200000,0.200000},{0.762500,0.712500,0.100000,0.100000},{0.762500,0.712500,0.200000,0.200000},{0.787500,0.712500,0.100000,0.100000},{0.787500,0.712500,0.200000,0.200000},{0.812500,0.712500,0.100000,0.100000},{0.812500,0.712500,0.200000,0.200000},{0.837500,0.712500,0.100000,0.100000},{0.837500,0.712500,0.200000,0.200000},{0.862500,0.712500,0.100000,0.100000},{0.862500,0.712500,0.200000,0.200000},{0.887500,0.712500,0.100000,0.100000},{0.887500,0.712500,0.200000,0.200000},{0.912500,0.712500,0.100000,0.100000},{0.912500,0.712500,0.200000,0.200000},{0.937500,0.712500,0.100000,0.100000},{0.937500,0.712500,0.200000,0.200000},{0.962500,0.712500,0.100000,0.100000},{0.962500,0.712500,0.200000,0.200000},{0.987500,0.712500,0.100000,0.100000},{0.987500,0.712500,0.200000,0.200000},{0.012500,0.737500,0.100000,0.100000},{0.012500,0.737500,0.200000,0.200000},{0.037500,0.737500,0.100000,0.100000},{0.037500,0.737500,0.200000,0.200000},{0.062500,0.737500,0.100000,0.100000},{0.062500,0.737500,0.200000,0.200000},{0.087500,0.737500,0.100000,0.100000},{0.087500,0.737500,0.200000,0.200000},{0.112500,0.737500,0.100000,0.100000},{0.112500,0.737500,0.200000,0.200000},{0.137500,0.737500,0.100000,0.100000},{0.137500,0.737500,0.200000,0.200000},{0.162500,0.737500,0.100000,0.100000},{0.162500,0.737500,0.200000,0.200000},{0.187500,0.737500,0.100000,0.100000},{0.187500,0.737500,0.200000,0.200000},{0.212500,0.737500,0.100000,0.100000},{0.212500,0.737500,0.200000,0.200000},{0.237500,0.737500,0.100000,0.100000},{0.237500,0.737500,0.200000,0.200000},{0.262500,0.737500,0.100000,0.100000},{0.262500,0.737500,0.200000,0.200000},{0.287500,0.737500,0.100000,0.100000},{0.287500,0.737500,0.200000,0.200000},{0.312500,0.737500,0.100000,0.100000},{0.312500,0.737500,0.200000,0.200000},{0.337500,0.737500,0.100000,0.100000},{0.337500,0.737500,0.200000,0.200000},{0.362500,0.737500,0.100000,0.100000},{0.362500,0.737500,0.200000,0.200000},{0.387500,0.737500,0.100000,0.100000},{0.387500,0.737500,0.200000,0.200000},{0.412500,0.737500,0.100000,0.100000},{0.412500,0.737500,0.200000,0.200000},{0.437500,0.737500,0.100000,0.100000},{0.437500,0.737500,0.200000,0.200000},{0.462500,0.737500,0.100000,0.100000},{0.462500,0.737500,0.200000,0.200000},{0.487500,0.737500,0.100000,0.100000},{0.487500,0.737500,0.200000,0.200000},{0.512500,0.737500,0.100000,0.100000},{0.512500,0.737500,0.200000,0.200000},{0.537500,0.737500,0.100000,0.100000},{0.537500,0.737500,0.200000,0.200000},{0.562500,0.737500,0.100000,0.100000},{0.562500,0.737500,0.200000,0.200000},{0.587500,0.737500,0.100000,0.100000},{0.587500,0.737500,0.200000,0.200000},{0.612500,0.737500,0.100000,0.100000},{0.612500,0.737500,0.200000,0.200000},{0.637500,0.737500,0.100000,0.100000},{0.637500,0.737500,0.200000,0.200000},{0.662500,0.737500,0.100000,0.100000},{0.662500,0.737500,0.200000,0.200000},{0.687500,0.737500,0.100000,0.100000},{0.687500,0.737500,0.200000,0.200000},{0.712500,0.737500,0.100000,0.100000},{0.712500,0.737500,0.200000,0.200000},{0.737500,0.737500,0.100000,0.100000},{0.737500,0.737500,0.200000,0.200000},{0.762500,0.737500,0.100000,0.100000},{0.762500,0.737500,0.200000,0.200000},{0.787500,0.737500,0.100000,0.100000},{0.787500,0.737500,0.200000,0.200000},{0.812500,0.737500,0.100000,0.100000},{0.812500,0.737500,0.200000,0.200000},{0.837500,0.737500,0.100000,0.100000},{0.837500,0.737500,0.200000,0.200000},{0.862500,0.737500,0.100000,0.100000},{0.862500,0.737500,0.200000,0.200000},{0.887500,0.737500,0.100000,0.100000},{0.887500,0.737500,0.200000,0.200000},{0.912500,0.737500,0.100000,0.100000},{0.912500,0.737500,0.200000,0.200000},{0.937500,0.737500,0.100000,0.100000},{0.937500,0.737500,0.200000,0.200000},{0.962500,0.737500,0.100000,0.100000},{0.962500,0.737500,0.200000,0.200000},{0.987500,0.737500,0.100000,0.100000},{0.987500,0.737500,0.200000,0.200000},{0.012500,0.762500,0.100000,0.100000},{0.012500,0.762500,0.200000,0.200000},{0.037500,0.762500,0.100000,0.100000},{0.037500,0.762500,0.200000,0.200000},{0.062500,0.762500,0.100000,0.100000},{0.062500,0.762500,0.200000,0.200000},{0.087500,0.762500,0.100000,0.100000},{0.087500,0.762500,0.200000,0.200000},{0.112500,0.762500,0.100000,0.100000},{0.112500,0.762500,0.200000,0.200000},{0.137500,0.762500,0.100000,0.100000},{0.137500,0.762500,0.200000,0.200000},{0.162500,0.762500,0.100000,0.100000},{0.162500,0.762500,0.200000,0.200000},{0.187500,0.762500,0.100000,0.100000},{0.187500,0.762500,0.200000,0.200000},{0.212500,0.762500,0.100000,0.100000},{0.212500,0.762500,0.200000,0.200000},{0.237500,0.762500,0.100000,0.100000},{0.237500,0.762500,0.200000,0.200000},{0.262500,0.762500,0.100000,0.100000},{0.262500,0.762500,0.200000,0.200000},{0.287500,0.762500,0.100000,0.100000},{0.287500,0.762500,0.200000,0.200000},{0.312500,0.762500,0.100000,0.100000},{0.312500,0.762500,0.200000,0.200000},{0.337500,0.762500,0.100000,0.100000},{0.337500,0.762500,0.200000,0.200000},{0.362500,0.762500,0.100000,0.100000},{0.362500,0.762500,0.200000,0.200000},{0.387500,0.762500,0.100000,0.100000},{0.387500,0.762500,0.200000,0.200000},{0.412500,0.762500,0.100000,0.100000},{0.412500,0.762500,0.200000,0.200000},{0.437500,0.762500,0.100000,0.100000},{0.437500,0.762500,0.200000,0.200000},{0.462500,0.762500,0.100000,0.100000},{0.462500,0.762500,0.200000,0.200000},{0.487500,0.762500,0.100000,0.100000},{0.487500,0.762500,0.200000,0.200000},{0.512500,0.762500,0.100000,0.100000},{0.512500,0.762500,0.200000,0.200000},{0.537500,0.762500,0.100000,0.100000},{0.537500,0.762500,0.200000,0.200000},{0.562500,0.762500,0.100000,0.100000},{0.562500,0.762500,0.200000,0.200000},{0.587500,0.762500,0.100000,0.100000},{0.587500,0.762500,0.200000,0.200000},{0.612500,0.762500,0.100000,0.100000},{0.612500,0.762500,0.200000,0.200000},{0.637500,0.762500,0.100000,0.100000},{0.637500,0.762500,0.200000,0.200000},{0.662500,0.762500,0.100000,0.100000},{0.662500,0.762500,0.200000,0.200000},{0.687500,0.762500,0.100000,0.100000},{0.687500,0.762500,0.200000,0.200000},{0.712500,0.762500,0.100000,0.100000},{0.712500,0.762500,0.200000,0.200000},{0.737500,0.762500,0.100000,0.100000},{0.737500,0.762500,0.200000,0.200000},{0.762500,0.762500,0.100000,0.100000},{0.762500,0.762500,0.200000,0.200000},{0.787500,0.762500,0.100000,0.100000},{0.787500,0.762500,0.200000,0.200000},{0.812500,0.762500,0.100000,0.100000},{0.812500,0.762500,0.200000,0.200000},{0.837500,0.762500,0.100000,0.100000},{0.837500,0.762500,0.200000,0.200000},{0.862500,0.762500,0.100000,0.100000},{0.862500,0.762500,0.200000,0.200000},{0.887500,0.762500,0.100000,0.100000},{0.887500,0.762500,0.200000,0.200000},{0.912500,0.762500,0.100000,0.100000},{0.912500,0.762500,0.200000,0.200000},{0.937500,0.762500,0.100000,0.100000},{0.937500,0.762500,0.200000,0.200000},{0.962500,0.762500,0.100000,0.100000},{0.962500,0.762500,0.200000,0.200000},{0.987500,0.762500,0.100000,0.100000},{0.987500,0.762500,0.200000,0.200000},{0.012500,0.787500,0.100000,0.100000},{0.012500,0.787500,0.200000,0.200000},{0.037500,0.787500,0.100000,0.100000},{0.037500,0.787500,0.200000,0.200000},{0.062500,0.787500,0.100000,0.100000},{0.062500,0.787500,0.200000,0.200000},{0.087500,0.787500,0.100000,0.100000},{0.087500,0.787500,0.200000,0.200000},{0.112500,0.787500,0.100000,0.100000},{0.112500,0.787500,0.200000,0.200000},{0.137500,0.787500,0.100000,0.100000},{0.137500,0.787500,0.200000,0.200000},{0.162500,0.787500,0.100000,0.100000},{0.162500,0.787500,0.200000,0.200000},{0.187500,0.787500,0.100000,0.100000},{0.187500,0.787500,0.200000,0.200000},{0.212500,0.787500,0.100000,0.100000},{0.212500,0.787500,0.200000,0.200000},{0.237500,0.787500,0.100000,0.100000},{0.237500,0.787500,0.200000,0.200000},{0.262500,0.787500,0.100000,0.100000},{0.262500,0.787500,0.200000,0.200000},{0.287500,0.787500,0.100000,0.100000},{0.287500,0.787500,0.200000,0.200000},{0.312500,0.787500,0.100000,0.100000},{0.312500,0.787500,0.200000,0.200000},{0.337500,0.787500,0.100000,0.100000},{0.337500,0.787500,0.200000,0.200000},{0.362500,0.787500,0.100000,0.100000},{0.362500,0.787500,0.200000,0.200000},{0.387500,0.787500,0.100000,0.100000},{0.387500,0.787500,0.200000,0.200000},{0.412500,0.787500,0.100000,0.100000},{0.412500,0.787500,0.200000,0.200000},{0.437500,0.787500,0.100000,0.100000},{0.437500,0.787500,0.200000,0.200000},{0.462500,0.787500,0.100000,0.100000},{0.462500,0.787500,0.200000,0.200000},{0.487500,0.787500,0.100000,0.100000},{0.487500,0.787500,0.200000,0.200000},{0.512500,0.787500,0.100000,0.100000},{0.512500,0.787500,0.200000,0.200000},{0.537500,0.787500,0.100000,0.100000},{0.537500,0.787500,0.200000,0.200000},{0.562500,0.787500,0.100000,0.100000},{0.562500,0.787500,0.200000,0.200000},{0.587500,0.787500,0.100000,0.100000},{0.587500,0.787500,0.200000,0.200000},{0.612500,0.787500,0.100000,0.100000},{0.612500,0.787500,0.200000,0.200000},{0.637500,0.787500,0.100000,0.100000},{0.637500,0.787500,0.200000,0.200000},{0.662500,0.787500,0.100000,0.100000},{0.662500,0.787500,0.200000,0.200000},{0.687500,0.787500,0.100000,0.100000},{0.687500,0.787500,0.200000,0.200000},{0.712500,0.787500,0.100000,0.100000},{0.712500,0.787500,0.200000,0.200000},{0.737500,0.787500,0.100000,0.100000},{0.737500,0.787500,0.200000,0.200000},{0.762500,0.787500,0.100000,0.100000},{0.762500,0.787500,0.200000,0.200000},{0.787500,0.787500,0.100000,0.100000},{0.787500,0.787500,0.200000,0.200000},{0.812500,0.787500,0.100000,0.100000},{0.812500,0.787500,0.200000,0.200000},{0.837500,0.787500,0.100000,0.100000},{0.837500,0.787500,0.200000,0.200000},{0.862500,0.787500,0.100000,0.100000},{0.862500,0.787500,0.200000,0.200000},{0.887500,0.787500,0.100000,0.100000},{0.887500,0.787500,0.200000,0.200000},{0.912500,0.787500,0.100000,0.100000},{0.912500,0.787500,0.200000,0.200000},{0.937500,0.787500,0.100000,0.100000},{0.937500,0.787500,0.200000,0.200000},{0.962500,0.787500,0.100000,0.100000},{0.962500,0.787500,0.200000,0.200000},{0.987500,0.787500,0.100000,0.100000},{0.987500,0.787500,0.200000,0.200000},{0.012500,0.812500,0.100000,0.100000},{0.012500,0.812500,0.200000,0.200000},{0.037500,0.812500,0.100000,0.100000},{0.037500,0.812500,0.200000,0.200000},{0.062500,0.812500,0.100000,0.100000},{0.062500,0.812500,0.200000,0.200000},{0.087500,0.812500,0.100000,0.100000},{0.087500,0.812500,0.200000,0.200000},{0.112500,0.812500,0.100000,0.100000},{0.112500,0.812500,0.200000,0.200000},{0.137500,0.812500,0.100000,0.100000},{0.137500,0.812500,0.200000,0.200000},{0.162500,0.812500,0.100000,0.100000},{0.162500,0.812500,0.200000,0.200000},{0.187500,0.812500,0.100000,0.100000},{0.187500,0.812500,0.200000,0.200000},{0.212500,0.812500,0.100000,0.100000},{0.212500,0.812500,0.200000,0.200000},{0.237500,0.812500,0.100000,0.100000},{0.237500,0.812500,0.200000,0.200000},{0.262500,0.812500,0.100000,0.100000},{0.262500,0.812500,0.200000,0.200000},{0.287500,0.812500,0.100000,0.100000},{0.287500,0.812500,0.200000,0.200000},{0.312500,0.812500,0.100000,0.100000},{0.312500,0.812500,0.200000,0.200000},{0.337500,0.812500,0.100000,0.100000},{0.337500,0.812500,0.200000,0.200000},{0.362500,0.812500,0.100000,0.100000},{0.362500,0.812500,0.200000,0.200000},{0.387500,0.812500,0.100000,0.100000},{0.387500,0.812500,0.200000,0.200000},{0.412500,0.812500,0.100000,0.100000},{0.412500,0.812500,0.200000,0.200000},{0.437500,0.812500,0.100000,0.100000},{0.437500,0.812500,0.200000,0.200000},{0.462500,0.812500,0.100000,0.100000},{0.462500,0.812500,0.200000,0.200000},{0.487500,0.812500,0.100000,0.100000},{0.487500,0.812500,0.200000,0.200000},{0.512500,0.812500,0.100000,0.100000},{0.512500,0.812500,0.200000,0.200000},{0.537500,0.812500,0.100000,0.100000},{0.537500,0.812500,0.200000,0.200000},{0.562500,0.812500,0.100000,0.100000},{0.562500,0.812500,0.200000,0.200000},{0.587500,0.812500,0.100000,0.100000},{0.587500,0.812500,0.200000,0.200000},{0.612500,0.812500,0.100000,0.100000},{0.612500,0.812500,0.200000,0.200000},{0.637500,0.812500,0.100000,0.100000},{0.637500,0.812500,0.200000,0.200000},{0.662500,0.812500,0.100000,0.100000},{0.662500,0.812500,0.200000,0.200000},{0.687500,0.812500,0.100000,0.100000},{0.687500,0.812500,0.200000,0.200000},{0.712500,0.812500,0.100000,0.100000},{0.712500,0.812500,0.200000,0.200000},{0.737500,0.812500,0.100000,0.100000},{0.737500,0.812500,0.200000,0.200000},{0.762500,0.812500,0.100000,0.100000},{0.762500,0.812500,0.200000,0.200000},{0.787500,0.812500,0.100000,0.100000},{0.787500,0.812500,0.200000,0.200000},{0.812500,0.812500,0.100000,0.100000},{0.812500,0.812500,0.200000,0.200000},{0.837500,0.812500,0.100000,0.100000},{0.837500,0.812500,0.200000,0.200000},{0.862500,0.812500,0.100000,0.100000},{0.862500,0.812500,0.200000,0.200000},{0.887500,0.812500,0.100000,0.100000},{0.887500,0.812500,0.200000,0.200000},{0.912500,0.812500,0.100000,0.100000},{0.912500,0.812500,0.200000,0.200000},{0.937500,0.812500,0.100000,0.100000},{0.937500,0.812500,0.200000,0.200000},{0.962500,0.812500,0.100000,0.100000},{0.962500,0.812500,0.200000,0.200000},{0.987500,0.812500,0.100000,0.100000},{0.987500,0.812500,0.200000,0.200000},{0.012500,0.837500,0.100000,0.100000},{0.012500,0.837500,0.200000,0.200000},{0.037500,0.837500,0.100000,0.100000},{0.037500,0.837500,0.200000,0.200000},{0.062500,0.837500,0.100000,0.100000},{0.062500,0.837500,0.200000,0.200000},{0.087500,0.837500,0.100000,0.100000},{0.087500,0.837500,0.200000,0.200000},{0.112500,0.837500,0.100000,0.100000},{0.112500,0.837500,0.200000,0.200000},{0.137500,0.837500,0.100000,0.100000},{0.137500,0.837500,0.200000,0.200000},{0.162500,0.837500,0.100000,0.100000},{0.162500,0.837500,0.200000,0.200000},{0.187500,0.837500,0.100000,0.100000},{0.187500,0.837500,0.200000,0.200000},{0.212500,0.837500,0.100000,0.100000},{0.212500,0.837500,0.200000,0.200000},{0.237500,0.837500,0.100000,0.100000},{0.237500,0.837500,0.200000,0.200000},{0.262500,0.837500,0.100000,0.100000},{0.262500,0.837500,0.200000,0.200000},{0.287500,0.837500,0.100000,0.100000},{0.287500,0.837500,0.200000,0.200000},{0.312500,0.837500,0.100000,0.100000},{0.312500,0.837500,0.200000,0.200000},{0.337500,0.837500,0.100000,0.100000},{0.337500,0.837500,0.200000,0.200000},{0.362500,0.837500,0.100000,0.100000},{0.362500,0.837500,0.200000,0.200000},{0.387500,0.837500,0.100000,0.100000},{0.387500,0.837500,0.200000,0.200000},{0.412500,0.837500,0.100000,0.100000},{0.412500,0.837500,0.200000,0.200000},{0.437500,0.837500,0.100000,0.100000},{0.437500,0.837500,0.200000,0.200000},{0.462500,0.837500,0.100000,0.100000},{0.462500,0.837500,0.200000,0.200000},{0.487500,0.837500,0.100000,0.100000},{0.487500,0.837500,0.200000,0.200000},{0.512500,0.837500,0.100000,0.100000},{0.512500,0.837500,0.200000,0.200000},{0.537500,0.837500,0.100000,0.100000},{0.537500,0.837500,0.200000,0.200000},{0.562500,0.837500,0.100000,0.100000},{0.562500,0.837500,0.200000,0.200000},{0.587500,0.837500,0.100000,0.100000},{0.587500,0.837500,0.200000,0.200000},{0.612500,0.837500,0.100000,0.100000},{0.612500,0.837500,0.200000,0.200000},{0.637500,0.837500,0.100000,0.100000},{0.637500,0.837500,0.200000,0.200000},{0.662500,0.837500,0.100000,0.100000},{0.662500,0.837500,0.200000,0.200000},{0.687500,0.837500,0.100000,0.100000},{0.687500,0.837500,0.200000,0.200000},{0.712500,0.837500,0.100000,0.100000},{0.712500,0.837500,0.200000,0.200000},{0.737500,0.837500,0.100000,0.100000},{0.737500,0.837500,0.200000,0.200000},{0.762500,0.837500,0.100000,0.100000},{0.762500,0.837500,0.200000,0.200000},{0.787500,0.837500,0.100000,0.100000},{0.787500,0.837500,0.200000,0.200000},{0.812500,0.837500,0.100000,0.100000},{0.812500,0.837500,0.200000,0.200000},{0.837500,0.837500,0.100000,0.100000},{0.837500,0.837500,0.200000,0.200000},{0.862500,0.837500,0.100000,0.100000},{0.862500,0.837500,0.200000,0.200000},{0.887500,0.837500,0.100000,0.100000},{0.887500,0.837500,0.200000,0.200000},{0.912500,0.837500,0.100000,0.100000},{0.912500,0.837500,0.200000,0.200000},{0.937500,0.837500,0.100000,0.100000},{0.937500,0.837500,0.200000,0.200000},{0.962500,0.837500,0.100000,0.100000},{0.962500,0.837500,0.200000,0.200000},{0.987500,0.837500,0.100000,0.100000},{0.987500,0.837500,0.200000,0.200000},{0.012500,0.862500,0.100000,0.100000},{0.012500,0.862500,0.200000,0.200000},{0.037500,0.862500,0.100000,0.100000},{0.037500,0.862500,0.200000,0.200000},{0.062500,0.862500,0.100000,0.100000},{0.062500,0.862500,0.200000,0.200000},{0.087500,0.862500,0.100000,0.100000},{0.087500,0.862500,0.200000,0.200000},{0.112500,0.862500,0.100000,0.100000},{0.112500,0.862500,0.200000,0.200000},{0.137500,0.862500,0.100000,0.100000},{0.137500,0.862500,0.200000,0.200000},{0.162500,0.862500,0.100000,0.100000},{0.162500,0.862500,0.200000,0.200000},{0.187500,0.862500,0.100000,0.100000},{0.187500,0.862500,0.200000,0.200000},{0.212500,0.862500,0.100000,0.100000},{0.212500,0.862500,0.200000,0.200000},{0.237500,0.862500,0.100000,0.100000},{0.237500,0.862500,0.200000,0.200000},{0.262500,0.862500,0.100000,0.100000},{0.262500,0.862500,0.200000,0.200000},{0.287500,0.862500,0.100000,0.100000},{0.287500,0.862500,0.200000,0.200000},{0.312500,0.862500,0.100000,0.100000},{0.312500,0.862500,0.200000,0.200000},{0.337500,0.862500,0.100000,0.100000},{0.337500,0.862500,0.200000,0.200000},{0.362500,0.862500,0.100000,0.100000},{0.362500,0.862500,0.200000,0.200000},{0.387500,0.862500,0.100000,0.100000},{0.387500,0.862500,0.200000,0.200000},{0.412500,0.862500,0.100000,0.100000},{0.412500,0.862500,0.200000,0.200000},{0.437500,0.862500,0.100000,0.100000},{0.437500,0.862500,0.200000,0.200000},{0.462500,0.862500,0.100000,0.100000},{0.462500,0.862500,0.200000,0.200000},{0.487500,0.862500,0.100000,0.100000},{0.487500,0.862500,0.200000,0.200000},{0.512500,0.862500,0.100000,0.100000},{0.512500,0.862500,0.200000,0.200000},{0.537500,0.862500,0.100000,0.100000},{0.537500,0.862500,0.200000,0.200000},{0.562500,0.862500,0.100000,0.100000},{0.562500,0.862500,0.200000,0.200000},{0.587500,0.862500,0.100000,0.100000},{0.587500,0.862500,0.200000,0.200000},{0.612500,0.862500,0.100000,0.100000},{0.612500,0.862500,0.200000,0.200000},{0.637500,0.862500,0.100000,0.100000},{0.637500,0.862500,0.200000,0.200000},{0.662500,0.862500,0.100000,0.100000},{0.662500,0.862500,0.200000,0.200000},{0.687500,0.862500,0.100000,0.100000},{0.687500,0.862500,0.200000,0.200000},{0.712500,0.862500,0.100000,0.100000},{0.712500,0.862500,0.200000,0.200000},{0.737500,0.862500,0.100000,0.100000},{0.737500,0.862500,0.200000,0.200000},{0.762500,0.862500,0.100000,0.100000},{0.762500,0.862500,0.200000,0.200000},{0.787500,0.862500,0.100000,0.100000},{0.787500,0.862500,0.200000,0.200000},{0.812500,0.862500,0.100000,0.100000},{0.812500,0.862500,0.200000,0.200000},{0.837500,0.862500,0.100000,0.100000},{0.837500,0.862500,0.200000,0.200000},{0.862500,0.862500,0.100000,0.100000},{0.862500,0.862500,0.200000,0.200000},{0.887500,0.862500,0.100000,0.100000},{0.887500,0.862500,0.200000,0.200000},{0.912500,0.862500,0.100000,0.100000},{0.912500,0.862500,0.200000,0.200000},{0.937500,0.862500,0.100000,0.100000},{0.937500,0.862500,0.200000,0.200000},{0.962500,0.862500,0.100000,0.100000},{0.962500,0.862500,0.200000,0.200000},{0.987500,0.862500,0.100000,0.100000},{0.987500,0.862500,0.200000,0.200000},{0.012500,0.887500,0.100000,0.100000},{0.012500,0.887500,0.200000,0.200000},{0.037500,0.887500,0.100000,0.100000},{0.037500,0.887500,0.200000,0.200000},{0.062500,0.887500,0.100000,0.100000},{0.062500,0.887500,0.200000,0.200000},{0.087500,0.887500,0.100000,0.100000},{0.087500,0.887500,0.200000,0.200000},{0.112500,0.887500,0.100000,0.100000},{0.112500,0.887500,0.200000,0.200000},{0.137500,0.887500,0.100000,0.100000},{0.137500,0.887500,0.200000,0.200000},{0.162500,0.887500,0.100000,0.100000},{0.162500,0.887500,0.200000,0.200000},{0.187500,0.887500,0.100000,0.100000},{0.187500,0.887500,0.200000,0.200000},{0.212500,0.887500,0.100000,0.100000},{0.212500,0.887500,0.200000,0.200000},{0.237500,0.887500,0.100000,0.100000},{0.237500,0.887500,0.200000,0.200000},{0.262500,0.887500,0.100000,0.100000},{0.262500,0.887500,0.200000,0.200000},{0.287500,0.887500,0.100000,0.100000},{0.287500,0.887500,0.200000,0.200000},{0.312500,0.887500,0.100000,0.100000},{0.312500,0.887500,0.200000,0.200000},{0.337500,0.887500,0.100000,0.100000},{0.337500,0.887500,0.200000,0.200000},{0.362500,0.887500,0.100000,0.100000},{0.362500,0.887500,0.200000,0.200000},{0.387500,0.887500,0.100000,0.100000},{0.387500,0.887500,0.200000,0.200000},{0.412500,0.887500,0.100000,0.100000},{0.412500,0.887500,0.200000,0.200000},{0.437500,0.887500,0.100000,0.100000},{0.437500,0.887500,0.200000,0.200000},{0.462500,0.887500,0.100000,0.100000},{0.462500,0.887500,0.200000,0.200000},{0.487500,0.887500,0.100000,0.100000},{0.487500,0.887500,0.200000,0.200000},{0.512500,0.887500,0.100000,0.100000},{0.512500,0.887500,0.200000,0.200000},{0.537500,0.887500,0.100000,0.100000},{0.537500,0.887500,0.200000,0.200000},{0.562500,0.887500,0.100000,0.100000},{0.562500,0.887500,0.200000,0.200000},{0.587500,0.887500,0.100000,0.100000},{0.587500,0.887500,0.200000,0.200000},{0.612500,0.887500,0.100000,0.100000},{0.612500,0.887500,0.200000,0.200000},{0.637500,0.887500,0.100000,0.100000},{0.637500,0.887500,0.200000,0.200000},{0.662500,0.887500,0.100000,0.100000},{0.662500,0.887500,0.200000,0.200000},{0.687500,0.887500,0.100000,0.100000},{0.687500,0.887500,0.200000,0.200000},{0.712500,0.887500,0.100000,0.100000},{0.712500,0.887500,0.200000,0.200000},{0.737500,0.887500,0.100000,0.100000},{0.737500,0.887500,0.200000,0.200000},{0.762500,0.887500,0.100000,0.100000},{0.762500,0.887500,0.200000,0.200000},{0.787500,0.887500,0.100000,0.100000},{0.787500,0.887500,0.200000,0.200000},{0.812500,0.887500,0.100000,0.100000},{0.812500,0.887500,0.200000,0.200000},{0.837500,0.887500,0.100000,0.100000},{0.837500,0.887500,0.200000,0.200000},{0.862500,0.887500,0.100000,0.100000},{0.862500,0.887500,0.200000,0.200000},{0.887500,0.887500,0.100000,0.100000},{0.887500,0.887500,0.200000,0.200000},{0.912500,0.887500,0.100000,0.100000},{0.912500,0.887500,0.200000,0.200000},{0.937500,0.887500,0.100000,0.100000},{0.937500,0.887500,0.200000,0.200000},{0.962500,0.887500,0.100000,0.100000},{0.962500,0.887500,0.200000,0.200000},{0.987500,0.887500,0.100000,0.100000},{0.987500,0.887500,0.200000,0.200000},{0.012500,0.912500,0.100000,0.100000},{0.012500,0.912500,0.200000,0.200000},{0.037500,0.912500,0.100000,0.100000},{0.037500,0.912500,0.200000,0.200000},{0.062500,0.912500,0.100000,0.100000},{0.062500,0.912500,0.200000,0.200000},{0.087500,0.912500,0.100000,0.100000},{0.087500,0.912500,0.200000,0.200000},{0.112500,0.912500,0.100000,0.100000},{0.112500,0.912500,0.200000,0.200000},{0.137500,0.912500,0.100000,0.100000},{0.137500,0.912500,0.200000,0.200000},{0.162500,0.912500,0.100000,0.100000},{0.162500,0.912500,0.200000,0.200000},{0.187500,0.912500,0.100000,0.100000},{0.187500,0.912500,0.200000,0.200000},{0.212500,0.912500,0.100000,0.100000},{0.212500,0.912500,0.200000,0.200000},{0.237500,0.912500,0.100000,0.100000},{0.237500,0.912500,0.200000,0.200000},{0.262500,0.912500,0.100000,0.100000},{0.262500,0.912500,0.200000,0.200000},{0.287500,0.912500,0.100000,0.100000},{0.287500,0.912500,0.200000,0.200000},{0.312500,0.912500,0.100000,0.100000},{0.312500,0.912500,0.200000,0.200000},{0.337500,0.912500,0.100000,0.100000},{0.337500,0.912500,0.200000,0.200000},{0.362500,0.912500,0.100000,0.100000},{0.362500,0.912500,0.200000,0.200000},{0.387500,0.912500,0.100000,0.100000},{0.387500,0.912500,0.200000,0.200000},{0.412500,0.912500,0.100000,0.100000},{0.412500,0.912500,0.200000,0.200000},{0.437500,0.912500,0.100000,0.100000},{0.437500,0.912500,0.200000,0.200000},{0.462500,0.912500,0.100000,0.100000},{0.462500,0.912500,0.200000,0.200000},{0.487500,0.912500,0.100000,0.100000},{0.487500,0.912500,0.200000,0.200000},{0.512500,0.912500,0.100000,0.100000},{0.512500,0.912500,0.200000,0.200000},{0.537500,0.912500,0.100000,0.100000},{0.537500,0.912500,0.200000,0.200000},{0.562500,0.912500,0.100000,0.100000},{0.562500,0.912500,0.200000,0.200000},{0.587500,0.912500,0.100000,0.100000},{0.587500,0.912500,0.200000,0.200000},{0.612500,0.912500,0.100000,0.100000},{0.612500,0.912500,0.200000,0.200000},{0.637500,0.912500,0.100000,0.100000},{0.637500,0.912500,0.200000,0.200000},{0.662500,0.912500,0.100000,0.100000},{0.662500,0.912500,0.200000,0.200000},{0.687500,0.912500,0.100000,0.100000},{0.687500,0.912500,0.200000,0.200000},{0.712500,0.912500,0.100000,0.100000},{0.712500,0.912500,0.200000,0.200000},{0.737500,0.912500,0.100000,0.100000},{0.737500,0.912500,0.200000,0.200000},{0.762500,0.912500,0.100000,0.100000},{0.762500,0.912500,0.200000,0.200000},{0.787500,0.912500,0.100000,0.100000},{0.787500,0.912500,0.200000,0.200000},{0.812500,0.912500,0.100000,0.100000},{0.812500,0.912500,0.200000,0.200000},{0.837500,0.912500,0.100000,0.100000},{0.837500,0.912500,0.200000,0.200000},{0.862500,0.912500,0.100000,0.100000},{0.862500,0.912500,0.200000,0.200000},{0.887500,0.912500,0.100000,0.100000},{0.887500,0.912500,0.200000,0.200000},{0.912500,0.912500,0.100000,0.100000},{0.912500,0.912500,0.200000,0.200000},{0.937500,0.912500,0.100000,0.100000},{0.937500,0.912500,0.200000,0.200000},{0.962500,0.912500,0.100000,0.100000},{0.962500,0.912500,0.200000,0.200000},{0.987500,0.912500,0.100000,0.100000},{0.987500,0.912500,0.200000,0.200000},{0.012500,0.937500,0.100000,0.100000},{0.012500,0.937500,0.200000,0.200000},{0.037500,0.937500,0.100000,0.100000},{0.037500,0.937500,0.200000,0.200000},{0.062500,0.937500,0.100000,0.100000},{0.062500,0.937500,0.200000,0.200000},{0.087500,0.937500,0.100000,0.100000},{0.087500,0.937500,0.200000,0.200000},{0.112500,0.937500,0.100000,0.100000},{0.112500,0.937500,0.200000,0.200000},{0.137500,0.937500,0.100000,0.100000},{0.137500,0.937500,0.200000,0.200000},{0.162500,0.937500,0.100000,0.100000},{0.162500,0.937500,0.200000,0.200000},{0.187500,0.937500,0.100000,0.100000},{0.187500,0.937500,0.200000,0.200000},{0.212500,0.937500,0.100000,0.100000},{0.212500,0.937500,0.200000,0.200000},{0.237500,0.937500,0.100000,0.100000},{0.237500,0.937500,0.200000,0.200000},{0.262500,0.937500,0.100000,0.100000},{0.262500,0.937500,0.200000,0.200000},{0.287500,0.937500,0.100000,0.100000},{0.287500,0.937500,0.200000,0.200000},{0.312500,0.937500,0.100000,0.100000},{0.312500,0.937500,0.200000,0.200000},{0.337500,0.937500,0.100000,0.100000},{0.337500,0.937500,0.200000,0.200000},{0.362500,0.937500,0.100000,0.100000},{0.362500,0.937500,0.200000,0.200000},{0.387500,0.937500,0.100000,0.100000},{0.387500,0.937500,0.200000,0.200000},{0.412500,0.937500,0.100000,0.100000},{0.412500,0.937500,0.200000,0.200000},{0.437500,0.937500,0.100000,0.100000},{0.437500,0.937500,0.200000,0.200000},{0.462500,0.937500,0.100000,0.100000},{0.462500,0.937500,0.200000,0.200000},{0.487500,0.937500,0.100000,0.100000},{0.487500,0.937500,0.200000,0.200000},{0.512500,0.937500,0.100000,0.100000},{0.512500,0.937500,0.200000,0.200000},{0.537500,0.937500,0.100000,0.100000},{0.537500,0.937500,0.200000,0.200000},{0.562500,0.937500,0.100000,0.100000},{0.562500,0.937500,0.200000,0.200000},{0.587500,0.937500,0.100000,0.100000},{0.587500,0.937500,0.200000,0.200000},{0.612500,0.937500,0.100000,0.100000},{0.612500,0.937500,0.200000,0.200000},{0.637500,0.937500,0.100000,0.100000},{0.637500,0.937500,0.200000,0.200000},{0.662500,0.937500,0.100000,0.100000},{0.662500,0.937500,0.200000,0.200000},{0.687500,0.937500,0.100000,0.100000},{0.687500,0.937500,0.200000,0.200000},{0.712500,0.937500,0.100000,0.100000},{0.712500,0.937500,0.200000,0.200000},{0.737500,0.937500,0.100000,0.100000},{0.737500,0.937500,0.200000,0.200000},{0.762500,0.937500,0.100000,0.100000},{0.762500,0.937500,0.200000,0.200000},{0.787500,0.937500,0.100000,0.100000},{0.787500,0.937500,0.200000,0.200000},{0.812500,0.937500,0.100000,0.100000},{0.812500,0.937500,0.200000,0.200000},{0.837500,0.937500,0.100000,0.100000},{0.837500,0.937500,0.200000,0.200000},{0.862500,0.937500,0.100000,0.100000},{0.862500,0.937500,0.200000,0.200000},{0.887500,0.937500,0.100000,0.100000},{0.887500,0.937500,0.200000,0.200000},{0.912500,0.937500,0.100000,0.100000},{0.912500,0.937500,0.200000,0.200000},{0.937500,0.937500,0.100000,0.100000},{0.937500,0.937500,0.200000,0.200000},{0.962500,0.937500,0.100000,0.100000},{0.962500,0.937500,0.200000,0.200000},{0.987500,0.937500,0.100000,0.100000},{0.987500,0.937500,0.200000,0.200000},{0.012500,0.962500,0.100000,0.100000},{0.012500,0.962500,0.200000,0.200000},{0.037500,0.962500,0.100000,0.100000},{0.037500,0.962500,0.200000,0.200000},{0.062500,0.962500,0.100000,0.100000},{0.062500,0.962500,0.200000,0.200000},{0.087500,0.962500,0.100000,0.100000},{0.087500,0.962500,0.200000,0.200000},{0.112500,0.962500,0.100000,0.100000},{0.112500,0.962500,0.200000,0.200000},{0.137500,0.962500,0.100000,0.100000},{0.137500,0.962500,0.200000,0.200000},{0.162500,0.962500,0.100000,0.100000},{0.162500,0.962500,0.200000,0.200000},{0.187500,0.962500,0.100000,0.100000},{0.187500,0.962500,0.200000,0.200000},{0.212500,0.962500,0.100000,0.100000},{0.212500,0.962500,0.200000,0.200000},{0.237500,0.962500,0.100000,0.100000},{0.237500,0.962500,0.200000,0.200000},{0.262500,0.962500,0.100000,0.100000},{0.262500,0.962500,0.200000,0.200000},{0.287500,0.962500,0.100000,0.100000},{0.287500,0.962500,0.200000,0.200000},{0.312500,0.962500,0.100000,0.100000},{0.312500,0.962500,0.200000,0.200000},{0.337500,0.962500,0.100000,0.100000},{0.337500,0.962500,0.200000,0.200000},{0.362500,0.962500,0.100000,0.100000},{0.362500,0.962500,0.200000,0.200000},{0.387500,0.962500,0.100000,0.100000},{0.387500,0.962500,0.200000,0.200000},{0.412500,0.962500,0.100000,0.100000},{0.412500,0.962500,0.200000,0.200000},{0.437500,0.962500,0.100000,0.100000},{0.437500,0.962500,0.200000,0.200000},{0.462500,0.962500,0.100000,0.100000},{0.462500,0.962500,0.200000,0.200000},{0.487500,0.962500,0.100000,0.100000},{0.487500,0.962500,0.200000,0.200000},{0.512500,0.962500,0.100000,0.100000},{0.512500,0.962500,0.200000,0.200000},{0.537500,0.962500,0.100000,0.100000},{0.537500,0.962500,0.200000,0.200000},{0.562500,0.962500,0.100000,0.100000},{0.562500,0.962500,0.200000,0.200000},{0.587500,0.962500,0.100000,0.100000},{0.587500,0.962500,0.200000,0.200000},{0.612500,0.962500,0.100000,0.100000},{0.612500,0.962500,0.200000,0.200000},{0.637500,0.962500,0.100000,0.100000},{0.637500,0.962500,0.200000,0.200000},{0.662500,0.962500,0.100000,0.100000},{0.662500,0.962500,0.200000,0.200000},{0.687500,0.962500,0.100000,0.100000},{0.687500,0.962500,0.200000,0.200000},{0.712500,0.962500,0.100000,0.100000},{0.712500,0.962500,0.200000,0.200000},{0.737500,0.962500,0.100000,0.100000},{0.737500,0.962500,0.200000,0.200000},{0.762500,0.962500,0.100000,0.100000},{0.762500,0.962500,0.200000,0.200000},{0.787500,0.962500,0.100000,0.100000},{0.787500,0.962500,0.200000,0.200000},{0.812500,0.962500,0.100000,0.100000},{0.812500,0.962500,0.200000,0.200000},{0.837500,0.962500,0.100000,0.100000},{0.837500,0.962500,0.200000,0.200000},{0.862500,0.962500,0.100000,0.100000},{0.862500,0.962500,0.200000,0.200000},{0.887500,0.962500,0.100000,0.100000},{0.887500,0.962500,0.200000,0.200000},{0.912500,0.962500,0.100000,0.100000},{0.912500,0.962500,0.200000,0.200000},{0.937500,0.962500,0.100000,0.100000},{0.937500,0.962500,0.200000,0.200000},{0.962500,0.962500,0.100000,0.100000},{0.962500,0.962500,0.200000,0.200000},{0.987500,0.962500,0.100000,0.100000},{0.987500,0.962500,0.200000,0.200000},{0.012500,0.987500,0.100000,0.100000},{0.012500,0.987500,0.200000,0.200000},{0.037500,0.987500,0.100000,0.100000},{0.037500,0.987500,0.200000,0.200000},{0.062500,0.987500,0.100000,0.100000},{0.062500,0.987500,0.200000,0.200000},{0.087500,0.987500,0.100000,0.100000},{0.087500,0.987500,0.200000,0.200000},{0.112500,0.987500,0.100000,0.100000},{0.112500,0.987500,0.200000,0.200000},{0.137500,0.987500,0.100000,0.100000},{0.137500,0.987500,0.200000,0.200000},{0.162500,0.987500,0.100000,0.100000},{0.162500,0.987500,0.200000,0.200000},{0.187500,0.987500,0.100000,0.100000},{0.187500,0.987500,0.200000,0.200000},{0.212500,0.987500,0.100000,0.100000},{0.212500,0.987500,0.200000,0.200000},{0.237500,0.987500,0.100000,0.100000},{0.237500,0.987500,0.200000,0.200000},{0.262500,0.987500,0.100000,0.100000},{0.262500,0.987500,0.200000,0.200000},{0.287500,0.987500,0.100000,0.100000},{0.287500,0.987500,0.200000,0.200000},{0.312500,0.987500,0.100000,0.100000},{0.312500,0.987500,0.200000,0.200000},{0.337500,0.987500,0.100000,0.100000},{0.337500,0.987500,0.200000,0.200000},{0.362500,0.987500,0.100000,0.100000},{0.362500,0.987500,0.200000,0.200000},{0.387500,0.987500,0.100000,0.100000},{0.387500,0.987500,0.200000,0.200000},{0.412500,0.987500,0.100000,0.100000},{0.412500,0.987500,0.200000,0.200000},{0.437500,0.987500,0.100000,0.100000},{0.437500,0.987500,0.200000,0.200000},{0.462500,0.987500,0.100000,0.100000},{0.462500,0.987500,0.200000,0.200000},{0.487500,0.987500,0.100000,0.100000},{0.487500,0.987500,0.200000,0.200000},{0.512500,0.987500,0.100000,0.100000},{0.512500,0.987500,0.200000,0.200000},{0.537500,0.987500,0.100000,0.100000},{0.537500,0.987500,0.200000,0.200000},{0.562500,0.987500,0.100000,0.100000},{0.562500,0.987500,0.200000,0.200000},{0.587500,0.987500,0.100000,0.100000},{0.587500,0.987500,0.200000,0.200000},{0.612500,0.987500,0.100000,0.100000},{0.612500,0.987500,0.200000,0.200000},{0.637500,0.987500,0.100000,0.100000},{0.637500,0.987500,0.200000,0.200000},{0.662500,0.987500,0.100000,0.100000},{0.662500,0.987500,0.200000,0.200000},{0.687500,0.987500,0.100000,0.100000},{0.687500,0.987500,0.200000,0.200000},{0.712500,0.987500,0.100000,0.100000},{0.712500,0.987500,0.200000,0.200000},{0.737500,0.987500,0.100000,0.100000},{0.737500,0.987500,0.200000,0.200000},{0.762500,0.987500,0.100000,0.100000},{0.762500,0.987500,0.200000,0.200000},{0.787500,0.987500,0.100000,0.100000},{0.787500,0.987500,0.200000,0.200000},{0.812500,0.987500,0.100000,0.100000},{0.812500,0.987500,0.200000,0.200000},{0.837500,0.987500,0.100000,0.100000},{0.837500,0.987500,0.200000,0.200000},{0.862500,0.987500,0.100000,0.100000},{0.862500,0.987500,0.200000,0.200000},{0.887500,0.987500,0.100000,0.100000},{0.887500,0.987500,0.200000,0.200000},{0.912500,0.987500,0.100000,0.100000},{0.912500,0.987500,0.200000,0.200000},{0.937500,0.987500,0.100000,0.100000},{0.937500,0.987500,0.200000,0.200000},{0.962500,0.987500,0.100000,0.100000},{0.962500,0.987500,0.200000,0.200000},{0.987500,0.987500,0.100000,0.100000},{0.987500,0.987500,0.200000,0.200000},{0.025000,0.025000,0.400000,0.400000},{0.025000,0.025000,0.800000,0.800000},{0.075000,0.025000,0.400000,0.400000},{0.075000,0.025000,0.800000,0.800000},{0.125000,0.025000,0.400000,0.400000},{0.125000,0.025000,0.800000,0.800000},{0.175000,0.025000,0.400000,0.400000},{0.175000,0.025000,0.800000,0.800000},{0.225000,0.025000,0.400000,0.400000},{0.225000,0.025000,0.800000,0.800000},{0.275000,0.025000,0.400000,0.400000},{0.275000,0.025000,0.800000,0.800000},{0.325000,0.025000,0.400000,0.400000},{0.325000,0.025000,0.800000,0.800000},{0.375000,0.025000,0.400000,0.400000},{0.375000,0.025000,0.800000,0.800000},{0.425000,0.025000,0.400000,0.400000},{0.425000,0.025000,0.800000,0.800000},{0.475000,0.025000,0.400000,0.400000},{0.475000,0.025000,0.800000,0.800000},{0.525000,0.025000,0.400000,0.400000},{0.525000,0.025000,0.800000,0.800000},{0.575000,0.025000,0.400000,0.400000},{0.575000,0.025000,0.800000,0.800000},{0.625000,0.025000,0.400000,0.400000},{0.625000,0.025000,0.800000,0.800000},{0.675000,0.025000,0.400000,0.400000},{0.675000,0.025000,0.800000,0.800000},{0.725000,0.025000,0.400000,0.400000},{0.725000,0.025000,0.800000,0.800000},{0.775000,0.025000,0.400000,0.400000},{0.775000,0.025000,0.800000,0.800000},{0.825000,0.025000,0.400000,0.400000},{0.825000,0.025000,0.800000,0.800000},{0.875000,0.025000,0.400000,0.400000},{0.875000,0.025000,0.800000,0.800000},{0.925000,0.025000,0.400000,0.400000},{0.925000,0.025000,0.800000,0.800000},{0.975000,0.025000,0.400000,0.400000},{0.975000,0.025000,0.800000,0.800000},{0.025000,0.075000,0.400000,0.400000},{0.025000,0.075000,0.800000,0.800000},{0.075000,0.075000,0.400000,0.400000},{0.075000,0.075000,0.800000,0.800000},{0.125000,0.075000,0.400000,0.400000},{0.125000,0.075000,0.800000,0.800000},{0.175000,0.075000,0.400000,0.400000},{0.175000,0.075000,0.800000,0.800000},{0.225000,0.075000,0.400000,0.400000},{0.225000,0.075000,0.800000,0.800000},{0.275000,0.075000,0.400000,0.400000},{0.275000,0.075000,0.800000,0.800000},{0.325000,0.075000,0.400000,0.400000},{0.325000,0.075000,0.800000,0.800000},{0.375000,0.075000,0.400000,0.400000},{0.375000,0.075000,0.800000,0.800000},{0.425000,0.075000,0.400000,0.400000},{0.425000,0.075000,0.800000,0.800000},{0.475000,0.075000,0.400000,0.400000},{0.475000,0.075000,0.800000,0.800000},{0.525000,0.075000,0.400000,0.400000},{0.525000,0.075000,0.800000,0.800000},{0.575000,0.075000,0.400000,0.400000},{0.575000,0.075000,0.800000,0.800000},{0.625000,0.075000,0.400000,0.400000},{0.625000,0.075000,0.800000,0.800000},{0.675000,0.075000,0.400000,0.400000},{0.675000,0.075000,0.800000,0.800000},{0.725000,0.075000,0.400000,0.400000},{0.725000,0.075000,0.800000,0.800000},{0.775000,0.075000,0.400000,0.400000},{0.775000,0.075000,0.800000,0.800000},{0.825000,0.075000,0.400000,0.400000},{0.825000,0.075000,0.800000,0.800000},{0.875000,0.075000,0.400000,0.400000},{0.875000,0.075000,0.800000,0.800000},{0.925000,0.075000,0.400000,0.400000},{0.925000,0.075000,0.800000,0.800000},{0.975000,0.075000,0.400000,0.400000},{0.975000,0.075000,0.800000,0.800000},{0.025000,0.125000,0.400000,0.400000},{0.025000,0.125000,0.800000,0.800000},{0.075000,0.125000,0.400000,0.400000},{0.075000,0.125000,0.800000,0.800000},{0.125000,0.125000,0.400000,0.400000},{0.125000,0.125000,0.800000,0.800000},{0.175000,0.125000,0.400000,0.400000},{0.175000,0.125000,0.800000,0.800000},{0.225000,0.125000,0.400000,0.400000},{0.225000,0.125000,0.800000,0.800000},{0.275000,0.125000,0.400000,0.400000},{0.275000,0.125000,0.800000,0.800000},{0.325000,0.125000,0.400000,0.400000},{0.325000,0.125000,0.800000,0.800000},{0.375000,0.125000,0.400000,0.400000},{0.375000,0.125000,0.800000,0.800000},{0.425000,0.125000,0.400000,0.400000},{0.425000,0.125000,0.800000,0.800000},{0.475000,0.125000,0.400000,0.400000},{0.475000,0.125000,0.800000,0.800000},{0.525000,0.125000,0.400000,0.400000},{0.525000,0.125000,0.800000,0.800000},{0.575000,0.125000,0.400000,0.400000},{0.575000,0.125000,0.800000,0.800000},{0.625000,0.125000,0.400000,0.400000},{0.625000,0.125000,0.800000,0.800000},{0.675000,0.125000,0.400000,0.400000},{0.675000,0.125000,0.800000,0.800000},{0.725000,0.125000,0.400000,0.400000},{0.725000,0.125000,0.800000,0.800000},{0.775000,0.125000,0.400000,0.400000},{0.775000,0.125000,0.800000,0.800000},{0.825000,0.125000,0.400000,0.400000},{0.825000,0.125000,0.800000,0.800000},{0.875000,0.125000,0.400000,0.400000},{0.875000,0.125000,0.800000,0.800000},{0.925000,0.125000,0.400000,0.400000},{0.925000,0.125000,0.800000,0.800000},{0.975000,0.125000,0.400000,0.400000},{0.975000,0.125000,0.800000,0.800000},{0.025000,0.175000,0.400000,0.400000},{0.025000,0.175000,0.800000,0.800000},{0.075000,0.175000,0.400000,0.400000},{0.075000,0.175000,0.800000,0.800000},{0.125000,0.175000,0.400000,0.400000},{0.125000,0.175000,0.800000,0.800000},{0.175000,0.175000,0.400000,0.400000},{0.175000,0.175000,0.800000,0.800000},{0.225000,0.175000,0.400000,0.400000},{0.225000,0.175000,0.800000,0.800000},{0.275000,0.175000,0.400000,0.400000},{0.275000,0.175000,0.800000,0.800000},{0.325000,0.175000,0.400000,0.400000},{0.325000,0.175000,0.800000,0.800000},{0.375000,0.175000,0.400000,0.400000},{0.375000,0.175000,0.800000,0.800000},{0.425000,0.175000,0.400000,0.400000},{0.425000,0.175000,0.800000,0.800000},{0.475000,0.175000,0.400000,0.400000},{0.475000,0.175000,0.800000,0.800000},{0.525000,0.175000,0.400000,0.400000},{0.525000,0.175000,0.800000,0.800000},{0.575000,0.175000,0.400000,0.400000},{0.575000,0.175000,0.800000,0.800000},{0.625000,0.175000,0.400000,0.400000},{0.625000,0.175000,0.800000,0.800000},{0.675000,0.175000,0.400000,0.400000},{0.675000,0.175000,0.800000,0.800000},{0.725000,0.175000,0.400000,0.400000},{0.725000,0.175000,0.800000,0.800000},{0.775000,0.175000,0.400000,0.400000},{0.775000,0.175000,0.800000,0.800000},{0.825000,0.175000,0.400000,0.400000},{0.825000,0.175000,0.800000,0.800000},{0.875000,0.175000,0.400000,0.400000},{0.875000,0.175000,0.800000,0.800000},{0.925000,0.175000,0.400000,0.400000},{0.925000,0.175000,0.800000,0.800000},{0.975000,0.175000,0.400000,0.400000},{0.975000,0.175000,0.800000,0.800000},{0.025000,0.225000,0.400000,0.400000},{0.025000,0.225000,0.800000,0.800000},{0.075000,0.225000,0.400000,0.400000},{0.075000,0.225000,0.800000,0.800000},{0.125000,0.225000,0.400000,0.400000},{0.125000,0.225000,0.800000,0.800000},{0.175000,0.225000,0.400000,0.400000},{0.175000,0.225000,0.800000,0.800000},{0.225000,0.225000,0.400000,0.400000},{0.225000,0.225000,0.800000,0.800000},{0.275000,0.225000,0.400000,0.400000},{0.275000,0.225000,0.800000,0.800000},{0.325000,0.225000,0.400000,0.400000},{0.325000,0.225000,0.800000,0.800000},{0.375000,0.225000,0.400000,0.400000},{0.375000,0.225000,0.800000,0.800000},{0.425000,0.225000,0.400000,0.400000},{0.425000,0.225000,0.800000,0.800000},{0.475000,0.225000,0.400000,0.400000},{0.475000,0.225000,0.800000,0.800000},{0.525000,0.225000,0.400000,0.400000},{0.525000,0.225000,0.800000,0.800000},{0.575000,0.225000,0.400000,0.400000},{0.575000,0.225000,0.800000,0.800000},{0.625000,0.225000,0.400000,0.400000},{0.625000,0.225000,0.800000,0.800000},{0.675000,0.225000,0.400000,0.400000},{0.675000,0.225000,0.800000,0.800000},{0.725000,0.225000,0.400000,0.400000},{0.725000,0.225000,0.800000,0.800000},{0.775000,0.225000,0.400000,0.400000},{0.775000,0.225000,0.800000,0.800000},{0.825000,0.225000,0.400000,0.400000},{0.825000,0.225000,0.800000,0.800000},{0.875000,0.225000,0.400000,0.400000},{0.875000,0.225000,0.800000,0.800000},{0.925000,0.225000,0.400000,0.400000},{0.925000,0.225000,0.800000,0.800000},{0.975000,0.225000,0.400000,0.400000},{0.975000,0.225000,0.800000,0.800000},{0.025000,0.275000,0.400000,0.400000},{0.025000,0.275000,0.800000,0.800000},{0.075000,0.275000,0.400000,0.400000},{0.075000,0.275000,0.800000,0.800000},{0.125000,0.275000,0.400000,0.400000},{0.125000,0.275000,0.800000,0.800000},{0.175000,0.275000,0.400000,0.400000},{0.175000,0.275000,0.800000,0.800000},{0.225000,0.275000,0.400000,0.400000},{0.225000,0.275000,0.800000,0.800000},{0.275000,0.275000,0.400000,0.400000},{0.275000,0.275000,0.800000,0.800000},{0.325000,0.275000,0.400000,0.400000},{0.325000,0.275000,0.800000,0.800000},{0.375000,0.275000,0.400000,0.400000},{0.375000,0.275000,0.800000,0.800000},{0.425000,0.275000,0.400000,0.400000},{0.425000,0.275000,0.800000,0.800000},{0.475000,0.275000,0.400000,0.400000},{0.475000,0.275000,0.800000,0.800000},{0.525000,0.275000,0.400000,0.400000},{0.525000,0.275000,0.800000,0.800000},{0.575000,0.275000,0.400000,0.400000},{0.575000,0.275000,0.800000,0.800000},{0.625000,0.275000,0.400000,0.400000},{0.625000,0.275000,0.800000,0.800000},{0.675000,0.275000,0.400000,0.400000},{0.675000,0.275000,0.800000,0.800000},{0.725000,0.275000,0.400000,0.400000},{0.725000,0.275000,0.800000,0.800000},{0.775000,0.275000,0.400000,0.400000},{0.775000,0.275000,0.800000,0.800000},{0.825000,0.275000,0.400000,0.400000},{0.825000,0.275000,0.800000,0.800000},{0.875000,0.275000,0.400000,0.400000},{0.875000,0.275000,0.800000,0.800000},{0.925000,0.275000,0.400000,0.400000},{0.925000,0.275000,0.800000,0.800000},{0.975000,0.275000,0.400000,0.400000},{0.975000,0.275000,0.800000,0.800000},{0.025000,0.325000,0.400000,0.400000},{0.025000,0.325000,0.800000,0.800000},{0.075000,0.325000,0.400000,0.400000},{0.075000,0.325000,0.800000,0.800000},{0.125000,0.325000,0.400000,0.400000},{0.125000,0.325000,0.800000,0.800000},{0.175000,0.325000,0.400000,0.400000},{0.175000,0.325000,0.800000,0.800000},{0.225000,0.325000,0.400000,0.400000},{0.225000,0.325000,0.800000,0.800000},{0.275000,0.325000,0.400000,0.400000},{0.275000,0.325000,0.800000,0.800000},{0.325000,0.325000,0.400000,0.400000},{0.325000,0.325000,0.800000,0.800000},{0.375000,0.325000,0.400000,0.400000},{0.375000,0.325000,0.800000,0.800000},{0.425000,0.325000,0.400000,0.400000},{0.425000,0.325000,0.800000,0.800000},{0.475000,0.325000,0.400000,0.400000},{0.475000,0.325000,0.800000,0.800000},{0.525000,0.325000,0.400000,0.400000},{0.525000,0.325000,0.800000,0.800000},{0.575000,0.325000,0.400000,0.400000},{0.575000,0.325000,0.800000,0.800000},{0.625000,0.325000,0.400000,0.400000},{0.625000,0.325000,0.800000,0.800000},{0.675000,0.325000,0.400000,0.400000},{0.675000,0.325000,0.800000,0.800000},{0.725000,0.325000,0.400000,0.400000},{0.725000,0.325000,0.800000,0.800000},{0.775000,0.325000,0.400000,0.400000},{0.775000,0.325000,0.800000,0.800000},{0.825000,0.325000,0.400000,0.400000},{0.825000,0.325000,0.800000,0.800000},{0.875000,0.325000,0.400000,0.400000},{0.875000,0.325000,0.800000,0.800000},{0.925000,0.325000,0.400000,0.400000},{0.925000,0.325000,0.800000,0.800000},{0.975000,0.325000,0.400000,0.400000},{0.975000,0.325000,0.800000,0.800000},{0.025000,0.375000,0.400000,0.400000},{0.025000,0.375000,0.800000,0.800000},{0.075000,0.375000,0.400000,0.400000},{0.075000,0.375000,0.800000,0.800000},{0.125000,0.375000,0.400000,0.400000},{0.125000,0.375000,0.800000,0.800000},{0.175000,0.375000,0.400000,0.400000},{0.175000,0.375000,0.800000,0.800000},{0.225000,0.375000,0.400000,0.400000},{0.225000,0.375000,0.800000,0.800000},{0.275000,0.375000,0.400000,0.400000},{0.275000,0.375000,0.800000,0.800000},{0.325000,0.375000,0.400000,0.400000},{0.325000,0.375000,0.800000,0.800000},{0.375000,0.375000,0.400000,0.400000},{0.375000,0.375000,0.800000,0.800000},{0.425000,0.375000,0.400000,0.400000},{0.425000,0.375000,0.800000,0.800000},{0.475000,0.375000,0.400000,0.400000},{0.475000,0.375000,0.800000,0.800000},{0.525000,0.375000,0.400000,0.400000},{0.525000,0.375000,0.800000,0.800000},{0.575000,0.375000,0.400000,0.400000},{0.575000,0.375000,0.800000,0.800000},{0.625000,0.375000,0.400000,0.400000},{0.625000,0.375000,0.800000,0.800000},{0.675000,0.375000,0.400000,0.400000},{0.675000,0.375000,0.800000,0.800000},{0.725000,0.375000,0.400000,0.400000},{0.725000,0.375000,0.800000,0.800000},{0.775000,0.375000,0.400000,0.400000},{0.775000,0.375000,0.800000,0.800000},{0.825000,0.375000,0.400000,0.400000},{0.825000,0.375000,0.800000,0.800000},{0.875000,0.375000,0.400000,0.400000},{0.875000,0.375000,0.800000,0.800000},{0.925000,0.375000,0.400000,0.400000},{0.925000,0.375000,0.800000,0.800000},{0.975000,0.375000,0.400000,0.400000},{0.975000,0.375000,0.800000,0.800000},{0.025000,0.425000,0.400000,0.400000},{0.025000,0.425000,0.800000,0.800000},{0.075000,0.425000,0.400000,0.400000},{0.075000,0.425000,0.800000,0.800000},{0.125000,0.425000,0.400000,0.400000},{0.125000,0.425000,0.800000,0.800000},{0.175000,0.425000,0.400000,0.400000},{0.175000,0.425000,0.800000,0.800000},{0.225000,0.425000,0.400000,0.400000},{0.225000,0.425000,0.800000,0.800000},{0.275000,0.425000,0.400000,0.400000},{0.275000,0.425000,0.800000,0.800000},{0.325000,0.425000,0.400000,0.400000},{0.325000,0.425000,0.800000,0.800000},{0.375000,0.425000,0.400000,0.400000},{0.375000,0.425000,0.800000,0.800000},{0.425000,0.425000,0.400000,0.400000},{0.425000,0.425000,0.800000,0.800000},{0.475000,0.425000,0.400000,0.400000},{0.475000,0.425000,0.800000,0.800000},{0.525000,0.425000,0.400000,0.400000},{0.525000,0.425000,0.800000,0.800000},{0.575000,0.425000,0.400000,0.400000},{0.575000,0.425000,0.800000,0.800000},{0.625000,0.425000,0.400000,0.400000},{0.625000,0.425000,0.800000,0.800000},{0.675000,0.425000,0.400000,0.400000},{0.675000,0.425000,0.800000,0.800000},{0.725000,0.425000,0.400000,0.400000},{0.725000,0.425000,0.800000,0.800000},{0.775000,0.425000,0.400000,0.400000},{0.775000,0.425000,0.800000,0.800000},{0.825000,0.425000,0.400000,0.400000},{0.825000,0.425000,0.800000,0.800000},{0.875000,0.425000,0.400000,0.400000},{0.875000,0.425000,0.800000,0.800000},{0.925000,0.425000,0.400000,0.400000},{0.925000,0.425000,0.800000,0.800000},{0.975000,0.425000,0.400000,0.400000},{0.975000,0.425000,0.800000,0.800000},{0.025000,0.475000,0.400000,0.400000},{0.025000,0.475000,0.800000,0.800000},{0.075000,0.475000,0.400000,0.400000},{0.075000,0.475000,0.800000,0.800000},{0.125000,0.475000,0.400000,0.400000},{0.125000,0.475000,0.800000,0.800000},{0.175000,0.475000,0.400000,0.400000},{0.175000,0.475000,0.800000,0.800000},{0.225000,0.475000,0.400000,0.400000},{0.225000,0.475000,0.800000,0.800000},{0.275000,0.475000,0.400000,0.400000},{0.275000,0.475000,0.800000,0.800000},{0.325000,0.475000,0.400000,0.400000},{0.325000,0.475000,0.800000,0.800000},{0.375000,0.475000,0.400000,0.400000},{0.375000,0.475000,0.800000,0.800000},{0.425000,0.475000,0.400000,0.400000},{0.425000,0.475000,0.800000,0.800000},{0.475000,0.475000,0.400000,0.400000},{0.475000,0.475000,0.800000,0.800000},{0.525000,0.475000,0.400000,0.400000},{0.525000,0.475000,0.800000,0.800000},{0.575000,0.475000,0.400000,0.400000},{0.575000,0.475000,0.800000,0.800000},{0.625000,0.475000,0.400000,0.400000},{0.625000,0.475000,0.800000,0.800000},{0.675000,0.475000,0.400000,0.400000},{0.675000,0.475000,0.800000,0.800000},{0.725000,0.475000,0.400000,0.400000},{0.725000,0.475000,0.800000,0.800000},{0.775000,0.475000,0.400000,0.400000},{0.775000,0.475000,0.800000,0.800000},{0.825000,0.475000,0.400000,0.400000},{0.825000,0.475000,0.800000,0.800000},{0.875000,0.475000,0.400000,0.400000},{0.875000,0.475000,0.800000,0.800000},{0.925000,0.475000,0.400000,0.400000},{0.925000,0.475000,0.800000,0.800000},{0.975000,0.475000,0.400000,0.400000},{0.975000,0.475000,0.800000,0.800000},{0.025000,0.525000,0.400000,0.400000},{0.025000,0.525000,0.800000,0.800000},{0.075000,0.525000,0.400000,0.400000},{0.075000,0.525000,0.800000,0.800000},{0.125000,0.525000,0.400000,0.400000},{0.125000,0.525000,0.800000,0.800000},{0.175000,0.525000,0.400000,0.400000},{0.175000,0.525000,0.800000,0.800000},{0.225000,0.525000,0.400000,0.400000},{0.225000,0.525000,0.800000,0.800000},{0.275000,0.525000,0.400000,0.400000},{0.275000,0.525000,0.800000,0.800000},{0.325000,0.525000,0.400000,0.400000},{0.325000,0.525000,0.800000,0.800000},{0.375000,0.525000,0.400000,0.400000},{0.375000,0.525000,0.800000,0.800000},{0.425000,0.525000,0.400000,0.400000},{0.425000,0.525000,0.800000,0.800000},{0.475000,0.525000,0.400000,0.400000},{0.475000,0.525000,0.800000,0.800000},{0.525000,0.525000,0.400000,0.400000},{0.525000,0.525000,0.800000,0.800000},{0.575000,0.525000,0.400000,0.400000},{0.575000,0.525000,0.800000,0.800000},{0.625000,0.525000,0.400000,0.400000},{0.625000,0.525000,0.800000,0.800000},{0.675000,0.525000,0.400000,0.400000},{0.675000,0.525000,0.800000,0.800000},{0.725000,0.525000,0.400000,0.400000},{0.725000,0.525000,0.800000,0.800000},{0.775000,0.525000,0.400000,0.400000},{0.775000,0.525000,0.800000,0.800000},{0.825000,0.525000,0.400000,0.400000},{0.825000,0.525000,0.800000,0.800000},{0.875000,0.525000,0.400000,0.400000},{0.875000,0.525000,0.800000,0.800000},{0.925000,0.525000,0.400000,0.400000},{0.925000,0.525000,0.800000,0.800000},{0.975000,0.525000,0.400000,0.400000},{0.975000,0.525000,0.800000,0.800000},{0.025000,0.575000,0.400000,0.400000},{0.025000,0.575000,0.800000,0.800000},{0.075000,0.575000,0.400000,0.400000},{0.075000,0.575000,0.800000,0.800000},{0.125000,0.575000,0.400000,0.400000},{0.125000,0.575000,0.800000,0.800000},{0.175000,0.575000,0.400000,0.400000},{0.175000,0.575000,0.800000,0.800000},{0.225000,0.575000,0.400000,0.400000},{0.225000,0.575000,0.800000,0.800000},{0.275000,0.575000,0.400000,0.400000},{0.275000,0.575000,0.800000,0.800000},{0.325000,0.575000,0.400000,0.400000},{0.325000,0.575000,0.800000,0.800000},{0.375000,0.575000,0.400000,0.400000},{0.375000,0.575000,0.800000,0.800000},{0.425000,0.575000,0.400000,0.400000},{0.425000,0.575000,0.800000,0.800000},{0.475000,0.575000,0.400000,0.400000},{0.475000,0.575000,0.800000,0.800000},{0.525000,0.575000,0.400000,0.400000},{0.525000,0.575000,0.800000,0.800000},{0.575000,0.575000,0.400000,0.400000},{0.575000,0.575000,0.800000,0.800000},{0.625000,0.575000,0.400000,0.400000},{0.625000,0.575000,0.800000,0.800000},{0.675000,0.575000,0.400000,0.400000},{0.675000,0.575000,0.800000,0.800000},{0.725000,0.575000,0.400000,0.400000},{0.725000,0.575000,0.800000,0.800000},{0.775000,0.575000,0.400000,0.400000},{0.775000,0.575000,0.800000,0.800000},{0.825000,0.575000,0.400000,0.400000},{0.825000,0.575000,0.800000,0.800000},{0.875000,0.575000,0.400000,0.400000},{0.875000,0.575000,0.800000,0.800000},{0.925000,0.575000,0.400000,0.400000},{0.925000,0.575000,0.800000,0.800000},{0.975000,0.575000,0.400000,0.400000},{0.975000,0.575000,0.800000,0.800000},{0.025000,0.625000,0.400000,0.400000},{0.025000,0.625000,0.800000,0.800000},{0.075000,0.625000,0.400000,0.400000},{0.075000,0.625000,0.800000,0.800000},{0.125000,0.625000,0.400000,0.400000},{0.125000,0.625000,0.800000,0.800000},{0.175000,0.625000,0.400000,0.400000},{0.175000,0.625000,0.800000,0.800000},{0.225000,0.625000,0.400000,0.400000},{0.225000,0.625000,0.800000,0.800000},{0.275000,0.625000,0.400000,0.400000},{0.275000,0.625000,0.800000,0.800000},{0.325000,0.625000,0.400000,0.400000},{0.325000,0.625000,0.800000,0.800000},{0.375000,0.625000,0.400000,0.400000},{0.375000,0.625000,0.800000,0.800000},{0.425000,0.625000,0.400000,0.400000},{0.425000,0.625000,0.800000,0.800000},{0.475000,0.625000,0.400000,0.400000},{0.475000,0.625000,0.800000,0.800000},{0.525000,0.625000,0.400000,0.400000},{0.525000,0.625000,0.800000,0.800000},{0.575000,0.625000,0.400000,0.400000},{0.575000,0.625000,0.800000,0.800000},{0.625000,0.625000,0.400000,0.400000},{0.625000,0.625000,0.800000,0.800000},{0.675000,0.625000,0.400000,0.400000},{0.675000,0.625000,0.800000,0.800000},{0.725000,0.625000,0.400000,0.400000},{0.725000,0.625000,0.800000,0.800000},{0.775000,0.625000,0.400000,0.400000},{0.775000,0.625000,0.800000,0.800000},{0.825000,0.625000,0.400000,0.400000},{0.825000,0.625000,0.800000,0.800000},{0.875000,0.625000,0.400000,0.400000},{0.875000,0.625000,0.800000,0.800000},{0.925000,0.625000,0.400000,0.400000},{0.925000,0.625000,0.800000,0.800000},{0.975000,0.625000,0.400000,0.400000},{0.975000,0.625000,0.800000,0.800000},{0.025000,0.675000,0.400000,0.400000},{0.025000,0.675000,0.800000,0.800000},{0.075000,0.675000,0.400000,0.400000},{0.075000,0.675000,0.800000,0.800000},{0.125000,0.675000,0.400000,0.400000},{0.125000,0.675000,0.800000,0.800000},{0.175000,0.675000,0.400000,0.400000},{0.175000,0.675000,0.800000,0.800000},{0.225000,0.675000,0.400000,0.400000},{0.225000,0.675000,0.800000,0.800000},{0.275000,0.675000,0.400000,0.400000},{0.275000,0.675000,0.800000,0.800000},{0.325000,0.675000,0.400000,0.400000},{0.325000,0.675000,0.800000,0.800000},{0.375000,0.675000,0.400000,0.400000},{0.375000,0.675000,0.800000,0.800000},{0.425000,0.675000,0.400000,0.400000},{0.425000,0.675000,0.800000,0.800000},{0.475000,0.675000,0.400000,0.400000},{0.475000,0.675000,0.800000,0.800000},{0.525000,0.675000,0.400000,0.400000},{0.525000,0.675000,0.800000,0.800000},{0.575000,0.675000,0.400000,0.400000},{0.575000,0.675000,0.800000,0.800000},{0.625000,0.675000,0.400000,0.400000},{0.625000,0.675000,0.800000,0.800000},{0.675000,0.675000,0.400000,0.400000},{0.675000,0.675000,0.800000,0.800000},{0.725000,0.675000,0.400000,0.400000},{0.725000,0.675000,0.800000,0.800000},{0.775000,0.675000,0.400000,0.400000},{0.775000,0.675000,0.800000,0.800000},{0.825000,0.675000,0.400000,0.400000},{0.825000,0.675000,0.800000,0.800000},{0.875000,0.675000,0.400000,0.400000},{0.875000,0.675000,0.800000,0.800000},{0.925000,0.675000,0.400000,0.400000},{0.925000,0.675000,0.800000,0.800000},{0.975000,0.675000,0.400000,0.400000},{0.975000,0.675000,0.800000,0.800000},{0.025000,0.725000,0.400000,0.400000},{0.025000,0.725000,0.800000,0.800000},{0.075000,0.725000,0.400000,0.400000},{0.075000,0.725000,0.800000,0.800000},{0.125000,0.725000,0.400000,0.400000},{0.125000,0.725000,0.800000,0.800000},{0.175000,0.725000,0.400000,0.400000},{0.175000,0.725000,0.800000,0.800000},{0.225000,0.725000,0.400000,0.400000},{0.225000,0.725000,0.800000,0.800000},{0.275000,0.725000,0.400000,0.400000},{0.275000,0.725000,0.800000,0.800000},{0.325000,0.725000,0.400000,0.400000},{0.325000,0.725000,0.800000,0.800000},{0.375000,0.725000,0.400000,0.400000},{0.375000,0.725000,0.800000,0.800000},{0.425000,0.725000,0.400000,0.400000},{0.425000,0.725000,0.800000,0.800000},{0.475000,0.725000,0.400000,0.400000},{0.475000,0.725000,0.800000,0.800000},{0.525000,0.725000,0.400000,0.400000},{0.525000,0.725000,0.800000,0.800000},{0.575000,0.725000,0.400000,0.400000},{0.575000,0.725000,0.800000,0.800000},{0.625000,0.725000,0.400000,0.400000},{0.625000,0.725000,0.800000,0.800000},{0.675000,0.725000,0.400000,0.400000},{0.675000,0.725000,0.800000,0.800000},{0.725000,0.725000,0.400000,0.400000},{0.725000,0.725000,0.800000,0.800000},{0.775000,0.725000,0.400000,0.400000},{0.775000,0.725000,0.800000,0.800000},{0.825000,0.725000,0.400000,0.400000},{0.825000,0.725000,0.800000,0.800000},{0.875000,0.725000,0.400000,0.400000},{0.875000,0.725000,0.800000,0.800000},{0.925000,0.725000,0.400000,0.400000},{0.925000,0.725000,0.800000,0.800000},{0.975000,0.725000,0.400000,0.400000},{0.975000,0.725000,0.800000,0.800000},{0.025000,0.775000,0.400000,0.400000},{0.025000,0.775000,0.800000,0.800000},{0.075000,0.775000,0.400000,0.400000},{0.075000,0.775000,0.800000,0.800000},{0.125000,0.775000,0.400000,0.400000},{0.125000,0.775000,0.800000,0.800000},{0.175000,0.775000,0.400000,0.400000},{0.175000,0.775000,0.800000,0.800000},{0.225000,0.775000,0.400000,0.400000},{0.225000,0.775000,0.800000,0.800000},{0.275000,0.775000,0.400000,0.400000},{0.275000,0.775000,0.800000,0.800000},{0.325000,0.775000,0.400000,0.400000},{0.325000,0.775000,0.800000,0.800000},{0.375000,0.775000,0.400000,0.400000},{0.375000,0.775000,0.800000,0.800000},{0.425000,0.775000,0.400000,0.400000},{0.425000,0.775000,0.800000,0.800000},{0.475000,0.775000,0.400000,0.400000},{0.475000,0.775000,0.800000,0.800000},{0.525000,0.775000,0.400000,0.400000},{0.525000,0.775000,0.800000,0.800000},{0.575000,0.775000,0.400000,0.400000},{0.575000,0.775000,0.800000,0.800000},{0.625000,0.775000,0.400000,0.400000},{0.625000,0.775000,0.800000,0.800000},{0.675000,0.775000,0.400000,0.400000},{0.675000,0.775000,0.800000,0.800000},{0.725000,0.775000,0.400000,0.400000},{0.725000,0.775000,0.800000,0.800000},{0.775000,0.775000,0.400000,0.400000},{0.775000,0.775000,0.800000,0.800000},{0.825000,0.775000,0.400000,0.400000},{0.825000,0.775000,0.800000,0.800000},{0.875000,0.775000,0.400000,0.400000},{0.875000,0.775000,0.800000,0.800000},{0.925000,0.775000,0.400000,0.400000},{0.925000,0.775000,0.800000,0.800000},{0.975000,0.775000,0.400000,0.400000},{0.975000,0.775000,0.800000,0.800000},{0.025000,0.825000,0.400000,0.400000},{0.025000,0.825000,0.800000,0.800000},{0.075000,0.825000,0.400000,0.400000},{0.075000,0.825000,0.800000,0.800000},{0.125000,0.825000,0.400000,0.400000},{0.125000,0.825000,0.800000,0.800000},{0.175000,0.825000,0.400000,0.400000},{0.175000,0.825000,0.800000,0.800000},{0.225000,0.825000,0.400000,0.400000},{0.225000,0.825000,0.800000,0.800000},{0.275000,0.825000,0.400000,0.400000},{0.275000,0.825000,0.800000,0.800000},{0.325000,0.825000,0.400000,0.400000},{0.325000,0.825000,0.800000,0.800000},{0.375000,0.825000,0.400000,0.400000},{0.375000,0.825000,0.800000,0.800000},{0.425000,0.825000,0.400000,0.400000},{0.425000,0.825000,0.800000,0.800000},{0.475000,0.825000,0.400000,0.400000},{0.475000,0.825000,0.800000,0.800000},{0.525000,0.825000,0.400000,0.400000},{0.525000,0.825000,0.800000,0.800000},{0.575000,0.825000,0.400000,0.400000},{0.575000,0.825000,0.800000,0.800000},{0.625000,0.825000,0.400000,0.400000},{0.625000,0.825000,0.800000,0.800000},{0.675000,0.825000,0.400000,0.400000},{0.675000,0.825000,0.800000,0.800000},{0.725000,0.825000,0.400000,0.400000},{0.725000,0.825000,0.800000,0.800000},{0.775000,0.825000,0.400000,0.400000},{0.775000,0.825000,0.800000,0.800000},{0.825000,0.825000,0.400000,0.400000},{0.825000,0.825000,0.800000,0.800000},{0.875000,0.825000,0.400000,0.400000},{0.875000,0.825000,0.800000,0.800000},{0.925000,0.825000,0.400000,0.400000},{0.925000,0.825000,0.800000,0.800000},{0.975000,0.825000,0.400000,0.400000},{0.975000,0.825000,0.800000,0.800000},{0.025000,0.875000,0.400000,0.400000},{0.025000,0.875000,0.800000,0.800000},{0.075000,0.875000,0.400000,0.400000},{0.075000,0.875000,0.800000,0.800000},{0.125000,0.875000,0.400000,0.400000},{0.125000,0.875000,0.800000,0.800000},{0.175000,0.875000,0.400000,0.400000},{0.175000,0.875000,0.800000,0.800000},{0.225000,0.875000,0.400000,0.400000},{0.225000,0.875000,0.800000,0.800000},{0.275000,0.875000,0.400000,0.400000},{0.275000,0.875000,0.800000,0.800000},{0.325000,0.875000,0.400000,0.400000},{0.325000,0.875000,0.800000,0.800000},{0.375000,0.875000,0.400000,0.400000},{0.375000,0.875000,0.800000,0.800000},{0.425000,0.875000,0.400000,0.400000},{0.425000,0.875000,0.800000,0.800000},{0.475000,0.875000,0.400000,0.400000},{0.475000,0.875000,0.800000,0.800000},{0.525000,0.875000,0.400000,0.400000},{0.525000,0.875000,0.800000,0.800000},{0.575000,0.875000,0.400000,0.400000},{0.575000,0.875000,0.800000,0.800000},{0.625000,0.875000,0.400000,0.400000},{0.625000,0.875000,0.800000,0.800000},{0.675000,0.875000,0.400000,0.400000},{0.675000,0.875000,0.800000,0.800000},{0.725000,0.875000,0.400000,0.400000},{0.725000,0.875000,0.800000,0.800000},{0.775000,0.875000,0.400000,0.400000},{0.775000,0.875000,0.800000,0.800000},{0.825000,0.875000,0.400000,0.400000},{0.825000,0.875000,0.800000,0.800000},{0.875000,0.875000,0.400000,0.400000},{0.875000,0.875000,0.800000,0.800000},{0.925000,0.875000,0.400000,0.400000},{0.925000,0.875000,0.800000,0.800000},{0.975000,0.875000,0.400000,0.400000},{0.975000,0.875000,0.800000,0.800000},{0.025000,0.925000,0.400000,0.400000},{0.025000,0.925000,0.800000,0.800000},{0.075000,0.925000,0.400000,0.400000},{0.075000,0.925000,0.800000,0.800000},{0.125000,0.925000,0.400000,0.400000},{0.125000,0.925000,0.800000,0.800000},{0.175000,0.925000,0.400000,0.400000},{0.175000,0.925000,0.800000,0.800000},{0.225000,0.925000,0.400000,0.400000},{0.225000,0.925000,0.800000,0.800000},{0.275000,0.925000,0.400000,0.400000},{0.275000,0.925000,0.800000,0.800000},{0.325000,0.925000,0.400000,0.400000},{0.325000,0.925000,0.800000,0.800000},{0.375000,0.925000,0.400000,0.400000},{0.375000,0.925000,0.800000,0.800000},{0.425000,0.925000,0.400000,0.400000},{0.425000,0.925000,0.800000,0.800000},{0.475000,0.925000,0.400000,0.400000},{0.475000,0.925000,0.800000,0.800000},{0.525000,0.925000,0.400000,0.400000},{0.525000,0.925000,0.800000,0.800000},{0.575000,0.925000,0.400000,0.400000},{0.575000,0.925000,0.800000,0.800000},{0.625000,0.925000,0.400000,0.400000},{0.625000,0.925000,0.800000,0.800000},{0.675000,0.925000,0.400000,0.400000},{0.675000,0.925000,0.800000,0.800000},{0.725000,0.925000,0.400000,0.400000},{0.725000,0.925000,0.800000,0.800000},{0.775000,0.925000,0.400000,0.400000},{0.775000,0.925000,0.800000,0.800000},{0.825000,0.925000,0.400000,0.400000},{0.825000,0.925000,0.800000,0.800000},{0.875000,0.925000,0.400000,0.400000},{0.875000,0.925000,0.800000,0.800000},{0.925000,0.925000,0.400000,0.400000},{0.925000,0.925000,0.800000,0.800000},{0.975000,0.925000,0.400000,0.400000},{0.975000,0.925000,0.800000,0.800000},{0.025000,0.975000,0.400000,0.400000},{0.025000,0.975000,0.800000,0.800000},{0.075000,0.975000,0.400000,0.400000},{0.075000,0.975000,0.800000,0.800000},{0.125000,0.975000,0.400000,0.400000},{0.125000,0.975000,0.800000,0.800000},{0.175000,0.975000,0.400000,0.400000},{0.175000,0.975000,0.800000,0.800000},{0.225000,0.975000,0.400000,0.400000},{0.225000,0.975000,0.800000,0.800000},{0.275000,0.975000,0.400000,0.400000},{0.275000,0.975000,0.800000,0.800000},{0.325000,0.975000,0.400000,0.400000},{0.325000,0.975000,0.800000,0.800000},{0.375000,0.975000,0.400000,0.400000},{0.375000,0.975000,0.800000,0.800000},{0.425000,0.975000,0.400000,0.400000},{0.425000,0.975000,0.800000,0.800000},{0.475000,0.975000,0.400000,0.400000},{0.475000,0.975000,0.800000,0.800000},{0.525000,0.975000,0.400000,0.400000},{0.525000,0.975000,0.800000,0.800000},{0.575000,0.975000,0.400000,0.400000},{0.575000,0.975000,0.800000,0.800000},{0.625000,0.975000,0.400000,0.400000},{0.625000,0.975000,0.800000,0.800000},{0.675000,0.975000,0.400000,0.400000},{0.675000,0.975000,0.800000,0.800000},{0.725000,0.975000,0.400000,0.400000},{0.725000,0.975000,0.800000,0.800000},{0.775000,0.975000,0.400000,0.400000},{0.775000,0.975000,0.800000,0.800000},{0.825000,0.975000,0.400000,0.400000},{0.825000,0.975000,0.800000,0.800000},{0.875000,0.975000,0.400000,0.400000},{0.875000,0.975000,0.800000,0.800000},{0.925000,0.975000,0.400000,0.400000},{0.925000,0.975000,0.800000,0.800000},{0.975000,0.975000,0.400000,0.400000},{0.975000,0.975000,0.800000,0.800000}}; \ No newline at end of file diff --git a/src/reference/ai_poc/face_alignment/constant.h b/src/reference/ai_poc/face_alignment/constant.h new file mode 100644 index 000000000..f78720ce2 --- /dev/null +++ b/src/reference/ai_poc/face_alignment/constant.h @@ -0,0 +1,32 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _CONSTANT_H +#define _CONSTANT_H + +//params normalization config +const float param_mean[62]={0.0003492636315058917,2.52790130161884e-07,-6.875197868794203e-07,60.1679573059082,-6.295513230725192e-07,0.0005757200415246189,-5.085391239845194e-05,74.2781982421875,5.400917189035681e-07,6.574138387804851e-05,0.0003442012530285865,-66.67157745361328,-346603.6875,-67468.234375,46822.265625,-15262.046875,4350.5888671875,-54261.453125,-18328.033203125,-1584.328857421875,-84566.34375,3835.960693359375,-20811.361328125,38094.9296875,-19967.85546875,-9241.3701171875,-19600.71484375,13168.08984375,-5259.14404296875,1848.6478271484375,-13030.662109375,-2435.55615234375,-2254.20654296875,-14396.5615234375,-6176.3291015625,-25621.919921875,226.39447021484375,-6326.12353515625,-10867.2509765625,868.465087890625,-5831.14794921875,2705.123779296875,-3629.417724609375,2043.9901123046875,-2446.6162109375,3658.697021484375,-7645.98974609375,-6674.45263671875,116.38838958740234,7185.59716796875,-1429.48681640625,2617.366455078125,-1.2070955038070679,0.6690792441368103,-0.17760828137397766,0.056725528091192245,0.03967815637588501,-0.13586315512657166,-0.09223993122577667,-0.1726071834564209,-0.015804484486579895,-0.1416848599910736}; +const float param_std[62]={0.00017632152594160289,6.737943476764485e-05,0.00044708489440381527,26.55023193359375,0.0001231376954820007,4.493021697271615e-05,7.923670636955649e-05,6.982563018798828,0.0004350444069132209,0.00012314890045672655,0.00017400001524947584,20.80303955078125,575421.125,277649.0625,258336.84375,255163.125,150994.375,160086.109375,111277.3046875,97311.78125,117198.453125,89317.3671875,88493.5546875,72229.9296875,71080.2109375,50013.953125,55968.58203125,47525.50390625,49515.06640625,38161.48046875,44872.05859375,46273.23828125,38116.76953125,28191.162109375,32191.4375,36006.171875,32559.892578125,25551.1171875,24267.509765625,27521.3984375,23166.53125,21101.576171875,19412.32421875,19452.203125,17454.984375,22537.623046875,16174.28125,14671.640625,15115.6884765625,13870.0732421875,13746.3125,12663.1337890625,1.5870834589004517,1.5077009201049805,0.5881357789039612,0.5889744758605957,0.21327851712703705,0.2630201280117035,0.2796429395675659,0.38030216097831726,0.16162841022014618,0.2559692859649658}; + +#endif \ No newline at end of file diff --git a/src/reference/ai_poc/face_alignment/face_alignment.cc b/src/reference/ai_poc/face_alignment/face_alignment.cc new file mode 100755 index 000000000..ee0d5db1d --- /dev/null +++ b/src/reference/ai_poc/face_alignment/face_alignment.cc @@ -0,0 +1,268 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "face_alignment.h" +#include "k230_math.h" +#include "constant.h" +#include "rasterize.h" + +// for image +FaceAlignment::FaceAlignment(const char *kmodel_file,const char *post_kmodel_file, const int debug_mode) : AIBase(kmodel_file,"FaceAlignment", debug_mode),post_obj_(post_kmodel_file,debug_mode) +{ + model_name_ = "FaceAlignment"; + constant_init(); + ai2d_out_tensor_ = get_input_tensor(0); + post_ver_dim_ = post_obj_.output_shapes_[0][1]; +} + +// for video +FaceAlignment::FaceAlignment(const char *kmodel_file,const char *post_kmodel_file, FrameCHWSize isp_shape, uintptr_t vaddr, uintptr_t paddr, const int debug_mode) : AIBase(kmodel_file,"FaceAlignment", debug_mode),post_obj_(post_kmodel_file,debug_mode) +{ + model_name_ = "FaceAlignment"; + constant_init(); + post_ver_dim_ = post_obj_.output_shapes_[0][1]; + vaddr_ = vaddr; + + // ai2d_in_tensor to isp + isp_shape_ = isp_shape; + dims_t in_shape{1, isp_shape.channel, isp_shape.height, isp_shape.width}; + int isp_size = isp_shape.channel * isp_shape.height * isp_shape.width; +#if 0 + ai2d_in_tensor_ = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, { (gsl::byte *)vaddr, isp_size }, + true, hrt::pool_shared).expect("cannot create input tensor"); +#else + ai2d_in_tensor_ = hrt::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("create ai2d input tensor failed"); +#endif + + ai2d_out_tensor_ = get_input_tensor(0); +} + +// ai2d for image +void FaceAlignment::pre_process(cv::Mat ori_img,Bbox &bbox) +{ + ScopedTiming st(model_name_ + " pre_process image", debug_mode_); + + Bbox roi_b; + roi = parse_roi_box_from_bbox({ori_img.cols,ori_img.rows},bbox,roi_b); + std::vector chw_vec; + Utils::bgr2rgb_and_hwc2chw(ori_img,chw_vec); + Utils::crop_resize({ori_img.channels(), ori_img.rows, ori_img.cols}, chw_vec, roi_b, ai2d_out_tensor_); +} + +// ai2d for video +void FaceAlignment::pre_process(Bbox &bbox) +{ + ScopedTiming st(model_name_ + " pre_process video", debug_mode_); + size_t isp_size = isp_shape_.channel * isp_shape_.height * isp_shape_.width; + auto buf = ai2d_in_tensor_.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(buf.data()), (void *)vaddr_, isp_size); + hrt::sync(ai2d_in_tensor_, sync_op_t::sync_write_back, true).expect("sync write_back failed"); + + Bbox roi_b; + roi = parse_roi_box_from_bbox({isp_shape_.width,isp_shape_.height},bbox,roi_b); + Utils::crop_resize(roi_b,ai2d_builder_, ai2d_in_tensor_, ai2d_out_tensor_); +} + +void FaceAlignment::inference() +{ + this->run(); + this->get_output(); +} + +void FaceAlignment::post_process(FrameSize frame_size,vector& vertices) +{ + ScopedTiming st(model_name_ + " post_process", debug_mode_); + vector param(p_outputs_[0],p_outputs_[0] + output_shapes_[0][1]); + param_normalized(param); + + post_obj_.pre_process(param); + post_obj_.inference(); + post_obj_.post_process(vertices); + + //因为要在osd上画图,故需要把返回值变换到osd的长、宽 + roi.x0 = roi.x0 / isp_shape_.width * frame_size.width; + roi.y0 = roi.y0 / isp_shape_.height * frame_size.height; + roi.x1 = roi.x1 / isp_shape_.width * frame_size.width; + roi.y1 = roi.y1 / isp_shape_.height * frame_size.height; + recon_vers(roi, vertices); +} + +/*************************常量操作********************/ +void FaceAlignment::constant_init() +{ + bfm_tri = Utils::read_binary_file("bfm_tri.bin"); + ncc_code = Utils::read_binary_file("ncc_code.bin"); +} +/*************************前处理********************/ +LeftTopRightBottom FaceAlignment::parse_roi_box_from_bbox(FrameSize frame_size,Bbox& b,Bbox& roi_b) +{ + float old_size = ( b.w + b.h) / 2; + float center_x = b.x + b.w / 2; + float center_y = b.y + b.h / 2 + old_size * 0.14; + int size = int(old_size * 1.58); + + float x0 = center_x - float(size) / 2; + float y0 = center_y - float(size) / 2; + float x1 = x0 + size; + float y1 = y0 + size; + + x0 = std::max(float(0), std::min(x0, float(frame_size.width))); + y0 = std::max(float(0), std::min(y0, float(frame_size.height))); + x1 = std::max(float(0), std::min(x1, float(frame_size.width))); + y1 = std::max(float(0), std::min(y1, float(frame_size.height))); + + roi_b.x = x0; + roi_b.y = y0; + roi_b.w = x1 - x0; + roi_b.h = y1 - y0; + return {x0,y0,x1,y1}; +} + +/*************************后处理********************/ +void FaceAlignment::get_depth(cv::Mat &img, vector& vertices) +{ + vector z(post_ver_dim_ * 3); + vector ver(post_ver_dim_ * 3); + + int row = 0, col = 0; + int start_ver = 2 * post_ver_dim_, end_ver = 3 * post_ver_dim_; + float z_min = 0, z_max = 0; + + if (start_ver < end_ver) + z_min = z_max = vertices[start_ver]; + for (int vi = 0; vi < end_ver; ++vi) + { + row = vi / post_ver_dim_; + col = vi % post_ver_dim_; + ver[col * 3 + row] = vertices[vi]; + if (vi > start_ver) + { + if (vertices[vi] > z_max) + z_max = vertices[vi]; + else if (vertices[vi] < z_min) + z_min = vertices[vi]; + } + } + + float tmp_z = 0; + for (int ver_index = start_ver; ver_index < end_ver; ++ver_index) + { + tmp_z = (vertices[ver_index] - z_min) / (z_max - z_min); + for (int z_index = (ver_index - start_ver) * 3; z_index < (ver_index - start_ver + 1) * 3; ++z_index) + z[z_index] = tmp_z; + } + + rasterize(img, ver, z); +} + +void FaceAlignment::get_pncc(cv::Mat &img,vector& vertices) +{ + //rendering pncc + vector ver(post_ver_dim_ * 3); + int row = 0, col = 0, end_ver = 3 * post_ver_dim_; + for (int ver_index = 0; ver_index < end_ver; ++ver_index) + { + row = ver_index / post_ver_dim_; + col = ver_index % post_ver_dim_; + ver[col * 3 + row] = vertices[ver_index]; + } + + rasterize(img, ver, ncc_code); +} + +void FaceAlignment::param_normalized(vector& param) +{ + for (int param_index = 0; param_index < param.size(); ++param_index) + { + param[param_index] = param[param_index] * param_std[param_index] + param_mean[param_index]; + } +} + +void FaceAlignment::recon_vers(LeftTopRightBottom& roi_box_lst,vector &vertices) +{ + similar_transform(roi_box_lst,vertices); +} + +void FaceAlignment::similar_transform(LeftTopRightBottom& roi_box,vector &vertices) +{ + double scale_x = (roi_box.x1 - roi_box.x0) / input_shapes_[0][3]; + double scale_y = (roi_box.y1 - roi_box.y0) / input_shapes_[0][3]; + double s = (scale_x + scale_y) / 2; + + for (int row_index = 0; row_index < 3; ++row_index) + { + if (row_index == 0) + { + int index = 0; + for (int col_index = 0; col_index < post_ver_dim_; ++col_index) + { + index = row_index * post_ver_dim_ + col_index; + vertices[index] -= 1; + vertices[index] = vertices[index] * scale_x + roi_box.x0; + } + } + else if (row_index == 2) + { + int index = 0; + float min_dim2 = 0; + for (int col_index = 0; col_index < post_ver_dim_; ++col_index) + { + index = row_index * post_ver_dim_ + col_index; + vertices[index] -= 1; + vertices[index] *= s; + if (col_index == 0) + min_dim2 = vertices[index]; + else + { + if (vertices[index] < min_dim2) + min_dim2 = vertices[index]; + } + } + for (int col_index = 0; col_index < post_ver_dim_; ++col_index) + { + vertices[row_index * post_ver_dim_ + col_index] -= min_dim2; + } + } + else + { + int index = 0; + for (int col_index = 0; col_index < post_ver_dim_; ++col_index) + { + index = row_index * post_ver_dim_ + col_index; + vertices[index] = input_shapes_[0][3] - vertices[index]; + vertices[index] = vertices[index] * scale_y + roi_box.y0; + } + } + } +} + +void FaceAlignment::rasterize(cv::Mat& img, vector& vertices,vector &colors,float alpha, bool reverse) +{ + vector buffer(img.cols*img.rows,-1e8); + _rasterize(img.data, vertices.data(), bfm_tri.data(), colors.data(), buffer.data(), bfm_tri.size()/3, img.rows, img.cols, img.channels(), alpha, reverse); +} + +FaceAlignment::~FaceAlignment() +{ +} \ No newline at end of file diff --git a/src/reference/ai_poc/face_alignment/face_alignment.h b/src/reference/ai_poc/face_alignment/face_alignment.h new file mode 100755 index 000000000..c5821b089 --- /dev/null +++ b/src/reference/ai_poc/face_alignment/face_alignment.h @@ -0,0 +1,198 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FACE_ALIGNMENT_H +#define _FACE_ALIGNMENT_H + +#include +#include + +#include "utils.h" +#include "ai_base.h" +#include "face_alignment_post.h" + +using std::vector; + +#define LOC_SIZE 4 +#define CONF_SIZE 2 +#define LAND_SIZE 10 +#define PI 3.1415926 + +/** + * @brief 人脸检测框 + */ +typedef struct LeftTopRightBottom +{ + float x0; // 人脸检测框的左上角x坐标 + float y0; // 人脸检测框的左上角y坐标 + float x1; // 人脸检测框的右下角x坐标 + float y1; // 人脸检测框的右下角y坐标 +} LeftTopRightBottom; + +/** + * @brief 人脸对齐 + * 主要封装了对于每一帧图片,从预处理、运行到后处理给出结果的过程 + */ +class FaceAlignment : public AIBase +{ +public: + /** + * @brief FaceAlignment构造函数 + * @param kmodel_file kmodel文件路径 + * @param post_kmodel_file 后处理kmodel文件路径 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + FaceAlignment(const char *kmodel_file,const char *post_kmodel_file, const int debug_mode = 1); + + /** + * @brief FaceAlignment构造函数 + * @param kmodel_file kmodel文件路径 + * @param post_kmodel_file 后处理kmodel文件路径 + * @param isp_shape isp输入大小 + * @param vaddr isp对应虚拟地址 + * @param paddr isp对应物理地址 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + FaceAlignment(const char *kmodel_file,const char *post_kmodel_file, FrameCHWSize isp_shape, uintptr_t vaddr, uintptr_t paddr, const int debug_mode); + + /** + * @brief FaceAlignment析构函数 + * @return None + */ + ~FaceAlignment(); + + /** + * @brief 图片预处理,(ai2d for image) + * @param ori_img 原始图片 + * @param bbox 人脸检测框 + * @return None + */ + void pre_process(cv::Mat ori_img,Bbox &bbox); + + /** + * @brief 视频流预处理(ai2d for isp) + * @param bbox 人脸检测框 + * @return None + */ + void pre_process(Bbox &bbox); + + /** + * @brief kmodel推理 + * @return None + */ + void inference(); + + /** + * @brief kmodel推理结果后处理 + * @param frame_size 原始图像/帧宽高,用于将结果放到原始图像大小 + * @param vertices 后处理后3d点 + * @return None + */ + void post_process(FrameSize frame_size, vector& vertices); + + /** + * @brief 获取深度图 + * @param img 展示的图片或图层 + * @param vertices 后处理后3d点 + * @return None + */ + void get_depth(cv::Mat &img, vector& vertices); + + /** + * @brief 获取pncc图 + * @param img 展示的图片或图层 + * @param vertices 后处理后3d点 + * @return None + */ + void get_pncc(cv::Mat &img,vector &vertices); + +private: + /** + * @brief face_alignment常量初始化 + * @return None + */ + void constant_init(); + + /** + * @brief 根据人脸检测框获取face_alignment roi + * @param frame_size 原图尺寸,用于防止roi越界 + * @param b 人脸检测框 + * @param roi_b roi(x,y,w,h) + * @return roi(x1,y1,x2,y2) + */ + LeftTopRightBottom parse_roi_box_from_bbox(FrameSize frame_size,Bbox& b,Bbox& roi_b); + + /** + * @brief 参数归一化 + * @param 模型输出参数 + * @return None + */ + void param_normalized(vector& param); + + /** + * @brief 3d关键点渲染 + * @param roi_box_lst roi(x1,y1,x2,y2) + * @param vertices 3d关键点 + * @return None + */ + void recon_vers(LeftTopRightBottom& roi_box_lst,vector &vertices); + + /** + * @brief 3d关键点映射,将3d关键点映射roi尺寸 + * @param roi_box roi(x1,y1,x2,y2) + * @param vertices 3d关键点 + * @return None + */ + void similar_transform(LeftTopRightBottom& roi_box,vector &vertices); + + /** + * @brief 图像渲染 + * @param img 原图 + * @param vertices 3d关键点 + * @param colors 渲染颜色 + * @param alpha 渲染透明度 + * @param reverse 是否翻转渲染结果 + * @return None + */ + void rasterize(cv::Mat& img, vector& vertices,vector &colors,float alpha = 1, bool reverse = false); + + std::unique_ptr ai2d_builder_; // ai2d构建器 + runtime_tensor ai2d_in_tensor_; // ai2d输入tensor + runtime_tensor ai2d_out_tensor_; // ai2d输出tensor + uintptr_t vaddr_; // isp的虚拟地址 + FrameCHWSize isp_shape_; // isp对应的地址大小 + + FaceAlignmentPost post_obj_; // 人脸对齐后处理对象 + + int post_ver_dim_; // 3d点个数 + vector bfm_u; + vector bfm_w; + vector bfm_tri; + vector ncc_code; + LeftTopRightBottom roi; // roi(x1,y1,x2,y2) +}; + +#endif \ No newline at end of file diff --git a/src/reference/ai_poc/face_alignment/face_alignment_post.cc b/src/reference/ai_poc/face_alignment/face_alignment_post.cc new file mode 100755 index 000000000..f6fcb54e9 --- /dev/null +++ b/src/reference/ai_poc/face_alignment/face_alignment_post.cc @@ -0,0 +1,90 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "face_alignment_post.h" +#include "k230_math.h" +#include "constant.h" +#include "rasterize.h" + +// for image +FaceAlignmentPost::FaceAlignmentPost(const char *kmodel_file, const int debug_mode) : AIBase(kmodel_file,"FaceAlignmentPost", debug_mode) +{ + model_name_ = "FaceAlignmentPost"; +} + +// ai2d for video +void FaceAlignmentPost::pre_process(vector& param) +{ + ScopedTiming st(model_name_ + " pre_process", debug_mode_); + int offset = 0; + for(int i =0;ito_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + float *buf_data = reinterpret_cast(buf.data()); + if(i==0) + { + int in_shape_row = input_shapes_[0][0],in_shape_col = input_shapes_[0][1]; + for(int j = 0;jrun(); + this->get_output(); +} + +void FaceAlignmentPost::post_process(vector& vertices) +{ + ScopedTiming st(model_name_ + " post_process", debug_mode_); + int out_size = (each_output_size_by_byte_[1]-each_output_size_by_byte_[0])/sizeof(float); + vertices.insert(vertices.end(),p_outputs_[0],p_outputs_[0]+out_size); +} + +FaceAlignmentPost::~FaceAlignmentPost() +{ +} \ No newline at end of file diff --git a/src/reference/ai_poc/face_alignment/face_alignment_post.h b/src/reference/ai_poc/face_alignment/face_alignment_post.h new file mode 100755 index 000000000..3dc0e7c6a --- /dev/null +++ b/src/reference/ai_poc/face_alignment/face_alignment_post.h @@ -0,0 +1,85 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FACE_ALIGNMENT_POST_H +#define _FACE_ALIGNMENT_POST_H + +#include +#include + +#include "utils.h" +#include "ai_base.h" + +using std::vector; + +#define LOC_SIZE 4 +#define CONF_SIZE 2 +#define LAND_SIZE 10 +#define PI 3.1415926 + +/** + * @brief 人脸对齐后处理 + * 主要封装了对于每一帧图片,从预处理、运行到后处理给出结果的过程 + */ +class FaceAlignmentPost : public AIBase +{ +public: + /** + * @brief FaceAlignmentPost构造函数 + * @param kmodel_file kmodel文件路径 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + FaceAlignmentPost(const char *kmodel_file, const int debug_mode = 1); + + /** + * @brief FaceAlignmentPost析构函数 + * @return None + */ + ~FaceAlignmentPost(); + + /** + * @brief 预处理 + * @param param 人脸对齐3d关键点 + * @return None + */ + void pre_process(vector& param); + + /** + * @brief kmodel推理 + * @return None + */ + void inference(); + + /** + * @brief kmodel推理结果后处理 + * @param vertices 人脸3d点 + * @return None + */ + void post_process(vector& vertices); +private: + friend class FaceAlignment; +}; + +#endif \ No newline at end of file diff --git a/src/reference/ai_poc/face_alignment/face_detection.cc b/src/reference/ai_poc/face_alignment/face_detection.cc new file mode 100755 index 000000000..e3d83c567 --- /dev/null +++ b/src/reference/ai_poc/face_alignment/face_detection.cc @@ -0,0 +1,419 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "face_detection.h" +#include "k230_math.h" + +extern float kAnchors320[4200][4]; +extern float kAnchors640[16800][4]; +static float (*g_anchors)[4]; + +cv::Scalar color_list_for_det[] = { + cv::Scalar(0, 0, 255), + cv::Scalar(0, 255, 255), + cv::Scalar(255, 0, 255), + cv::Scalar(0, 255, 0), + cv::Scalar(255, 0, 0) +}; + +cv::Scalar color_list_for_osd_det[] = { + cv::Scalar(255, 0, 0, 255), + cv::Scalar(255, 0, 255, 255), + cv::Scalar(255, 255, 0, 255), + cv::Scalar(255, 0, 255, 0), + cv::Scalar(255, 255, 0, 0) +}; + +int nms_comparator(const void *pa, const void *pb) +{ + NMSRoiObj a = *(NMSRoiObj *)pa; + NMSRoiObj b = *(NMSRoiObj *)pb; + float diff = a.confidence - b.confidence; + + if (diff < 0) + return 1; + else if (diff > 0) + return -1; + return 0; +} + +// for image +FaceDetection::FaceDetection(const char *kmodel_file, float obj_thresh,float nms_thresh, const int debug_mode) : obj_thresh_(obj_thresh), AIBase(kmodel_file,"FaceDetection", debug_mode) +{ + model_name_ = "FaceDetection"; + nms_thresh_ = nms_thresh; + + int net_len = input_shapes_[0][2]; // input_shapes_[0][2]==input_shapes_[0][3] + min_size_ = (net_len == 320 ? 200 : 800); + g_anchors = (net_len == 320 ? kAnchors320 : kAnchors640); + objs_num_ = min_size_ * (1 + 4 + 16); + + so_ = new NMSRoiObj[objs_num_]; + boxes_ = new float[objs_num_ * LOC_SIZE]; + landmarks_ = new float[objs_num_ * LAND_SIZE]; + + ai2d_out_tensor_ = get_input_tensor(0); +} + +// for video +FaceDetection::FaceDetection(const char *kmodel_file, float obj_thresh,float nms_thresh, FrameCHWSize isp_shape, uintptr_t vaddr, uintptr_t paddr, const int debug_mode) : obj_thresh_(obj_thresh), AIBase(kmodel_file,"FaceDetection", debug_mode) +{ + model_name_ = "FaceDetection"; + nms_thresh_ = nms_thresh; + int net_len = input_shapes_[0][2]; // input_shapes_[0][2]==input_shapes_[0][3] + min_size_ = (net_len == 320 ? 200 : 800); + g_anchors = (net_len == 320 ? kAnchors320 : kAnchors640); + objs_num_ = min_size_ * (1 + 4 + 16); + vaddr_ = vaddr; + + so_ = new NMSRoiObj[objs_num_]; + boxes_ = new float[objs_num_ * LOC_SIZE]; + landmarks_ = new float[objs_num_ * LAND_SIZE]; + + // ai2d_in_tensor to isp + isp_shape_ = isp_shape; + dims_t in_shape{1, isp_shape.channel, isp_shape.height, isp_shape.width}; + int isp_size = isp_shape.channel * isp_shape.height * isp_shape.width; +#if 0 + ai2d_in_tensor_ = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, { (gsl::byte *)vaddr, isp_size }, + true, hrt::pool_shared).expect("cannot create input tensor"); +#else + ai2d_in_tensor_ = hrt::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("create ai2d input tensor failed"); +#endif + + ai2d_out_tensor_ = get_input_tensor(0); + + // fixed padding resize param + Utils::padding_resize_one_side(isp_shape, {input_shapes_[0][3], input_shapes_[0][2]}, ai2d_builder_, ai2d_in_tensor_, ai2d_out_tensor_, cv::Scalar(104, 117, 123)); +} + +// opencv for image +void FaceDetection::pre_process(cv::Mat ori_img, std::vector &dst) +{ + ScopedTiming st(model_name_ + " pre_process", debug_mode_); + cv::Mat padding_resize_img = Utils::padding_resize(ori_img, {input_shapes_[0][3], input_shapes_[0][2]}); + Utils::bgr2rgb_and_hwc2chw(padding_resize_img,dst); +} + +// ai2d for image +void FaceDetection::pre_process(cv::Mat ori_img) +{ + ScopedTiming st(model_name_ + " pre_process image", debug_mode_); + std::vector chw_vec; + Utils::bgr2rgb_and_hwc2chw(ori_img,chw_vec); + Utils::padding_resize_one_side({ori_img.channels(), ori_img.rows, ori_img.cols}, chw_vec, {input_shapes_[0][3], input_shapes_[0][2]}, ai2d_out_tensor_, cv::Scalar(104, 117, 123)); +} + +// ai2d for video +void FaceDetection::pre_process() +{ + ScopedTiming st(model_name_ + " pre_process video", debug_mode_); +#if 0 + ai2d_builder_->invoke(ai2d_in_tensor_,ai2d_out_tensor_).expect("error occurred in ai2d running"); +#else + size_t isp_size = isp_shape_.channel * isp_shape_.height * isp_shape_.width; + auto buf = ai2d_in_tensor_.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(buf.data()), (void *)vaddr_, isp_size); + hrt::sync(ai2d_in_tensor_, sync_op_t::sync_write_back, true).expect("sync write_back failed"); + ai2d_builder_->invoke(ai2d_in_tensor_,ai2d_out_tensor_).expect("error occurred in ai2d running"); +#endif + static int aa = 0; + if(aa==50) + { + auto vaddr_out_buf = ai2d_in_tensor_.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_read).unwrap().buffer(); + unsigned char *output = reinterpret_cast(vaddr_out_buf.data()); + Utils::dump_color_image("FaceDetection_input_ori_50.png",{isp_shape_.width,isp_shape_.height},output); + } + aa += 1; +} + +void FaceDetection::inference() +{ + this->run(); + this->get_output(); +} + +void FaceDetection::post_process(FrameSize frame_size, vector &results) +{ + ScopedTiming st(model_name_ + " post_process", debug_mode_); + int obj_cnt = 0; + deal_conf(p_outputs_[3], so_, 16 * min_size_ / 2, obj_cnt); + deal_conf(p_outputs_[4], so_, 4 * min_size_ / 2, obj_cnt); + deal_conf(p_outputs_[5], so_, 1 * min_size_ / 2, obj_cnt); + obj_cnt = 0; + deal_loc(p_outputs_[0], boxes_, 16 * min_size_ / 2, obj_cnt); + deal_loc(p_outputs_[1], boxes_, 4 * min_size_ / 2, obj_cnt); + deal_loc(p_outputs_[2], boxes_, 1 * min_size_ / 2, obj_cnt); + obj_cnt = 0; + deal_landms(p_outputs_[6], landmarks_, 16 * min_size_ / 2, obj_cnt); + deal_landms(p_outputs_[7], landmarks_, 4 * min_size_ / 2, obj_cnt); + deal_landms(p_outputs_[8], landmarks_, 1 * min_size_ / 2, obj_cnt); + qsort(so_, objs_num_, sizeof(NMSRoiObj), nms_comparator); + + get_final_box(frame_size, results); +} + +void FaceDetection::draw_result(cv::Mat& src_img,vector& results, bool pic_mode) +{ + int src_w = src_img.cols; + int src_h = src_img.rows; + int max_src_size = std::max(src_w,src_h); + for (int i = 0; i < results.size(); ++i) + { + auto& l = results[i].sparse_kps; + for (uint32_t ll = 0; ll < 5; ll++) + { + if(pic_mode) + { + int32_t x0 = l.points[2 * ll + 0]; + int32_t y0 = l.points[2 * ll + 1]; + cv::circle(src_img, cv::Point(x0, y0), 2, color_list_for_det[ll], 4); + } + else + { + int32_t x0 = l.points[2 * ll]/isp_shape_.width*src_w; + int32_t y0 = l.points[2 * ll+1]/isp_shape_.height*src_h; + cv::circle(src_img, cv::Point(x0, y0), 4, color_list_for_osd_det[ll], 8); + } + } + + auto& b = results[i].bbox; + char text[10]; + sprintf(text, "%.2f", results[i].score); + if(pic_mode) + { + cv::rectangle(src_img, cv::Rect(b.x, b.y , b.w, b.h), cv::Scalar(255, 255, 255), 2, 2, 0); + cv::putText(src_img, text , {b.x,b.y}, cv::FONT_HERSHEY_COMPLEX, 0.5, cv::Scalar(0, 255, 255), 1, 8, 0); + } + else + { + int x = b.x / isp_shape_.width * src_w; + int y = b.y / isp_shape_.height * src_h; + int w = b.w / isp_shape_.width * src_w; + int h = b.h / isp_shape_.height * src_h; + cv::rectangle(src_img, cv::Rect(x, y , w, h), cv::Scalar(255,255, 255, 255), 6, 2, 0); + } + } +} + +void FaceDetection::get_final_box(FrameSize &frame_size, vector &results) +{ + int iou_cal_times = 0; + int i, j, obj_index; + for (i = 0; i < objs_num_; ++i) + { + obj_index = so_[i].index; + if (so_[i].confidence < obj_thresh_) + continue; + FaceDetectionInfo obj; + obj.bbox = get_box(boxes_, obj_index); + obj.sparse_kps = get_landmark(landmarks_, obj_index); + + for (j = i + 1; j < objs_num_; ++j) + { + obj_index = so_[j].index; + if (so_[j].confidence < obj_thresh_) + continue; + Bbox b = get_box(boxes_, obj_index); + iou_cal_times += 1; + if (box_iou(obj.bbox, b) >= nms_thresh_) // thres + so_[j].confidence = 0; + } + obj.score = so_[i].confidence; + results.push_back(obj); + } + + // for src img + int max_src_size = std::max(frame_size.width, frame_size.height); + for (int i = 0; i < results.size(); ++i) + { + auto &l = results[i].sparse_kps; + for (uint32_t ll = 0; ll < 5; ll++) + { + l.points[2 * ll + 0] = l.points[2 * ll + 0] * max_src_size; + l.points[2 * ll + 1] = l.points[2 * ll + 1] * max_src_size; + } + + auto &b = results[i].bbox; + float x1 = (b.x + b.w / 2) * max_src_size; + float x0 = (b.x - b.w / 2) * max_src_size; + float y0 = (b.y - b.h / 2) * max_src_size; + float y1 = (b.y + b.h / 2) * max_src_size; + x1 = std::max(float(0), std::min(x1, float(frame_size.width))); + x0 = std::max(float(0), std::min(x0, float(frame_size.width))); + y0 = std::max(float(0), std::min(y0, float(frame_size.height))); + y1 = std::max(float(0), std::min(y1, float(frame_size.height))); + b.x = x0; + b.y = y0; + b.w = x1 - x0; + b.h = y1 - y0; + } +} + +void FaceDetection::local_softmax(float *x, float *dx, uint32_t len) +{ + float max_value = x[0]; + for (uint32_t i = 0; i < len; i++) + { + if (max_value < x[i]) + { + max_value = x[i]; + } + } + for (uint32_t i = 0; i < len; i++) + { + x[i] -= max_value; + x[i] = expf(x[i]); + } + float sum_value = 0.0f; + for (uint32_t i = 0; i < len; i++) + { + sum_value += x[i]; + } + for (uint32_t i = 0; i < len; i++) + { + dx[i] = x[i] / sum_value; + } +} + +void FaceDetection::deal_conf(float *conf, NMSRoiObj *so, int size, int &obj_cnt) +{ + float confidence[CONF_SIZE] = {0.0}; + for (uint32_t ww = 0; ww < size; ww++) + { + for (uint32_t hh = 0; hh < 2; hh++) + { + for (uint32_t cc = 0; cc < CONF_SIZE; cc++) + { + confidence[cc] = conf[(hh * CONF_SIZE + cc) * size + ww]; + } + local_softmax(confidence, confidence, 2); + so_[obj_cnt].index = obj_cnt; + so_[obj_cnt].confidence = confidence[1]; + obj_cnt += 1; + } + } +} + +void FaceDetection::deal_loc(float *loc, float *boxes, int size, int &obj_cnt) +{ + for (uint32_t ww = 0; ww < size; ww++) + { + for (uint32_t hh = 0; hh < 2; hh++) + { + for (uint32_t cc = 0; cc < LOC_SIZE; cc++) + { + boxes_[obj_cnt * LOC_SIZE + cc] = loc[(hh * LOC_SIZE + cc) * size + ww]; + } + obj_cnt += 1; + } + } +} + +void FaceDetection::deal_landms(float *landms, float *landmarks, int size, int &obj_cnt) +{ + // chw->hwc + for (uint32_t ww = 0; ww < size; ww++) + { + for (uint32_t hh = 0; hh < 2; hh++) + { + for (uint32_t cc = 0; cc < LAND_SIZE; cc++) + { + landmarks_[obj_cnt * LAND_SIZE + cc] = landms[(hh * LAND_SIZE + cc) * size + ww]; + } + obj_cnt += 1; + } + } +} + +Bbox FaceDetection::get_box(float *boxes, int obj_index) +{ + float cx, cy, w, h; + cx = boxes_[obj_index * LOC_SIZE + 0]; + cy = boxes_[obj_index * LOC_SIZE + 1]; + w = boxes_[obj_index * LOC_SIZE + 2]; + h = boxes_[obj_index * LOC_SIZE + 3]; + cx = g_anchors[obj_index][0] + cx * 0.1 * g_anchors[obj_index][2]; + cy = g_anchors[obj_index][1] + cy * 0.1 * g_anchors[obj_index][3]; + w = g_anchors[obj_index][2] * k230_expf(w * 0.2); + h = g_anchors[obj_index][3] * k230_expf(h * 0.2); + Bbox box; + box.x = cx; + box.y = cy; + box.w = w; + box.h = h; + return box; +} + +SparseLandmarks FaceDetection::get_landmark(float *landmarks, int obj_index) +{ + SparseLandmarks landmark; + for (uint32_t ll = 0; ll < 5; ll++) + { + landmark.points[2 * ll + 0] = g_anchors[obj_index][0] + landmarks_[obj_index * LAND_SIZE + 2 * ll + 0] * 0.1 * g_anchors[obj_index][2]; + landmark.points[2 * ll + 1] = g_anchors[obj_index][1] + landmarks_[obj_index * LAND_SIZE + 2 * ll + 1] * 0.1 * g_anchors[obj_index][3]; + } + return landmark; +} + +float FaceDetection::overlap(float x1, float w1, float x2, float w2) +{ + float l1 = x1 - w1 / 2; + float l2 = x2 - w2 / 2; + float left = l1 > l2 ? l1 : l2; + float r1 = x1 + w1 / 2; + float r2 = x2 + w2 / 2; + float right = r1 < r2 ? r1 : r2; + return right - left; +} + +float FaceDetection::box_intersection(Bbox a, Bbox b) +{ + float w = overlap(a.x, a.w, b.x, b.w); + float h = overlap(a.y, a.h, b.y, b.h); + + if (w < 0 || h < 0) + return 0; + return w * h; +} + +float FaceDetection::box_union(Bbox a, Bbox b) +{ + float i = box_intersection(a, b); + float u = a.w * a.h + b.w * b.h - i; + + return u; +} + +float FaceDetection::box_iou(Bbox a, Bbox b) +{ + return box_intersection(a, b) / box_union(a, b); +} + +FaceDetection::~FaceDetection() +{ + delete[] so_; + delete[] boxes_; + delete[] landmarks_; +} \ No newline at end of file diff --git a/src/reference/ai_poc/face_alignment/face_detection.h b/src/reference/ai_poc/face_alignment/face_detection.h new file mode 100755 index 000000000..385d98109 --- /dev/null +++ b/src/reference/ai_poc/face_alignment/face_detection.h @@ -0,0 +1,253 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FACE_DETECTION_H +#define _FACE_DETECTION_H + +#include +#include + +#include "utils.h" +#include "ai_base.h" + +using std::vector; + +#define LOC_SIZE 4 +#define CONF_SIZE 2 +#define LAND_SIZE 10 +#define PI 3.1415926 + +/** + * @brief 用于NMS排序的roi对象 + */ +typedef struct NMSRoiObj +{ + int index; // roi对象所在原列表的索引 + float confidence; // roi对象的置信度 +} NMSRoiObj; + +/** + * @brief 预测人脸roi信息 + */ +typedef struct FaceDetectionInfo +{ + Bbox bbox; // 人脸检测框 + SparseLandmarks sparse_kps; // 人脸五官关键点 + float score; // 人脸检测框置信度 +} FaceDetectionInfo; + +/** + * @brief 人脸检测 + * 主要封装了对于每一帧图片,从预处理、运行到后处理给出结果的过程 + */ +class FaceDetection : public AIBase +{ +public: + /** + * @brief FaceDetection构造函数,加载kmodel,并初始化kmodel输入、输出和人脸检测阈值 + * @param kmodel_file kmodel文件路径 + * @param obj_thresh 人脸检测阈值,用于过滤roi + * @param nms_thresh 人脸检测nms阈值 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + FaceDetection(const char *kmodel_file, float obj_thresh,float nms_thresh, const int debug_mode = 1); + + /** + * @brief FaceDetection构造函数,加载kmodel,并初始化kmodel输入、输出和人脸检测阈值 + * @param kmodel_file kmodel文件路径 + * @param obj_thresh 人脸检测阈值,用于过滤roi + * @param nms_thresh 人脸检测nms阈值 + * @param isp_shape isp输入大小(chw) + * @param vaddr isp对应虚拟地址 + * @param paddr isp对应物理地址 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + FaceDetection(const char *kmodel_file, float obj_thresh,float nms_thresh, FrameCHWSize isp_shape, uintptr_t vaddr, uintptr_t paddr, const int debug_mode); + + /** + * @brief FaceDetection析构函数 + * @return None + */ + ~FaceDetection(); + + /** + * @brief 图片预处理 + * @param ori_img 原始图片 + * @param dst 处理后NCHW的图像数据 + * @return None + */ + void pre_process(cv::Mat ori_img, std::vector &dst); + + /** + * @brief 图片预处理,(ai2d for image) + * @param ori_img 原始图片 + * @return None + */ + void pre_process(cv::Mat ori_img); + + /** + * @brief 视频流预处理(ai2d for isp) + * @return None + */ + void pre_process(); + + /** + * @brief kmodel推理 + * @return None + */ + void inference(); + + /** + * @brief kmodel推理结果后处理 + * @param frame_size 原始图像/帧宽高,用于将结果放到原始图像大小 + * @param results 后处理之后的基于原始图像的{检测框、五官点和得分}集合 + * @return None + */ + void post_process(FrameSize frame_size, vector &results); + + /** + * @brief 将检测结果画到原图 + * @param src_img 原图 + * @param pic_mode ture(原图片),false(osd) + * @return None + */ + void draw_result(cv::Mat& src_img,vector& results, bool pic_mode = true); + +private: + /** + * @brief softmax操作 + * @param x 需要处理数据指针 + * @param dx 处理数据后的指针 + * @param len 需要处理数据长度 + * @return None + */ + void local_softmax(float *x, float *dx, uint32_t len); + + /** + * @brief roi置信度后处理 + * @param conf 指向模型推理得到的首个roi置信度的指针 + * @param so 指向经过softmax之后首个roi置信度的指针 + * @param size 需要处理roi个数 + * @param obj_cnt 已经处理的roi个数,deal_conf会被调用多次 + * @return None + */ + void deal_conf(float *conf, NMSRoiObj *so, int size, int &obj_cnt); + + /** + * @brief roi位置(location)后处理 + * @param loc 模型推理后,指向首个roi位置的指针 + * @param boxes 经过NCHW-NHWC之后,指向首个roi位置的指针 + * @param size 需要处理roi个数 + * @param obj_cnt 已经处理的roi个数,deal_loc会被调用多次 + * @return None + */ + void deal_loc(float *loc, float *boxes, int size, int &obj_cnt); + + /** + * @brief roi五官关键点后处理 + * @param landms 模型推理后,指向首个roi对应的五官关键点的指针 + * @param boxes 经过NCHW-NHWC之后,指向首个roi对应的五官关键点的指针 + * @param size 需要处理roi个数 + * @param obj_cnt 已经处理的roi个数,deal_landms会被调用多次 + * @return None + */ + void deal_landms(float *landms, float *landmarks, int size, int &obj_cnt); + + /** + * @brief 根据索引值得到单个roi检测框 + * @param boxes 指向首个roi的检测框的指针 + * @param obj_index 需要获取的roi索引 + * @return None + */ + Bbox get_box(float *boxes, int obj_index); + + /** + * @brief 根据索引值得到单个roi对应的五官关键点 + * @param landmarks 指向首个roi对应的五官关键点指针 + * @param obj_index 需要获取的roi索引 + * @return None + */ + SparseLandmarks get_landmark(float *landmarks, int obj_index); + + /** + * @brief 获取2个检测框重叠区域的左上角或右下角 + * @param x1 第1个检测框的中心点x或y坐标 + * @param w1 第1个检测框的宽(w)或高(h) + * @param x2 第2个检测框的中心点x或y坐标 + * @param w2 第2个检测框的宽(w)或高(h) + * @return 2个检测框重叠区域的宽或高 + */ + float overlap(float x1, float w1, float x2, float w2); + + /** + * @brief 获取2个检测框重叠区域的面积 + * @param a 第1个检测框 + * @param b 第2个检测框 + * @return 2个检测框重叠区域的面积 + */ + float box_intersection(Bbox a, Bbox b); + + /** + * @brief 获取2个检测框联合区域的面积 + * @param a 第1个检测框 + * @param b 第2个检测框 + * @return 2个检测框重叠联合区域的面积 + */ + float box_union(Bbox a, Bbox b); + + /** + * @brief 获取2个检测框的iou + * @param a 第1个检测框 + * @param b 第2个检测框 + * @return 2个检测框的iou + */ + float box_iou(Bbox a, Bbox b); + + /** + * @brief 获取2个检测框的iou + * @param frame_size 原始图像/帧宽高,用于将结果放到原始图像大小 + * @param results 后处理之后的基于原始图像的{检测框、五官点和得分}集合 + * @return None + */ + void get_final_box(FrameSize &frame_size, vector &results); + + std::unique_ptr ai2d_builder_; // ai2d构建器 + runtime_tensor ai2d_in_tensor_; // ai2d输入tensor + runtime_tensor ai2d_out_tensor_; // ai2d输出tensor + uintptr_t vaddr_; // isp的虚拟地址 + FrameCHWSize isp_shape_; // isp对应的地址大小 + + int min_size_; + float obj_thresh_; // 人脸检测阈值 + float nms_thresh_; // nms阈值 + int objs_num_; // roi个数 + + NMSRoiObj *so_; // 指向经过softmax之后首个roi置信度的指针 + float *boxes_; // 指向首个roi检测框的指针 + float *landmarks_; // 指向首个roi对应五官关键点的指针 +}; + +#endif \ No newline at end of file diff --git a/src/reference/ai_poc/face_alignment/main.cc b/src/reference/ai_poc/face_alignment/main.cc new file mode 100644 index 000000000..4e658db98 --- /dev/null +++ b/src/reference/ai_poc/face_alignment/main.cc @@ -0,0 +1,200 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include "utils.h" +#include "vi_vo.h" +#include "face_detection.h" +#include "face_alignment.h" +#include "face_alignment_post.h" + +using std::cerr; +using std::cout; +using std::endl; + +std::atomic isp_stop(false); + +void print_usage(const char *name) +{ + cout << "Usage: " << name << " " << endl + << "Options:" << endl + << " kmodel_det 人脸检测kmodel路径\n" + << " obj_thres 人脸检测阈值\n" + << " nms_thres 人脸检测nms阈值\n" + << " kmodel_align 人脸对齐kmodel路径\n" + << " kmodel_align_post 人脸对齐后处理kmodel路径\n" + << " input_mode 本地图片(图片路径)/ 摄像头(None) \n" + << " output_mode 渲染方式(depth、pncc)\n" + << " debug_mode 是否需要调试,0、1、2分别表示不调试、简单调试、详细调试\n" + << "\n" + << endl; +} + +void video_proc(char *argv[]) +{ + vivcap_start(); + // 设置osd参数 + k_video_frame_info vf_info; + void *pic_vaddr = NULL; //osd + memset(&vf_info, 0, sizeof(vf_info)); + vf_info.v_frame.width = osd_width; + vf_info.v_frame.height = osd_height; + vf_info.v_frame.stride[0] = osd_width; + vf_info.v_frame.pixel_format = PIXEL_FORMAT_ARGB_8888; + block = vo_insert_frame(&vf_info, &pic_vaddr); + + // alloc memory,get isp memory + size_t paddr = 0; + void *vaddr = nullptr; + size_t size = SENSOR_CHANNEL * SENSOR_HEIGHT * SENSOR_WIDTH; + int ret = kd_mpi_sys_mmz_alloc_cached(&paddr, &vaddr, "allocate", "anonymous", size); + if (ret) + { + std::cerr << "physical_memory_block::allocate failed: ret = " << ret << ", errno = " << strerror(errno) << std::endl; + std::abort(); + } + + FaceDetection face_det(argv[1], atof(argv[2]),atof(argv[3]), {SENSOR_CHANNEL, SENSOR_HEIGHT, SENSOR_WIDTH}, reinterpret_cast(vaddr), reinterpret_cast(paddr), atoi(argv[8])); + FaceAlignment face_align(argv[4],argv[5], {SENSOR_CHANNEL, SENSOR_HEIGHT, SENSOR_WIDTH}, reinterpret_cast(vaddr), reinterpret_cast(paddr), atoi(argv[8])); + string output_mode(argv[7]); + + vector det_results; + while (!isp_stop) + { + ScopedTiming st("total time", 1); + + { + ScopedTiming st("read capture", atoi(argv[8])); + // 从vivcap中读取一帧图像到dump_info + memset(&dump_info, 0, sizeof(k_video_frame_info)); + ret = kd_mpi_vicap_dump_frame(vicap_dev, VICAP_CHN_ID_1, VICAP_DUMP_YUV, &dump_info, 1000); + if (ret) + { + printf("sample_vicap...kd_mpi_vicap_dump_frame failed.\n"); + continue; + } + } + + { + ScopedTiming st("isp copy", atoi(argv[8])); + auto vbvaddr = kd_mpi_sys_mmap_cached(dump_info.v_frame.phys_addr[0], size); + memcpy(vaddr, (void *)vbvaddr, SENSOR_HEIGHT * SENSOR_WIDTH * 3); // 这里以后可以去掉,不用copy + kd_mpi_sys_munmap(vbvaddr, size); + } + + det_results.clear(); + + face_det.pre_process(); + face_det.inference(); + // 旋转后图像 + face_det.post_process({SENSOR_WIDTH, SENSOR_HEIGHT}, det_results); + cv::Mat osd_frame(osd_height, osd_width, CV_8UC4, cv::Scalar(0, 0, 0, 0)); + + for (int i = 0; i < det_results.size(); ++i) + { + face_align.pre_process(det_results[i].bbox); + face_align.inference(); + vector vertices; + face_align.post_process({osd_width, osd_height},vertices); + if(output_mode == "depth") + face_align.get_depth(osd_frame, vertices); + else if(output_mode == "pncc") + face_align.get_pncc(osd_frame, vertices); + } + + { + ScopedTiming st("osd copy", atoi(argv[8])); + memcpy(pic_vaddr, osd_frame.data, osd_width * osd_height * 4); + kd_mpi_vo_chn_insert_frame(osd_id + 3, &vf_info); // K_VO_OSD0 + ret = kd_mpi_vicap_dump_release(vicap_dev, VICAP_CHN_ID_1, &dump_info); + if (ret) + { + printf("sample_vicap...kd_mpi_vicap_dump_release failed.\n"); + } + } + } + + vo_osd_release_block(); + vivcap_stop(); + + // free memory + ret = kd_mpi_sys_mmz_free(paddr, vaddr); + if (ret) + { + std::cerr << "free failed: ret = " << ret << ", errno = " << strerror(errno) << std::endl; + std::abort(); + } +} + +int main(int argc, char *argv[]) +{ + std::cout << "case " << argv[0] << " built at " << __DATE__ << " " << __TIME__ << std::endl; + if (argc != 9) + { + print_usage(argv[0]); + return -1; + } + + if (strcmp(argv[6], "None") == 0) + { + std::thread thread_isp(video_proc, argv); + while (getchar() != 'q') + { + usleep(10000); + } + + isp_stop = true; + thread_isp.join(); + } + else + { + cv::Mat ori_img = cv::imread(argv[6]); + int ori_w = ori_img.cols; + int ori_h = ori_img.rows; + FaceDetection face_det(argv[1], atof(argv[2]),atof(argv[3]), atoi(argv[8])); + face_det.pre_process(ori_img); + face_det.inference(); + + vector det_results; + face_det.post_process({ori_w, ori_h}, det_results); + + FaceAlignment face_align(argv[4],argv[5],atoi(argv[8])); + string output_mode(argv[7]); + + for (int i = 0; i < det_results.size(); ++i) + { + face_align.pre_process(ori_img, det_results[i].bbox); + face_align.inference(); + vector vertices; + face_align.post_process({ori_w, ori_h},vertices); + if(output_mode == "depth") + face_align.get_depth(ori_img, vertices); + else if(output_mode == "pncc") + face_align.get_pncc(ori_img, vertices); + } + cv::imwrite("face_align_result.jpg", ori_img); + } + return 0; +} \ No newline at end of file diff --git a/src/reference/ai_poc/face_alignment/rasterize.cc b/src/reference/ai_poc/face_alignment/rasterize.cc new file mode 100644 index 000000000..00448fe73 --- /dev/null +++ b/src/reference/ai_poc/face_alignment/rasterize.cc @@ -0,0 +1,156 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include + +#include"rasterize.h" + +void _get_point_weight(float *weight, Point p, Point p0, Point p1, Point p2) +{ + // vectors + Point v0, v1, v2; + v0 = p2 - p0; + v1 = p1 - p0; + v2 = p - p0; + + // dot products + float dot00 = v0.dot(v0); //v0.x * v0.x + v0.y * v0.y //np.dot(v0.T, v0) + float dot01 = v0.dot(v1); //v0.x * v1.x + v0.y * v1.y //np.dot(v0.T, v1) + float dot02 = v0.dot(v2); //v0.x * v2.x + v0.y * v2.y //np.dot(v0.T, v2) + float dot11 = v1.dot(v1); //v1.x * v1.x + v1.y * v1.y //np.dot(v1.T, v1) + float dot12 = v1.dot(v2); //v1.x * v2.x + v1.y * v2.y//np.dot(v1.T, v2) + + // barycentric coordinates + float inverDeno; + if (dot00 * dot11 - dot01 * dot01 == 0) + inverDeno = 0; + else + inverDeno = 1 / (dot00 * dot11 - dot01 * dot01); + + float u = (dot11 * dot02 - dot01 * dot12) * inverDeno; + float v = (dot00 * dot12 - dot01 * dot02) * inverDeno; + + // weight + weight[0] = 1 - u - v; + weight[1] = v; + weight[2] = u; +} + +void _rasterize( + unsigned char *image, float *vertices, int *triangles, float *colors, float *depth_buffer, + int ntri, int h, int w, int c, float alpha, bool reverse) { + int x, y, k; + int tri_p0_ind, tri_p1_ind, tri_p2_ind; + Point p0, p1, p2, p; + int x_min, x_max, y_min, y_max; + float p_depth, p0_depth, p1_depth, p2_depth; + float p_color, p0_color, p1_color, p2_color; + float weight[3]; + + for (int i = 0; i < ntri; i++) { + tri_p0_ind = triangles[3 * i]; + tri_p1_ind = triangles[3 * i + 1]; + tri_p2_ind = triangles[3 * i + 2]; + + p0.x = vertices[3 * tri_p0_ind]; + p0.y = vertices[3 * tri_p0_ind + 1]; + p0_depth = vertices[3 * tri_p0_ind + 2]; + p1.x = vertices[3 * tri_p1_ind]; + p1.y = vertices[3 * tri_p1_ind + 1]; + p1_depth = vertices[3 * tri_p1_ind + 2]; + p2.x = vertices[3 * tri_p2_ind]; + p2.y = vertices[3 * tri_p2_ind + 1]; + p2_depth = vertices[3 * tri_p2_ind + 2]; + + x_min = max((int)ceil(min(p0.x, min(p1.x, p2.x))), 0); + x_max = min((int)floor(max(p0.x, max(p1.x, p2.x))), w - 1); + + y_min = max((int)ceil(min(p0.y, min(p1.y, p2.y))), 0); + y_max = min((int)floor(max(p0.y, max(p1.y, p2.y))), h - 1); + + if (x_max < x_min || y_max < y_min) { + continue; + } + + for (y = y_min; y <= y_max; y++) { + for (x = x_min; x <= x_max; x++) { + p.x = float(x); + p.y = float(y); + + // call get_point_weight function once + _get_point_weight(weight, p, p0, p1, p2); + + // and judge is_point_in_tri by below line of code + if (weight[2] > 0 && weight[1] > 0 && weight[0] > 0) { + _get_point_weight(weight, p, p0, p1, p2); + p_depth = weight[0] * p0_depth + weight[1] * p1_depth + weight[2] * p2_depth; + + if ((p_depth > depth_buffer[y * w + x])) { + //for (k = 0; k < c; k++) { + for (k = 0; k < 3; k++) { + p0_color = colors[3 * tri_p0_ind + k]; + p1_color = colors[3 * tri_p1_ind + k]; + p2_color = colors[3 * tri_p2_ind + k]; + + p_color = weight[0] * p0_color + weight[1] * p1_color + weight[2] * p2_color; + if (reverse) { + if (c == 3) //bgr + { + image[(h - 1 - y) * w * c + x * c + k] = (unsigned char)( + (1 - alpha) * image[(h - 1 - y) * w * c + x * c + k] + alpha * 255 * p_color); + // image[(h - 1 - y) * w * c + x * c + k] = (unsigned char) (255 * p_color); + } + else //c==4 ,argb + { + image[(h - 1 - y) * w * c + x * c + k + 1] = (unsigned char)( + (1 - alpha) * image[(h - 1 - y) * w * c + x * c + k + 1] + alpha * 255 * p_color); + } + + } + else { + if (c == 3) //bgr + { + image[y * w * c + x * c + k] = (unsigned char)( + (1 - alpha) * image[y * w * c + x * c + k] + alpha * 255 * p_color); + + } + else //c==4 ,argb + { + image[y * w * c + x * c] = 255; + image[y * w * c + x * c + k + 1] = (unsigned char)( + (1 - alpha) * image[y * w * c + x * c + k] + alpha * 255 * p_color); + } + + + } + } + + depth_buffer[y * w + x] = p_depth; + } + } + } + } + } +} \ No newline at end of file diff --git a/src/reference/ai_poc/face_alignment/rasterize.h b/src/reference/ai_poc/face_alignment/rasterize.h new file mode 100644 index 000000000..18e5023a9 --- /dev/null +++ b/src/reference/ai_poc/face_alignment/rasterize.h @@ -0,0 +1,77 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _RASTERIZE_H +#define _RASTERIZE_H + +#include +#include + +using std::max; +using std::min; + +class Point +{ +public: + float x; + float y; + +public: + Point() : x(0.f), y(0.f) {} + Point(float x_, float y_) : x(x_), y(y_) {} + float dot(Point p) + { + return this->x * p.x + this->y * p.y; + } + + Point operator-(const Point &p) + { + Point np; + np.x = this->x - p.x; + np.y = this->y - p.y; + return np; + } + + Point operator+(const Point &p) + { + Point np; + np.x = this->x + p.x; + np.y = this->y + p.y; + return np; + } + + Point operator*(float s) + { + Point np; + np.x = s * this->x; + np.y = s * this->y; + return np; + } +}; + +void _get_point_weight(float *weight, Point p, Point p0, Point p1, Point p2); +void _rasterize(unsigned char *image, float *vertices, int *triangles, float *colors, float *depth_buffer, + int ntri, int h, int w, int c, float alpha, bool reverse); +#endif diff --git a/src/reference/ai_poc/face_alignment/scoped_timing.hpp b/src/reference/ai_poc/face_alignment/scoped_timing.hpp new file mode 100644 index 000000000..874ff1b17 --- /dev/null +++ b/src/reference/ai_poc/face_alignment/scoped_timing.hpp @@ -0,0 +1,70 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include + +/** + * @brief 计时类 + * 统计在该类实例生命周期内的耗时 + */ +class ScopedTiming +{ +public: + /** + * @brief ScopedTiming构造函数,初始化计时对象名称并开始计时 + * @param info 计时对象名称 + * @param enable_profile 是否开始计时 + * @return None + */ + ScopedTiming(std::string info = "ScopedTiming", int enable_profile = 1) + : m_info(info), enable_profile(enable_profile) + { + if (enable_profile) + { + m_start = std::chrono::steady_clock::now(); + } + } + + /** + * @brief ScopedTiming析构,结束计时,并打印耗时 + * @return None + */ + ~ScopedTiming() + { + if (enable_profile) + { + m_stop = std::chrono::steady_clock::now(); + double elapsed_ms = std::chrono::duration(m_stop - m_start).count(); + std::cout << m_info << " took " << elapsed_ms << " ms" << std::endl; + } + } + +private: + int enable_profile; // 是否统计时间 + std::string m_info; // 计时对象名称 + std::chrono::steady_clock::time_point m_start; // 计时开始时间 + std::chrono::steady_clock::time_point m_stop; // 计时结束时间 +}; \ No newline at end of file diff --git a/src/reference/ai_poc/face_alignment/utils.cc b/src/reference/ai_poc/face_alignment/utils.cc new file mode 100755 index 000000000..15332261d --- /dev/null +++ b/src/reference/ai_poc/face_alignment/utils.cc @@ -0,0 +1,402 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +// utils.cpp +#include +#include "utils.h" + +using std::ofstream; +using std::vector; +auto cache = cv::Mat::zeros(1, 1, CV_32FC1); +void Utils::dump_binary_file(const char *file_name, char *data, const size_t size) +{ + // eg:Utils::dump_binary_file(out_name.c_str(),reinterpret_cast(p_outputs_[i]),each_output_size_by_byte_[i+1]-each_output_size_by_byte_[i]); + std::ofstream outf; + outf.open(file_name, std::ofstream::binary); + outf.write(data, size); + outf.close(); +} + +void Utils::dump_gray_image(const char *file_name, const FrameSize &frame_size, unsigned char *data) +{ + cv::Mat gray_image = cv::Mat(frame_size.height, frame_size.width, CV_8UC1, data); + cv::imwrite(file_name, gray_image); +} + +void Utils::dump_color_image(const char *file_name, const FrameSize &frame_size, unsigned char *data) +{ + cv::Mat image_r = cv::Mat(frame_size.height, frame_size.width, CV_8UC1, data); + cv::Mat image_g = cv::Mat(frame_size.height, frame_size.width, CV_8UC1, data+frame_size.height*frame_size.width); + cv::Mat image_b = cv::Mat(frame_size.height, frame_size.width, CV_8UC1, data+2*frame_size.height*frame_size.width); + + std::vector color_vec(3); + color_vec.clear(); + color_vec.push_back(image_b); + color_vec.push_back(image_g); + color_vec.push_back(image_r); + + cv::Mat color_img; + cv::merge(color_vec, color_img); + cv::imwrite(file_name, color_img); +} + +cv::Mat Utils::padding_resize(const cv::Mat img, const FrameSize &frame_size, const cv::Scalar &padding) +{ + // width:dst_width + int ori_w = img.cols; + int ori_h = img.rows; + float ratiow = (float)frame_size.width / ori_w; + float ratioh = (float)frame_size.height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(frame_size.width - new_w) / 2; + float dh = (float)(frame_size.height - new_h) / 2; + int top = (int)(roundf(0 - 0.1)); + int bottom = (int)(roundf(dh * 2 + 0.1)); + int left = (int)(roundf(0 - 0.1)); + int right = (int)(roundf(dw * 2 - 0.1)); + cv::Mat cropped_img; + { + if ((new_w != frame_size.width) || (new_h != frame_size.height)) + { + cv::resize(img, cropped_img, cv::Size(new_w, new_h), cv::INTER_AREA); + } + } + { + // 104, 117, 123,BGR + cv::copyMakeBorder(cropped_img, cropped_img, top, bottom, left, right, cv::BORDER_CONSTANT, padding); + } + return cropped_img; +} + +cv::Mat Utils::resize(const cv::Mat img, const FrameSize &frame_size) +{ + cv::Mat cropped_img; + cv::resize(img, cropped_img, cv::Size(frame_size.width, frame_size.height), cv::INTER_LINEAR); + return cropped_img; +} + +cv::Mat Utils::bgr_to_rgb(cv::Mat ori_img) +{ + cv::Mat rgb_img; + cv::cvtColor(ori_img, rgb_img, cv::COLOR_BGR2RGB); + return rgb_img; +} + +void Utils::hwc_to_chw(cv::Mat &ori_img, std::vector &chw_vec) +{ + // for rgb format + std::vector rgbChannels(3); + cv::split(ori_img, rgbChannels); + for (auto i = 0; i < rgbChannels.size(); i++) + { + std::vector data = std::vector(rgbChannels[i].reshape(1, 1)); + chw_vec.insert(chw_vec.end(), data.begin(), data.end()); + } +} + +void Utils::bgr2rgb_and_hwc2chw(cv::Mat &ori_img, std::vector &chw_vec) +{ + // for bgr format + std::vector bgrChannels(3); + cv::split(ori_img, bgrChannels); + for (auto i = 2; i > -1; i--) + { + std::vector data = std::vector(bgrChannels[i].reshape(1, 1)); + chw_vec.insert(chw_vec.end(), data.begin(), data.end()); + } +} + +void Utils::resize(FrameCHWSize ori_shape, std::vector &chw_vec, runtime_tensor &ai2d_out_tensor) +{ + // build ai2d_in_tensor + dims_t in_shape{1, ori_shape.channel, ori_shape.height, ori_shape.width}; + runtime_tensor ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), chw_vec.data(), chw_vec.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + // ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, typecode_t::dt_uint8, typecode_t::dt_uint8}; + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param { false, 30, 20, 400, 600 }; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, ai2d_pad_mode::constant, {114, 114, 114}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::resize(std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor) +{ + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param { false, 30, 20, 400, 600 }; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, ai2d_pad_mode::constant, {114, 114, 114}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::crop_resize(FrameCHWSize ori_shape, std::vector &chw_vec, Bbox &crop_info, runtime_tensor &ai2d_out_tensor) +{ + // build ai2d_in_tensor + dims_t in_shape{1, ori_shape.channel, ori_shape.height, ori_shape.width}; + runtime_tensor ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), chw_vec.data(), chw_vec.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{true, crop_info.x, crop_info.y, crop_info.w, crop_info.h}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, ai2d_pad_mode::constant, {114, 114, 114}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::crop_resize(Bbox &crop_info, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor) +{ + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{true, crop_info.x, crop_info.y, crop_info.w, crop_info.h}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, ai2d_pad_mode::constant, {114, 114, 114}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::padding_resize(FrameCHWSize ori_shape, std::vector &chw_vec, FrameSize resize_shape, runtime_tensor &ai2d_out_tensor, cv::Scalar padding) +{ + int ori_w = ori_shape.width; + int ori_h = ori_shape.height; + int width = resize_shape.width; + int height = resize_shape.height; + float ratiow = (float)width / ori_w; + float ratioh = (float)height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(width - new_w) / 2; + float dh = (float)(height - new_h) / 2; + int top = (int)(roundf(dh - 0.1)); + int bottom = (int)(roundf(dh + 0.1)); + int left = (int)(roundf(dw - 0.1)); + int right = (int)(roundf(dw - 0.1)); + + // create input + dims_t in_shape{1, ori_shape.channel, ori_h, ori_w}; + auto ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), chw_vec.data(), chw_vec.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{true, {{0, 0}, {0, 0}, {top, bottom}, {left, right}}, ai2d_pad_mode::constant, {padding[0], padding[1], padding[2]}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::padding_resize_one_side(FrameCHWSize ori_shape, std::vector &chw_vec, FrameSize resize_shape, runtime_tensor &ai2d_out_tensor, cv::Scalar padding) +{ + int ori_w = ori_shape.width; + int ori_h = ori_shape.height; + int width = resize_shape.width; + int height = resize_shape.height; + float ratiow = (float)width / ori_w; + float ratioh = (float)height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(width - new_w) / 2; + float dh = (float)(height - new_h) / 2; + int top = (int)(roundf(0)); + int bottom = (int)(roundf(dh * 2 + 0.1)); + int left = (int)(roundf(0)); + int right = (int)(roundf(dw * 2 - 0.1)); + + // create input + dims_t in_shape{1, ori_shape.channel, ori_h, ori_w}; + auto ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), chw_vec.data(), chw_vec.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{true, {{0, 0}, {0, 0}, {top, bottom}, {left, right}}, ai2d_pad_mode::constant, {padding[0], padding[1], padding[2]}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::padding_resize(FrameCHWSize ori_shape, FrameSize resize_shape, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor, const cv::Scalar padding) +{ + int ori_w = ori_shape.width; + int ori_h = ori_shape.height; + int width = resize_shape.width; + int height = resize_shape.height; + float ratiow = (float)width / ori_w; + float ratioh = (float)height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(width - new_w) / 2; + float dh = (float)(height - new_h) / 2; + int top = (int)(roundf(dh - 0.1)); + int bottom = (int)(roundf(dh + 0.1)); + int left = (int)(roundf(dw - 0.1)); + int right = (int)(roundf(dw - 0.1)); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{true, {{0, 0}, {0, 0}, {top, bottom}, {left, right}}, ai2d_pad_mode::constant, {padding[0], padding[1], padding[2]}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::padding_resize_one_side(FrameCHWSize ori_shape, FrameSize resize_shape, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor, const cv::Scalar padding) +{ + int ori_w = ori_shape.width; + int ori_h = ori_shape.height; + int width = resize_shape.width; + int height = resize_shape.height; + float ratiow = (float)width / ori_w; + float ratioh = (float)height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(width - new_w) / 2; + float dh = (float)(height - new_h) / 2; + int top = (int)(roundf(0)); + int bottom = (int)(roundf(dh * 2 + 0.1)); + int left = (int)(roundf(0)); + int right = (int)(roundf(dw * 2 - 0.1)); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{true, {{0, 0}, {0, 0}, {top, bottom}, {left, right}}, ai2d_pad_mode::constant, {padding[0], padding[1], padding[2]}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::affine(FrameCHWSize ori_shape, std::vector &ori_data, float *affine_matrix, runtime_tensor &ai2d_out_tensor) +{ + runtime_tensor ai2d_in_tensor; + // init ai2d in/out + dims_t in_shape{1, ori_shape.channel, ori_shape.height, ori_shape.width}; + ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + + // ai2d input + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), ori_data.data(), ori_data.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {10, 0}}, ai2d_pad_mode::constant, {255, 10, 5}}; + ai2d_resize_param_t resize_param{false, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{true, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {affine_matrix[0], affine_matrix[1], affine_matrix[2], affine_matrix[3], affine_matrix[4], affine_matrix[5]}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +// for video(只算一次即可) +void Utils::affine(float *affine_matrix, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor) +{ + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {10, 0}}, ai2d_pad_mode::constant, {255, 10, 5}}; + ai2d_resize_param_t resize_param{false, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{true, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {affine_matrix[0], affine_matrix[1], affine_matrix[2], affine_matrix[3], affine_matrix[4], affine_matrix[5]}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} \ No newline at end of file diff --git a/src/reference/ai_poc/face_alignment/utils.h b/src/reference/ai_poc/face_alignment/utils.h new file mode 100755 index 000000000..145e5630b --- /dev/null +++ b/src/reference/ai_poc/face_alignment/utils.h @@ -0,0 +1,307 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +// utils.h +#ifndef UTILS_H +#define UTILS_H + +#include +#include +#include +#include +#include +#include +#include + +using namespace nncase; +using namespace nncase::runtime; +using namespace nncase::runtime::k230; +using namespace nncase::F::k230; + +using cv::Mat; +using std::cout; +using std::endl; +using std::ifstream; +using std::vector; + +/** + * @brief 人脸检测框 + */ +typedef struct Bbox +{ + float x; // 人脸检测框的左顶点x坐标 + float y; // 人脸检测框的左顶点x坐标 + float w; + float h; +} Bbox; + +/** + * @brief 人脸五官点 + */ +typedef struct SparseLandmarks +{ + float points[10]; // 人脸五官点,依次是图片的左眼(x,y)、右眼(x,y),鼻子(x,y),左嘴角(x,y),右嘴角 +} SparseLandmarks; + +/** + * @brief 单张/帧图片大小 + */ +typedef struct FrameSize +{ + size_t width; // 宽 + size_t height; // 高 +} FrameSize; + +/** + * @brief 单张/帧图片大小 + */ +typedef struct FrameCHWSize +{ + size_t channel; // 通道 + size_t height; // 高 + size_t width; // 宽 +} FrameCHWSize; + +/** + * @brief AI Demo工具类 + * 封装了AI Demo常用的函数,包括二进制文件读取、文件保存、图片预处理等操作 + */ +class Utils +{ +public: + /** + * @brief 读取2进制文件 + * @param file_name 文件路径 + * @return 文件对应类型的数据 + */ + template + static vector read_binary_file(const char *file_name) + { + ifstream ifs(file_name, std::ios::binary); + ifs.seekg(0, ifs.end); + size_t len = ifs.tellg(); + vector vec(len / sizeof(T), 0); + ifs.seekg(0, ifs.beg); + ifs.read(reinterpret_cast(vec.data()), len); + ifs.close(); + return vec; + } + + /** + * @brief 打印数据 + * @param data 需打印数据对应指针 + * @param size 需打印数据大小 + * @return None + */ + template + static void dump(const T *data, size_t size) + { + for (size_t i = 0; i < size; i++) + { + cout << data[i] << " "; + } + cout << endl; + } + + // 静态成员函数不依赖于类的实例,可以直接通过类名调用 + /** + * @brief 将数据以2进制方式保存为文件 + * @param file_name 保存文件路径+文件名 + * @param data 需要保存的数据 + * @param size 需要保存的长度 + * @return None + */ + static void dump_binary_file(const char *file_name, char *data, const size_t size); + + /** + * @brief 将数据保存为灰度图片 + * @param file_name 保存图片路径+文件名 + * @param frame_size 保存图片的宽、高 + * @param data 需要保存的数据 + * @return None + */ + static void dump_gray_image(const char *file_name, const FrameSize &frame_size, unsigned char *data); + + /** + * @brief 将数据保存为彩色图片 + * @param file_name 保存图片路径+文件名 + * @param frame_size 保存图片的宽、高 + * @param data 需要保存的数据 + * @return None + */ + static void dump_color_image(const char *file_name, const FrameSize &frame_size, unsigned char *data); + + + /*************************for img process********************/ + /** + * @brief 对图片进行先padding后resize的处理 + * @param ori_img 原始图片 + * @param frame_size 需要resize图像的宽高 + * @param padding 需要padding的像素,默认是cv::Scalar(104, 117, 123),BGR + * @return 处理后图像 + */ + static cv::Mat padding_resize(const cv::Mat img, const FrameSize &frame_size, const cv::Scalar &padding = cv::Scalar(104, 117, 123)); + + /** + * @brief 对图片resize + * @param ori_img 原始图片 + * @param frame_size 需要resize图像的宽高 + * @param padding 需要padding的像素,默认是cv::Scalar(104, 117, 123),BGR + * @return 处理后图像 + */ + static cv::Mat resize(const cv::Mat ori_img, const FrameSize &frame_size); + + /** + * @brief 将图片从bgr转为rgb + * @param ori_img 原始图片 + * @return 处理后图像 + */ + static cv::Mat bgr_to_rgb(cv::Mat ori_img); + + /** + * @brief 将RGB或RGB图片从hwc转为chw + * @param ori_img 原始图片 + * @param chw_vec 转为chw后的数据 + * @return None + */ + static void hwc_to_chw(cv::Mat &ori_img, std::vector &chw_vec); // for rgb data + + /** + * @brief 将BGR图片从hwc转为chw + * @param ori_img 原始图片 + * @param chw_vec 转为chw后的数据 + * @return None + */ + static void bgr2rgb_and_hwc2chw(cv::Mat &ori_img, std::vector &chw_vec); + + /*************************for ai2d ori_img process********************/ + // resize + /** + * @brief resize函数,对chw数据进行resize + * @param ori_shape 原始数据chw + * @param chw_vec 原始数据 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + void resize(FrameCHWSize ori_shape, std::vector &chw_vec, runtime_tensor &ai2d_out_tensor); + + /** + * @brief resize函数 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + void resize(std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor); + + // crop resize + /** + * @brief resize函数,对chw数据进行crop & resize + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + static void crop_resize(FrameCHWSize ori_shape, std::vector &chw_vec, Bbox &crop_info, runtime_tensor &ai2d_out_tensor); + + /** + * @brief crop_resize函数,对chw数据进行crop & resize + * @param crop_info 需要crop的位置,x,y,w,h + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + static void crop_resize(Bbox &crop_info, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor); + + // padding resize + /** + * @brief padding_resize函数(上下左右padding),对chw数据进行padding & resize + * @param ori_shape 原始数据chw + * @param chw_vec 原始数据 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + static void padding_resize(FrameCHWSize ori_shape, std::vector &chw_vec, FrameSize resize_shape, runtime_tensor &ai2d_out_tensor, cv::Scalar padding); + + /** + * @brief padding_resize函数(右或下padding),对chw数据进行padding & resize + * @param ori_shape 原始数据chw + * @param chw_vec 原始数据 + * @param resize_shape resize之后的大小 + * @param ai2d_out_tensor ai2d输出 + * @param padding 填充值,用于resize时的等比例变换 + * @return None + */ + static void padding_resize_one_side(FrameCHWSize ori_shape, std::vector &chw_vec, FrameSize resize_shape, runtime_tensor &ai2d_out_tensor, cv::Scalar padding); + + /** + * @brief padding_resize函数(上下左右padding),对chw数据进行padding & resize + * @param ori_shape 原始数据chw + * @param resize_shape resize之后的大小 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @param padding 填充值,用于resize时的等比例变换 + * @return None + */ + static void padding_resize(FrameCHWSize ori_shape, FrameSize resize_shape, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor, cv::Scalar padding); + + /** + * @brief padding_resize函数(右或下padding),对chw数据进行padding & resize + * @param ori_shape 原始数据chw + * @param resize_shape resize之后的大小 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @param padding 填充值,用于resize时的等比例变换 + * @return None + */ + static void padding_resize_one_side(FrameCHWSize ori_shape, FrameSize resize_shape, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor, const cv::Scalar padding); + + // affine + /** + * @brief 仿射变换函数,对chw数据进行仿射变换(for imgae) + * @param ori_shape 原始数据chw大小 + * @param ori_data 原始数据 + * @param affine_matrix 仿射变换矩阵 + * @param ai2d_out_tensor 仿射变换后的数据 + * @return None + */ + static void affine(FrameCHWSize ori_shape, std::vector &ori_data, float *affine_matrix, runtime_tensor &ai2d_out_tensor); + + /** + * @brief 仿射变换函数,对chw数据进行仿射变换(for video) + * @param affine_matrix 仿射变换矩阵 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + static void affine(float *affine_matrix, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor); +}; + +#endif diff --git a/src/reference/ai_poc/face_alignment/vi_vo.h b/src/reference/ai_poc/face_alignment/vi_vo.h new file mode 100644 index 000000000..f0c1bccc5 --- /dev/null +++ b/src/reference/ai_poc/face_alignment/vi_vo.h @@ -0,0 +1,627 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include "mpi_sys_api.h" + +/* vicap */ +#include +#include +#include +#include +#include + +#include "k_module.h" +#include "k_type.h" +#include "k_vb_comm.h" +#include "k_video_comm.h" +#include "k_sys_comm.h" +#include "mpi_vb_api.h" +#include "mpi_vicap_api.h" +#include "mpi_isp_api.h" +#include "mpi_sys_api.h" +#include "k_vo_comm.h" +#include "mpi_vo_api.h" + +#include "vo_test_case.h" + +#include "k_connector_comm.h" +#include "mpi_connector_api.h" +#include "k_autoconf_comm.h" + + +#if defined(CONFIG_BOARD_K230_CANMV) +#define SENSOR_CHANNEL (3) // isp通道数 +#define SENSOR_HEIGHT (720) // isp高度,ai输入,竖屏 +#define SENSOR_WIDTH (1280) // isp宽度,ai输入,竖屏 +#define ISP_CHN0_WIDTH (1920)//(1920) +#define ISP_CHN0_HEIGHT (1080)//(1080) +#define vicap_install_osd (1) +#define osd_id K_VO_OSD3 +#define osd_width (1920) +#define osd_height (1080) +#else +#define SENSOR_CHANNEL (3) // isp通道数 +#define SENSOR_HEIGHT (1280) // isp高度,ai输入,竖屏 +#define SENSOR_WIDTH (720) // isp宽度,ai输入,竖屏 +#define ISP_CHN0_WIDTH (1088)//(1920) +#define ISP_CHN0_HEIGHT (1920)//(1080) +#define vicap_install_osd (1) +#define osd_id K_VO_OSD3 +#define osd_width (1080) +#define osd_height (1920) +#endif + + +k_vb_config config; +k_vicap_dev vicap_dev; +k_vicap_chn vicap_chn; +k_vicap_dev_attr dev_attr; +k_vicap_chn_attr chn_attr; +k_vicap_sensor_info sensor_info; +k_vicap_sensor_type sensor_type; +k_mpp_chn vicap_mpp_chn; +k_mpp_chn vo_mpp_chn; + +k_video_frame_info dump_info; + +k_vo_draw_frame vo_frame = (k_vo_draw_frame) { + 1, + 16, + 16, + 128, + 128, + 1 +}; + +static k_vb_blk_handle block; +k_u32 g_pool_id; + +int vo_creat_layer_test(k_vo_layer chn_id, layer_info *info) +{ + k_vo_video_layer_attr attr; + + // check layer + if ((chn_id >= K_MAX_VO_LAYER_NUM) || ((info->func & K_VO_SCALER_ENABLE) && (chn_id != K_VO_LAYER0)) + || ((info->func != 0) && (chn_id == K_VO_LAYER2))) + { + printf("input layer num failed \n"); + return -1 ; + } + + // check scaler + + // set offset + attr.display_rect = info->offset; + // set act + attr.img_size = info->act_size; + // sget size + info->size = info->act_size.height * info->act_size.width * 3 / 2; + //set pixel format + attr.pixel_format = info->format; + if (info->format != PIXEL_FORMAT_YVU_PLANAR_420) + { + printf("input pix format failed \n"); + return -1; + } + // set stride + attr.stride = (info->act_size.width / 8 - 1) + ((info->act_size.height - 1) << 16); + // set function + attr.func = info->func; + // set scaler attr + attr.scaler_attr = info->attr; + + // set video layer atrr + kd_mpi_vo_set_video_layer_attr(chn_id, &attr); + + // enable layer + kd_mpi_vo_enable_video_layer(chn_id); + + return 0; +} + +k_vb_blk_handle vo_insert_frame(k_video_frame_info *vf_info, void **pic_vaddr) +{ + k_u64 phys_addr = 0; + k_u32 *virt_addr; + k_vb_blk_handle handle; + k_s32 size; + + if (vf_info == NULL) + return K_FALSE; + + if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_ABGR_8888 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_ARGB_8888) + size = vf_info->v_frame.height * vf_info->v_frame.width * 4; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_RGB_565 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_BGR_565) + size = vf_info->v_frame.height * vf_info->v_frame.width * 2; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_ABGR_4444 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_ARGB_4444) + size = vf_info->v_frame.height * vf_info->v_frame.width * 2; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_RGB_888 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_BGR_888) + size = vf_info->v_frame.height * vf_info->v_frame.width * 3; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_ARGB_1555 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_ABGR_1555) + size = vf_info->v_frame.height * vf_info->v_frame.width * 2; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_YVU_PLANAR_420) + size = vf_info->v_frame.height * vf_info->v_frame.width * 3 / 2; + + size = size + 4096; // 强制4K ,后边得删了 + + printf("vb block size is %x \n", size); + + handle = kd_mpi_vb_get_block(g_pool_id, size, NULL); + if (handle == VB_INVALID_HANDLE) + { + printf("%s get vb block error\n", __func__); + return K_FAILED; + } + + phys_addr = kd_mpi_vb_handle_to_phyaddr(handle); + if (phys_addr == 0) + { + printf("%s get phys addr error\n", __func__); + return K_FAILED; + } + + virt_addr = (k_u32 *)kd_mpi_sys_mmap(phys_addr, size); + // virt_addr = (k_u32 *)kd_mpi_sys_mmap_cached(phys_addr, size); + + if (virt_addr == NULL) + { + printf("%s mmap error\n", __func__); + return K_FAILED; + } + + vf_info->mod_id = K_ID_VO; + vf_info->pool_id = g_pool_id; + vf_info->v_frame.phys_addr[0] = phys_addr; + if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_YVU_PLANAR_420) + vf_info->v_frame.phys_addr[1] = phys_addr + (vf_info->v_frame.height * vf_info->v_frame.stride[0]); + *pic_vaddr = virt_addr; + + printf("phys_addr is %lx g_pool_id is %d \n", phys_addr, g_pool_id); + + return handle; +} + +k_u32 vo_creat_osd_test(k_vo_osd osd, osd_info *info) +{ + k_vo_video_osd_attr attr; + + // set attr + attr.global_alptha = info->global_alptha; + + if (info->format == PIXEL_FORMAT_ABGR_8888 || info->format == PIXEL_FORMAT_ARGB_8888) + { + info->size = info->act_size.width * info->act_size.height * 4; + info->stride = info->act_size.width * 4 / 8; + } + else if (info->format == PIXEL_FORMAT_RGB_565 || info->format == PIXEL_FORMAT_BGR_565) + { + info->size = info->act_size.width * info->act_size.height * 2; + info->stride = info->act_size.width * 2 / 8; + } + else if (info->format == PIXEL_FORMAT_RGB_888 || info->format == PIXEL_FORMAT_BGR_888) + { + info->size = info->act_size.width * info->act_size.height * 3; + info->stride = info->act_size.width * 3 / 8; + } + else if(info->format == PIXEL_FORMAT_ARGB_4444 || info->format == PIXEL_FORMAT_ABGR_4444) + { + info->size = info->act_size.width * info->act_size.height * 2; + info->stride = info->act_size.width * 2 / 8; + } + else if(info->format == PIXEL_FORMAT_ARGB_1555 || info->format == PIXEL_FORMAT_ABGR_1555) + { + info->size = info->act_size.width * info->act_size.height * 2; + info->stride = info->act_size.width * 2 / 8; + } + else + { + printf("set osd pixel format failed \n"); + } + + attr.stride = info->stride; + attr.pixel_format = info->format; + attr.display_rect = info->offset; + attr.img_size = info->act_size; + kd_mpi_vo_set_video_osd_attr(osd, &attr); + + kd_mpi_vo_osd_enable(osd); + + return 0; +} + +void sample_vicap_install_osd(void) +{ + osd_info osd; + + osd.act_size.width = osd_width ; + osd.act_size.height = osd_height; + osd.offset.x = 0; + osd.offset.y = 0; + osd.global_alptha = 0xff; + // osd.global_alptha = 0x32; + osd.format = PIXEL_FORMAT_ARGB_8888;//PIXEL_FORMAT_ARGB_4444; //PIXEL_FORMAT_ARGB_1555;//PIXEL_FORMAT_ARGB_8888; + + vo_creat_osd_test(osd_id, &osd); +} + +void vo_osd_release_block(void) +{ + if(vicap_install_osd == 1) + { + kd_mpi_vo_osd_disable(osd_id); + kd_mpi_vb_release_block(block); + } + +} + +static k_s32 sample_connector_init(void) +{ + k_u32 ret = 0; + k_s32 connector_fd; +#if defined(CONFIG_BOARD_K230_CANMV) + k_connector_type connector_type = LT9611_MIPI_4LAN_1920X1080_30FPS;// HX8377_V2_MIPI_4LAN_1080X1920_30FPS; +#else + k_connector_type connector_type = HX8377_V2_MIPI_4LAN_1080X1920_30FPS; +#endif + k_connector_info connector_info; + + memset(&connector_info, 0, sizeof(k_connector_info)); + + //connector get sensor info + ret = kd_mpi_get_connector_info(connector_type, &connector_info); + if (ret) { + printf("sample_vicap, the sensor type not supported!\n"); + return ret; + } + + connector_fd = kd_mpi_connector_open(connector_info.connector_name); + if (connector_fd < 0) { + printf("%s, connector open failed.\n", __func__); + return K_ERR_VO_NOTREADY; + } + + // set connect power + kd_mpi_connector_power_set(connector_fd, K_TRUE); + // connector init + kd_mpi_connector_init(connector_fd, connector_info); + + return 0; +} + +static k_s32 vo_layer_vdss_bind_vo_config(void) +{ + layer_info info; + + k_vo_layer chn_id = K_VO_LAYER1; + + memset(&info, 0, sizeof(info)); + + sample_connector_init(); + + // config lyaer + info.act_size.width = ISP_CHN0_WIDTH;//ISP_CHN0_HEIGHT;//1080;//640;//1080; + info.act_size.height = ISP_CHN0_HEIGHT;//ISP_CHN0_WIDTH;//1920;//480;//1920; + info.format = PIXEL_FORMAT_YVU_PLANAR_420; + info.func = 0;//K_ROTATION_180;////K_ROTATION_90; + info.global_alptha = 0xff; + info.offset.x = 0;//(1080-w)/2, + info.offset.y = 0;//(1920-h)/2; + vo_creat_layer_test(chn_id, &info); + + if(vicap_install_osd == 1) + sample_vicap_install_osd(); + + //exit ; + return 0; +} + +static void sample_vicap_bind_vo(k_mpp_chn vicap_mpp_chn, k_mpp_chn vo_mpp_chn) +{ + k_s32 ret; + + ret = kd_mpi_sys_bind(&vicap_mpp_chn, &vo_mpp_chn); + if (ret) { + printf("kd_mpi_sys_unbind failed:0x%x\n", ret); + } + + return; +} + +static void sample_vicap_unbind_vo(k_mpp_chn vicap_mpp_chn, k_mpp_chn vo_mpp_chn) +{ + k_s32 ret; + + ret = kd_mpi_sys_unbind(&vicap_mpp_chn, &vo_mpp_chn); + if (ret) { + printf("kd_mpi_sys_unbind failed:0x%x\n", ret); + } + + return; +} + +int vivcap_start() +{ + k_s32 ret = 0; + + k_u32 pool_id; + k_vb_pool_config pool_config; + + printf("sample_vicap ...\n"); + +#if defined(CONFIG_BOARD_K230_CANMV) + sensor_type = OV_OV5647_MIPI_CSI0_1920X1080_30FPS_10BIT_LINEAR; + kd_mpi_vicap_set_mclk(VICAP_MCLK0, VICAP_PLL0_CLK_DIV4, 16, 1); +#else + sensor_type = IMX335_MIPI_2LANE_RAW12_2592X1944_30FPS_LINEAR; +#endif + vicap_dev = VICAP_DEV_ID_0; + + memset(&config, 0, sizeof(config)); + config.max_pool_cnt = 64; + //VB for YUV420SP output + config.comm_pool[0].blk_cnt = 5; + config.comm_pool[0].mode = VB_REMAP_MODE_NOCACHE; + config.comm_pool[0].blk_size = VICAP_ALIGN_UP((ISP_CHN0_WIDTH * ISP_CHN0_HEIGHT * 3 / 2), VICAP_ALIGN_1K); + + //VB for RGB888 output + config.comm_pool[1].blk_cnt = 5; + config.comm_pool[1].mode = VB_REMAP_MODE_NOCACHE; + config.comm_pool[1].blk_size = VICAP_ALIGN_UP((SENSOR_HEIGHT * SENSOR_WIDTH * 3 ), VICAP_ALIGN_1K); + + ret = kd_mpi_vb_set_config(&config); + if (ret) { + printf("vb_set_config failed ret:%d\n", ret); + return ret; + } + + k_vb_supplement_config supplement_config; + memset(&supplement_config, 0, sizeof(supplement_config)); + supplement_config.supplement_config |= VB_SUPPLEMENT_JPEG_MASK; + + ret = kd_mpi_vb_set_supplement_config(&supplement_config); + if (ret) { + printf("vb_set_supplement_config failed ret:%d\n", ret); + return ret; + } + + ret = kd_mpi_vb_init(); + if (ret) { + printf("vb_init failed ret:%d\n", ret); + return ret; + } + printf("sample_vicap ...kd_mpi_vicap_get_sensor_info\n"); + + // dwc_dsi_init(); + vo_layer_vdss_bind_vo_config(); + + if(vicap_install_osd == 1) + { + memset(&pool_config, 0, sizeof(pool_config)); + pool_config.blk_size = VICAP_ALIGN_UP((osd_width * osd_height * 4 * 2), VICAP_ALIGN_1K); + pool_config.blk_cnt = 4; + pool_config.mode = VB_REMAP_MODE_NOCACHE; + pool_id = kd_mpi_vb_create_pool(&pool_config); // osd0 - 3 argb 320 x 240 + g_pool_id = pool_id; + + printf("--------aa--------------g_pool_id is %d pool_id is %d \n",g_pool_id, pool_id); + } + + memset(&sensor_info, 0, sizeof(k_vicap_sensor_info)); + ret = kd_mpi_vicap_get_sensor_info(sensor_type, &sensor_info); + if (ret) { + printf("sample_vicap, the sensor type not supported!\n"); + return ret; + } + + memset(&dev_attr, 0, sizeof(k_vicap_dev_attr)); + dev_attr.acq_win.h_start = 0; + dev_attr.acq_win.v_start = 0; +#if defined (CONFIG_BOARD_K230_CANMV) + dev_attr.acq_win.width = ISP_CHN0_WIDTH; + dev_attr.acq_win.height = ISP_CHN0_HEIGHT; +#else + dev_attr.acq_win.width = 2592;//SENSOR_HEIGHT; + dev_attr.acq_win.height = 1944;//SENSOR_WIDTH; +#endif + dev_attr.mode = VICAP_WORK_ONLINE_MODE; + + dev_attr.pipe_ctrl.data = 0xFFFFFFFF; + dev_attr.pipe_ctrl.bits.af_enable = 0; + dev_attr.pipe_ctrl.bits.ahdr_enable = 0; + + + dev_attr.cpature_frame = 0; + memcpy(&dev_attr.sensor_info, &sensor_info, sizeof(k_vicap_sensor_info)); + + ret = kd_mpi_vicap_set_dev_attr(vicap_dev, dev_attr); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_set_dev_attr failed.\n"); + return ret; + } + + memset(&chn_attr, 0, sizeof(k_vicap_chn_attr)); + + //set chn0 output yuv420sp + chn_attr.out_win.h_start = 0; + chn_attr.out_win.v_start = 0; + chn_attr.out_win.width = ISP_CHN0_WIDTH; + chn_attr.out_win.height = ISP_CHN0_HEIGHT; + + +#if defined(CONFIG_BOARD_K230_CANMV) + chn_attr.crop_win = dev_attr.acq_win; +#else + // chn_attr.crop_win = dev_attr.acq_win; + chn_attr.crop_win.h_start = 768; + chn_attr.crop_win.v_start = 16; + chn_attr.crop_win.width = ISP_CHN0_WIDTH; + chn_attr.crop_win.height = ISP_CHN0_HEIGHT; +#endif + + chn_attr.scale_win = chn_attr.out_win; + chn_attr.crop_enable = K_FALSE; + chn_attr.scale_enable = K_FALSE; + // chn_attr.dw_enable = K_FALSE; + chn_attr.chn_enable = K_TRUE; + chn_attr.pix_format = PIXEL_FORMAT_YVU_PLANAR_420; + chn_attr.buffer_num = VICAP_MAX_FRAME_COUNT;//at least 3 buffers for isp + chn_attr.buffer_size = config.comm_pool[0].blk_size; + vicap_chn = VICAP_CHN_ID_0; + + printf("sample_vicap ...kd_mpi_vicap_set_chn_attr, buffer_size[%d]\n", chn_attr.buffer_size); + ret = kd_mpi_vicap_set_chn_attr(vicap_dev, vicap_chn, chn_attr); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_set_chn_attr failed.\n"); + return ret; + } + + //bind vicap chn 0 to vo + vicap_mpp_chn.mod_id = K_ID_VI; + vicap_mpp_chn.dev_id = vicap_dev; + vicap_mpp_chn.chn_id = vicap_chn; + + vo_mpp_chn.mod_id = K_ID_VO; + vo_mpp_chn.dev_id = K_VO_DISPLAY_DEV_ID; + vo_mpp_chn.chn_id = K_VO_DISPLAY_CHN_ID1; + + sample_vicap_bind_vo(vicap_mpp_chn, vo_mpp_chn); + printf("sample_vicap ...dwc_dsi_init\n"); + + //set chn1 output rgb888p + chn_attr.out_win.h_start = 0; + chn_attr.out_win.v_start = 0; + chn_attr.out_win.width = SENSOR_WIDTH ; + chn_attr.out_win.height = SENSOR_HEIGHT; + // chn_attr.crop_win = dev_attr.acq_win; + +#if defined(CONFIG_BOARD_K230_CANMV) + chn_attr.crop_win = dev_attr.acq_win; +#else + chn_attr.crop_win.h_start = 768; + chn_attr.crop_win.v_start = 16; + chn_attr.crop_win.width = ISP_CHN0_WIDTH; + chn_attr.crop_win.height = ISP_CHN0_HEIGHT; +#endif + + chn_attr.scale_win = chn_attr.out_win; + chn_attr.crop_enable = K_FALSE; + chn_attr.scale_enable = K_FALSE; + // chn_attr.dw_enable = K_FALSE; + chn_attr.chn_enable = K_TRUE; + chn_attr.pix_format = PIXEL_FORMAT_BGR_888_PLANAR; + chn_attr.buffer_num = VICAP_MAX_FRAME_COUNT;//at least 3 buffers for isp + chn_attr.buffer_size = config.comm_pool[1].blk_size; + + printf("sample_vicap ...kd_mpi_vicap_set_chn_attr, buffer_size[%d]\n", chn_attr.buffer_size); + ret = kd_mpi_vicap_set_chn_attr(vicap_dev, VICAP_CHN_ID_1, chn_attr); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_set_chn_attr failed.\n"); + return ret; + } + + printf("sample_vicap ...kd_mpi_vicap_init\n"); + ret = kd_mpi_vicap_init(vicap_dev); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_init failed.\n"); + // goto err_exit; + } + + printf("sample_vicap ...kd_mpi_vicap_start_stream\n"); + ret = kd_mpi_vicap_start_stream(vicap_dev); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_init failed.\n"); + // goto err_exit; + } + + return ret; +} + +int vivcap_stop() +{ + printf("sample_vicap ...kd_mpi_vicap_stop_stream\n"); + int ret = kd_mpi_vicap_stop_stream(vicap_dev); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_init failed.\n"); + return ret; + } + + ret = kd_mpi_vicap_deinit(vicap_dev); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_deinit failed.\n"); + return ret; + } + + kd_mpi_vo_disable_video_layer(K_VO_LAYER1); + + vicap_mpp_chn.mod_id = K_ID_VI; + vicap_mpp_chn.dev_id = vicap_dev; + vicap_mpp_chn.chn_id = vicap_chn; + + vo_mpp_chn.mod_id = K_ID_VO; + vo_mpp_chn.dev_id = K_VO_DISPLAY_DEV_ID; + vo_mpp_chn.chn_id = K_VO_DISPLAY_CHN_ID1; + + sample_vicap_unbind_vo(vicap_mpp_chn, vo_mpp_chn); + + /*Allow one frame time for the VO to release the VB block*/ + k_u32 display_ms = 1000 / 33; + usleep(1000 * display_ms); + + ret = kd_mpi_vb_exit(); + if (ret) { + printf("sample_vicap, kd_mpi_vb_exit failed.\n"); + return ret; + } + + return 0; +} + +void yuv_rotate_90(char *des, char *src,int width,int height) +{ + int n = 0; + int hw = width>>1; + int hh = height>>1; + int size = width * height; + int hsize = size>>2; + + int pos = 0; + + for(int i = width-1;i >= 0;i--) + { + pos = 0; + for(int j= 0;j < height;j++) + { + des[n++]= src[pos+i]; + pos += width; + } + } + +} \ No newline at end of file diff --git a/src/reference/ai_poc/face_detection/face_detection.h b/src/reference/ai_poc/face_detection/face_detection.h index 7057721c6..4d1a7c036 100755 --- a/src/reference/ai_poc/face_detection/face_detection.h +++ b/src/reference/ai_poc/face_detection/face_detection.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2022, Canaan Bright Sight Co., Ltd +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/src/reference/ai_poc/face_gender/face_detection.h b/src/reference/ai_poc/face_gender/face_detection.h index 4e4331600..385d98109 100755 --- a/src/reference/ai_poc/face_gender/face_detection.h +++ b/src/reference/ai_poc/face_gender/face_detection.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2022, Canaan Bright Sight Co., Ltd +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/src/reference/ai_poc/face_glasses/face_detection.h b/src/reference/ai_poc/face_glasses/face_detection.h index 4e4331600..385d98109 100755 --- a/src/reference/ai_poc/face_glasses/face_detection.h +++ b/src/reference/ai_poc/face_glasses/face_detection.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2022, Canaan Bright Sight Co., Ltd +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/src/reference/ai_poc/face_landmark/face_detection.h b/src/reference/ai_poc/face_landmark/face_detection.h index 4e4331600..385d98109 100755 --- a/src/reference/ai_poc/face_landmark/face_detection.h +++ b/src/reference/ai_poc/face_landmark/face_detection.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2022, Canaan Bright Sight Co., Ltd +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/src/reference/ai_poc/face_mask/face_detection.h b/src/reference/ai_poc/face_mask/face_detection.h index 4e4331600..385d98109 100755 --- a/src/reference/ai_poc/face_mask/face_detection.h +++ b/src/reference/ai_poc/face_mask/face_detection.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2022, Canaan Bright Sight Co., Ltd +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/src/reference/ai_poc/face_mesh/CMakeLists.txt b/src/reference/ai_poc/face_mesh/CMakeLists.txt new file mode 100644 index 000000000..6966a4728 --- /dev/null +++ b/src/reference/ai_poc/face_mesh/CMakeLists.txt @@ -0,0 +1,18 @@ +set(src main.cc utils.cc ai_base.cc face_detection.cc face_mesh.cc face_mesh_post.cc anchors_320.cc anchors_640.cc) +set(bin face_mesh.elf) + +include_directories(${PROJECT_SOURCE_DIR}) +include_directories(${nncase_sdk_root}/riscv64/rvvlib/include) +include_directories(${k230_sdk}/src/big/mpp/userapps/api/) +include_directories(${k230_sdk}/src/big/mpp/include) +include_directories(${k230_sdk}/src/big/mpp/include/comm) +include_directories(${k230_sdk}/src/big/mpp/userapps/sample/sample_vo) +link_directories(${nncase_sdk_root}/riscv64/rvvlib/) + +add_executable(${bin} ${src}) +target_link_libraries(${bin} -Wl,--start-group rvv Nncase.Runtime.Native nncase.rt_modules.k230 functional_k230 sys vicap vb cam_device cam_engine + hal oslayer ebase fpga isp_drv binder auto_ctrol common cam_caldb isi 3a buffer_management cameric_drv video_in virtual_hal start_engine cmd_buffer + switch cameric_reg_drv t_database_c t_mxml_c t_json_c t_common_c vo connector sensor atomic dma -Wl,--end-group) + +target_link_libraries(${bin} opencv_imgcodecs opencv_imgproc opencv_core zlib libjpeg-turbo libopenjp2 libpng libtiff libwebp csi_cv) +install(TARGETS ${bin} DESTINATION bin) \ No newline at end of file diff --git a/src/reference/ai_poc/face_mesh/README.md b/src/reference/ai_poc/face_mesh/README.md new file mode 100644 index 000000000..7a2192518 --- /dev/null +++ b/src/reference/ai_poc/face_mesh/README.md @@ -0,0 +1,28 @@ +# 1.简介 + +人脸检测采用了retina-face网络结构,backbone选取0.25-mobilenet,人脸对齐网络基于3DDFA(3D Dense Face Alignment)实现。使用该应用,可得到图像或视频中的每个人脸的mesh。 + +# 2.应用使用说明 + +## 2.1 使用帮助 + +``` +Usage: ./face_mesh +Options: + kmodel_det 人脸检测kmodel路径 + obj_thres 人脸检测阈值 + nms_thres 人脸检测nms阈值 + kmodel_mesh 人脸mesh kmodel路径 + kmodel_mesh_post 人脸mesh后处理kmodel路径 + input_mode 本地图片(图片路径)/ 摄像头(None) + debug_mode 是否需要调试,0、1、2分别表示不调试、简单调试、详细调试 + + #单图推理示例:(face_mesh_image.sh) +./face_mesh.elf face_detection_320.kmodel 0.6 0.2 face_alignment.kmodel face_alignment_post.kmodel 1024x768.jpg 1 + + #视频流推理:(face_mesh_isp.sh) +./face_mesh.elf face_detection_320.kmodel 0.6 0.2 face_alignment.kmodel face_alignment_post.kmodel None 0 +``` +## 2.2 效果展示 + +人脸mesh图 \ No newline at end of file diff --git a/src/reference/ai_poc/face_mesh/ai_base.cc b/src/reference/ai_poc/face_mesh/ai_base.cc new file mode 100644 index 000000000..2bc809473 --- /dev/null +++ b/src/reference/ai_poc/face_mesh/ai_base.cc @@ -0,0 +1,184 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "ai_base.h" + +#include +#include +#include +#include + +#include +#include "utils.h" + +using std::cout; +using std::endl; +using namespace nncase; +using namespace nncase::runtime::detail; + +AIBase::AIBase(const char *kmodel_file,const string model_name, const int debug_mode) : debug_mode_(debug_mode),model_name_(model_name) +{ + if (debug_mode > 1) + cout << "kmodel_file:" << kmodel_file << endl; + std::ifstream ifs(kmodel_file, std::ios::binary); + kmodel_interp_.load_model(ifs).expect("Invalid kmodel"); + set_input_init(); + set_output_init(); +} + +AIBase::~AIBase() +{ +} + +void AIBase::set_input_init() +{ + ScopedTiming st(model_name_ + " set_input init", debug_mode_); + int input_total_size = 0; + each_input_size_by_byte_.push_back(0); // 先补0,为之后做准备 + for (int i = 0; i < kmodel_interp_.inputs_size(); ++i) + { + auto desc = kmodel_interp_.input_desc(i); + auto shape = kmodel_interp_.input_shape(i); + auto tensor = host_runtime_tensor::create(desc.datatype, shape, hrt::pool_shared).expect("cannot create input tensor"); + kmodel_interp_.input_tensor(i, tensor).expect("cannot set input tensor"); + vector in_shape; + if (debug_mode_ > 1) + cout<<"input "<< std::to_string(i) <<" : "< 1) + cout << shape[j] << ","; + } + if (debug_mode_ > 1) + cout << endl; + input_shapes_.push_back(in_shape); + // DEFINE_TYPECODE(uint8, u8, 0x06) + // DEFINE_TYPECODE(float32, f32, 0x0B) + if (desc.datatype == dt_int8 || desc.datatype == dt_uint8) + { + input_total_size += dsize; + } + else if (desc.datatype == dt_int16 || desc.datatype == dt_uint16 || desc.datatype == dt_float16 || desc.datatype == dt_bfloat16) + { + input_total_size += (dsize * 2); + } + else if (desc.datatype == dt_int32 || desc.datatype == dt_uint32 || desc.datatype == dt_float32) + { + input_total_size += (dsize * 4); + } + else if(desc.datatype == dt_int64 || desc.datatype == dt_uint64 || desc.datatype == dt_float64) + { + input_total_size += (dsize * 8); + } + else + { + printf("input data type:%d",desc.datatype); + assert(("unsupported kmodel output data type", 0)); + } + each_input_size_by_byte_.push_back(input_total_size); + + } + each_input_size_by_byte_.push_back(input_total_size); // 最后一个保存总大小 +} + +runtime_tensor AIBase::get_input_tensor(size_t idx) +{ + return kmodel_interp_.input_tensor(idx).expect("cannot get input tensor"); +} + +void AIBase::set_output_init() +{ + ScopedTiming st(model_name_ + " set_output_init", debug_mode_); + each_output_size_by_byte_.clear(); + int output_total_size = 0; + each_output_size_by_byte_.push_back(0); + for (size_t i = 0; i < kmodel_interp_.outputs_size(); i++) + { + auto desc = kmodel_interp_.output_desc(i); + auto shape = kmodel_interp_.output_shape(i); + vector out_shape; + if (debug_mode_ > 1) + cout<<"output "< 1) + cout << shape[j] << ","; + } + if (debug_mode_ > 1) + cout << endl; + output_shapes_.push_back(out_shape); + if (desc.datatype == dt_int8 || desc.datatype == dt_uint8) + { + output_total_size += dsize; + } + else if (desc.datatype == dt_int16 || desc.datatype == dt_uint16 || desc.datatype == dt_float16 || desc.datatype == dt_bfloat16) + { + output_total_size += (dsize * 2); + } + else if (desc.datatype == dt_int32 || desc.datatype == dt_uint32 || desc.datatype == dt_float32) + { + output_total_size += (dsize * 4); + } + else if(desc.datatype == dt_int64 || desc.datatype == dt_uint64 || desc.datatype == dt_float64) + { + output_total_size += (dsize * 8); + } + else + { + printf("output data type:%d",desc.datatype); + assert(("unsupported kmodel output data type", 0)); + } + + each_output_size_by_byte_.push_back(output_total_size); + auto tensor = host_runtime_tensor::create(desc.datatype, shape, hrt::pool_shared).expect("cannot create output tensor"); + kmodel_interp_.output_tensor(i, tensor).expect("cannot set output tensor"); + } +} + +void AIBase::run() +{ + ScopedTiming st(model_name_ + " run", debug_mode_); + kmodel_interp_.run().expect("error occurred in running model"); +} + +void AIBase::get_output() +{ + ScopedTiming st(model_name_ + " get_output", debug_mode_); + p_outputs_.clear(); + for (int i = 0; i < kmodel_interp_.outputs_size(); i++) + { + auto out = kmodel_interp_.output_tensor(i).expect("cannot get output tensor"); + // auto mapped_buf = std::move(hrt::map(out, map_access_::map_read).unwrap()); + // float *p_out = reinterpret_cast(mapped_buf.buffer().data()); + auto buf = out.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_read).unwrap().buffer(); + float *p_out = reinterpret_cast(buf.data()); + p_outputs_.push_back(p_out); + } +} diff --git a/src/reference/ai_poc/face_mesh/ai_base.h b/src/reference/ai_poc/face_mesh/ai_base.h new file mode 100644 index 000000000..7486c9d35 --- /dev/null +++ b/src/reference/ai_poc/face_mesh/ai_base.h @@ -0,0 +1,104 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +// ai_base.h +#ifndef AI_BASE_H +#define AI_BASE_H + +#include +#include +#include + +#include +#include "scoped_timing.hpp" + +using std::string; +using std::vector; +using namespace nncase::runtime; + +/** + * @brief AI基类,封装nncase相关操作 + * 主要封装了nncase的加载、设置输入、运行、获取输出操作,后续开发demo只需要关注模型的前处理、后处理即可 + */ +class AIBase +{ +public: + /** + * @brief AI基类构造函数,加载kmodel,并初始化kmodel输入、输出 + * @param kmodel_file kmodel文件路径 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + AIBase(const char *kmodel_file,const string model_name, const int debug_mode = 1); + + /** + * @brief AI基类析构函数 + * @return None + */ + ~AIBase(); + + /** + * @brief 根据索引获取kmodel输入tensor + * @param idx 输入数据指针 + * @return None + */ + runtime_tensor get_input_tensor(size_t idx); + + /** + * @brief 推理kmodel + * @return None + */ + void run(); + + /** + * @brief 获取kmodel输出,结果保存在对应的类属性中 + * @return None + */ + void get_output(); + +protected: + string model_name_; // 模型名字 + int debug_mode_; // 调试模型,0(不打印),1(打印时间),2(打印所有) + vector p_outputs_; // kmodel输出对应的指针列表 + vector> input_shapes_; //{{N,C,H,W},{N,C,H,W}...} + vector> output_shapes_; //{{N,C,H,W},{N,C,H,W}...}} 或 {{N,C},{N,C}...}}等 + vector each_input_size_by_byte_; //{0,layer1_length,layer1_length+layer2_length,...} + vector each_output_size_by_byte_; //{0,layer1_length,layer1_length+layer2_length,...} +private: + /** + * @brief 首次初始化kmodel输入,并获取输入shape + * @return None + */ + void set_input_init(); + + /** + * @brief 首次初始化kmodel输出,并获取输出shape + * @return None + */ + void set_output_init(); + + interpreter kmodel_interp_; // kmodel解释器,从kmodel文件构建,负责模型的加载、输入输出设置和推理 + vector kmodel_vec_; // 通过读取kmodel文件得到整个kmodel数据,用于传给kmodel解释器加载kmodel +}; +#endif \ No newline at end of file diff --git a/src/reference/ai_poc/face_mesh/anchors_320.cc b/src/reference/ai_poc/face_mesh/anchors_320.cc new file mode 100644 index 000000000..f4d166abe --- /dev/null +++ b/src/reference/ai_poc/face_mesh/anchors_320.cc @@ -0,0 +1,25 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +float kAnchors320[4200][4] = {{0.012500,0.012500,0.050000,0.050000},{0.012500,0.012500,0.100000,0.100000},{0.037500,0.012500,0.050000,0.050000},{0.037500,0.012500,0.100000,0.100000},{0.062500,0.012500,0.050000,0.050000},{0.062500,0.012500,0.100000,0.100000},{0.087500,0.012500,0.050000,0.050000},{0.087500,0.012500,0.100000,0.100000},{0.112500,0.012500,0.050000,0.050000},{0.112500,0.012500,0.100000,0.100000},{0.137500,0.012500,0.050000,0.050000},{0.137500,0.012500,0.100000,0.100000},{0.162500,0.012500,0.050000,0.050000},{0.162500,0.012500,0.100000,0.100000},{0.187500,0.012500,0.050000,0.050000},{0.187500,0.012500,0.100000,0.100000},{0.212500,0.012500,0.050000,0.050000},{0.212500,0.012500,0.100000,0.100000},{0.237500,0.012500,0.050000,0.050000},{0.237500,0.012500,0.100000,0.100000},{0.262500,0.012500,0.050000,0.050000},{0.262500,0.012500,0.100000,0.100000},{0.287500,0.012500,0.050000,0.050000},{0.287500,0.012500,0.100000,0.100000},{0.312500,0.012500,0.050000,0.050000},{0.312500,0.012500,0.100000,0.100000},{0.337500,0.012500,0.050000,0.050000},{0.337500,0.012500,0.100000,0.100000},{0.362500,0.012500,0.050000,0.050000},{0.362500,0.012500,0.100000,0.100000},{0.387500,0.012500,0.050000,0.050000},{0.387500,0.012500,0.100000,0.100000},{0.412500,0.012500,0.050000,0.050000},{0.412500,0.012500,0.100000,0.100000},{0.437500,0.012500,0.050000,0.050000},{0.437500,0.012500,0.100000,0.100000},{0.462500,0.012500,0.050000,0.050000},{0.462500,0.012500,0.100000,0.100000},{0.487500,0.012500,0.050000,0.050000},{0.487500,0.012500,0.100000,0.100000},{0.512500,0.012500,0.050000,0.050000},{0.512500,0.012500,0.100000,0.100000},{0.537500,0.012500,0.050000,0.050000},{0.537500,0.012500,0.100000,0.100000},{0.562500,0.012500,0.050000,0.050000},{0.562500,0.012500,0.100000,0.100000},{0.587500,0.012500,0.050000,0.050000},{0.587500,0.012500,0.100000,0.100000},{0.612500,0.012500,0.050000,0.050000},{0.612500,0.012500,0.100000,0.100000},{0.637500,0.012500,0.050000,0.050000},{0.637500,0.012500,0.100000,0.100000},{0.662500,0.012500,0.050000,0.050000},{0.662500,0.012500,0.100000,0.100000},{0.687500,0.012500,0.050000,0.050000},{0.687500,0.012500,0.100000,0.100000},{0.712500,0.012500,0.050000,0.050000},{0.712500,0.012500,0.100000,0.100000},{0.737500,0.012500,0.050000,0.050000},{0.737500,0.012500,0.100000,0.100000},{0.762500,0.012500,0.050000,0.050000},{0.762500,0.012500,0.100000,0.100000},{0.787500,0.012500,0.050000,0.050000},{0.787500,0.012500,0.100000,0.100000},{0.812500,0.012500,0.050000,0.050000},{0.812500,0.012500,0.100000,0.100000},{0.837500,0.012500,0.050000,0.050000},{0.837500,0.012500,0.100000,0.100000},{0.862500,0.012500,0.050000,0.050000},{0.862500,0.012500,0.100000,0.100000},{0.887500,0.012500,0.050000,0.050000},{0.887500,0.012500,0.100000,0.100000},{0.912500,0.012500,0.050000,0.050000},{0.912500,0.012500,0.100000,0.100000},{0.937500,0.012500,0.050000,0.050000},{0.937500,0.012500,0.100000,0.100000},{0.962500,0.012500,0.050000,0.050000},{0.962500,0.012500,0.100000,0.100000},{0.987500,0.012500,0.050000,0.050000},{0.987500,0.012500,0.100000,0.100000},{0.012500,0.037500,0.050000,0.050000},{0.012500,0.037500,0.100000,0.100000},{0.037500,0.037500,0.050000,0.050000},{0.037500,0.037500,0.100000,0.100000},{0.062500,0.037500,0.050000,0.050000},{0.062500,0.037500,0.100000,0.100000},{0.087500,0.037500,0.050000,0.050000},{0.087500,0.037500,0.100000,0.100000},{0.112500,0.037500,0.050000,0.050000},{0.112500,0.037500,0.100000,0.100000},{0.137500,0.037500,0.050000,0.050000},{0.137500,0.037500,0.100000,0.100000},{0.162500,0.037500,0.050000,0.050000},{0.162500,0.037500,0.100000,0.100000},{0.187500,0.037500,0.050000,0.050000},{0.187500,0.037500,0.100000,0.100000},{0.212500,0.037500,0.050000,0.050000},{0.212500,0.037500,0.100000,0.100000},{0.237500,0.037500,0.050000,0.050000},{0.237500,0.037500,0.100000,0.100000},{0.262500,0.037500,0.050000,0.050000},{0.262500,0.037500,0.100000,0.100000},{0.287500,0.037500,0.050000,0.050000},{0.287500,0.037500,0.100000,0.100000},{0.312500,0.037500,0.050000,0.050000},{0.312500,0.037500,0.100000,0.100000},{0.337500,0.037500,0.050000,0.050000},{0.337500,0.037500,0.100000,0.100000},{0.362500,0.037500,0.050000,0.050000},{0.362500,0.037500,0.100000,0.100000},{0.387500,0.037500,0.050000,0.050000},{0.387500,0.037500,0.100000,0.100000},{0.412500,0.037500,0.050000,0.050000},{0.412500,0.037500,0.100000,0.100000},{0.437500,0.037500,0.050000,0.050000},{0.437500,0.037500,0.100000,0.100000},{0.462500,0.037500,0.050000,0.050000},{0.462500,0.037500,0.100000,0.100000},{0.487500,0.037500,0.050000,0.050000},{0.487500,0.037500,0.100000,0.100000},{0.512500,0.037500,0.050000,0.050000},{0.512500,0.037500,0.100000,0.100000},{0.537500,0.037500,0.050000,0.050000},{0.537500,0.037500,0.100000,0.100000},{0.562500,0.037500,0.050000,0.050000},{0.562500,0.037500,0.100000,0.100000},{0.587500,0.037500,0.050000,0.050000},{0.587500,0.037500,0.100000,0.100000},{0.612500,0.037500,0.050000,0.050000},{0.612500,0.037500,0.100000,0.100000},{0.637500,0.037500,0.050000,0.050000},{0.637500,0.037500,0.100000,0.100000},{0.662500,0.037500,0.050000,0.050000},{0.662500,0.037500,0.100000,0.100000},{0.687500,0.037500,0.050000,0.050000},{0.687500,0.037500,0.100000,0.100000},{0.712500,0.037500,0.050000,0.050000},{0.712500,0.037500,0.100000,0.100000},{0.737500,0.037500,0.050000,0.050000},{0.737500,0.037500,0.100000,0.100000},{0.762500,0.037500,0.050000,0.050000},{0.762500,0.037500,0.100000,0.100000},{0.787500,0.037500,0.050000,0.050000},{0.787500,0.037500,0.100000,0.100000},{0.812500,0.037500,0.050000,0.050000},{0.812500,0.037500,0.100000,0.100000},{0.837500,0.037500,0.050000,0.050000},{0.837500,0.037500,0.100000,0.100000},{0.862500,0.037500,0.050000,0.050000},{0.862500,0.037500,0.100000,0.100000},{0.887500,0.037500,0.050000,0.050000},{0.887500,0.037500,0.100000,0.100000},{0.912500,0.037500,0.050000,0.050000},{0.912500,0.037500,0.100000,0.100000},{0.937500,0.037500,0.050000,0.050000},{0.937500,0.037500,0.100000,0.100000},{0.962500,0.037500,0.050000,0.050000},{0.962500,0.037500,0.100000,0.100000},{0.987500,0.037500,0.050000,0.050000},{0.987500,0.037500,0.100000,0.100000},{0.012500,0.062500,0.050000,0.050000},{0.012500,0.062500,0.100000,0.100000},{0.037500,0.062500,0.050000,0.050000},{0.037500,0.062500,0.100000,0.100000},{0.062500,0.062500,0.050000,0.050000},{0.062500,0.062500,0.100000,0.100000},{0.087500,0.062500,0.050000,0.050000},{0.087500,0.062500,0.100000,0.100000},{0.112500,0.062500,0.050000,0.050000},{0.112500,0.062500,0.100000,0.100000},{0.137500,0.062500,0.050000,0.050000},{0.137500,0.062500,0.100000,0.100000},{0.162500,0.062500,0.050000,0.050000},{0.162500,0.062500,0.100000,0.100000},{0.187500,0.062500,0.050000,0.050000},{0.187500,0.062500,0.100000,0.100000},{0.212500,0.062500,0.050000,0.050000},{0.212500,0.062500,0.100000,0.100000},{0.237500,0.062500,0.050000,0.050000},{0.237500,0.062500,0.100000,0.100000},{0.262500,0.062500,0.050000,0.050000},{0.262500,0.062500,0.100000,0.100000},{0.287500,0.062500,0.050000,0.050000},{0.287500,0.062500,0.100000,0.100000},{0.312500,0.062500,0.050000,0.050000},{0.312500,0.062500,0.100000,0.100000},{0.337500,0.062500,0.050000,0.050000},{0.337500,0.062500,0.100000,0.100000},{0.362500,0.062500,0.050000,0.050000},{0.362500,0.062500,0.100000,0.100000},{0.387500,0.062500,0.050000,0.050000},{0.387500,0.062500,0.100000,0.100000},{0.412500,0.062500,0.050000,0.050000},{0.412500,0.062500,0.100000,0.100000},{0.437500,0.062500,0.050000,0.050000},{0.437500,0.062500,0.100000,0.100000},{0.462500,0.062500,0.050000,0.050000},{0.462500,0.062500,0.100000,0.100000},{0.487500,0.062500,0.050000,0.050000},{0.487500,0.062500,0.100000,0.100000},{0.512500,0.062500,0.050000,0.050000},{0.512500,0.062500,0.100000,0.100000},{0.537500,0.062500,0.050000,0.050000},{0.537500,0.062500,0.100000,0.100000},{0.562500,0.062500,0.050000,0.050000},{0.562500,0.062500,0.100000,0.100000},{0.587500,0.062500,0.050000,0.050000},{0.587500,0.062500,0.100000,0.100000},{0.612500,0.062500,0.050000,0.050000},{0.612500,0.062500,0.100000,0.100000},{0.637500,0.062500,0.050000,0.050000},{0.637500,0.062500,0.100000,0.100000},{0.662500,0.062500,0.050000,0.050000},{0.662500,0.062500,0.100000,0.100000},{0.687500,0.062500,0.050000,0.050000},{0.687500,0.062500,0.100000,0.100000},{0.712500,0.062500,0.050000,0.050000},{0.712500,0.062500,0.100000,0.100000},{0.737500,0.062500,0.050000,0.050000},{0.737500,0.062500,0.100000,0.100000},{0.762500,0.062500,0.050000,0.050000},{0.762500,0.062500,0.100000,0.100000},{0.787500,0.062500,0.050000,0.050000},{0.787500,0.062500,0.100000,0.100000},{0.812500,0.062500,0.050000,0.050000},{0.812500,0.062500,0.100000,0.100000},{0.837500,0.062500,0.050000,0.050000},{0.837500,0.062500,0.100000,0.100000},{0.862500,0.062500,0.050000,0.050000},{0.862500,0.062500,0.100000,0.100000},{0.887500,0.062500,0.050000,0.050000},{0.887500,0.062500,0.100000,0.100000},{0.912500,0.062500,0.050000,0.050000},{0.912500,0.062500,0.100000,0.100000},{0.937500,0.062500,0.050000,0.050000},{0.937500,0.062500,0.100000,0.100000},{0.962500,0.062500,0.050000,0.050000},{0.962500,0.062500,0.100000,0.100000},{0.987500,0.062500,0.050000,0.050000},{0.987500,0.062500,0.100000,0.100000},{0.012500,0.087500,0.050000,0.050000},{0.012500,0.087500,0.100000,0.100000},{0.037500,0.087500,0.050000,0.050000},{0.037500,0.087500,0.100000,0.100000},{0.062500,0.087500,0.050000,0.050000},{0.062500,0.087500,0.100000,0.100000},{0.087500,0.087500,0.050000,0.050000},{0.087500,0.087500,0.100000,0.100000},{0.112500,0.087500,0.050000,0.050000},{0.112500,0.087500,0.100000,0.100000},{0.137500,0.087500,0.050000,0.050000},{0.137500,0.087500,0.100000,0.100000},{0.162500,0.087500,0.050000,0.050000},{0.162500,0.087500,0.100000,0.100000},{0.187500,0.087500,0.050000,0.050000},{0.187500,0.087500,0.100000,0.100000},{0.212500,0.087500,0.050000,0.050000},{0.212500,0.087500,0.100000,0.100000},{0.237500,0.087500,0.050000,0.050000},{0.237500,0.087500,0.100000,0.100000},{0.262500,0.087500,0.050000,0.050000},{0.262500,0.087500,0.100000,0.100000},{0.287500,0.087500,0.050000,0.050000},{0.287500,0.087500,0.100000,0.100000},{0.312500,0.087500,0.050000,0.050000},{0.312500,0.087500,0.100000,0.100000},{0.337500,0.087500,0.050000,0.050000},{0.337500,0.087500,0.100000,0.100000},{0.362500,0.087500,0.050000,0.050000},{0.362500,0.087500,0.100000,0.100000},{0.387500,0.087500,0.050000,0.050000},{0.387500,0.087500,0.100000,0.100000},{0.412500,0.087500,0.050000,0.050000},{0.412500,0.087500,0.100000,0.100000},{0.437500,0.087500,0.050000,0.050000},{0.437500,0.087500,0.100000,0.100000},{0.462500,0.087500,0.050000,0.050000},{0.462500,0.087500,0.100000,0.100000},{0.487500,0.087500,0.050000,0.050000},{0.487500,0.087500,0.100000,0.100000},{0.512500,0.087500,0.050000,0.050000},{0.512500,0.087500,0.100000,0.100000},{0.537500,0.087500,0.050000,0.050000},{0.537500,0.087500,0.100000,0.100000},{0.562500,0.087500,0.050000,0.050000},{0.562500,0.087500,0.100000,0.100000},{0.587500,0.087500,0.050000,0.050000},{0.587500,0.087500,0.100000,0.100000},{0.612500,0.087500,0.050000,0.050000},{0.612500,0.087500,0.100000,0.100000},{0.637500,0.087500,0.050000,0.050000},{0.637500,0.087500,0.100000,0.100000},{0.662500,0.087500,0.050000,0.050000},{0.662500,0.087500,0.100000,0.100000},{0.687500,0.087500,0.050000,0.050000},{0.687500,0.087500,0.100000,0.100000},{0.712500,0.087500,0.050000,0.050000},{0.712500,0.087500,0.100000,0.100000},{0.737500,0.087500,0.050000,0.050000},{0.737500,0.087500,0.100000,0.100000},{0.762500,0.087500,0.050000,0.050000},{0.762500,0.087500,0.100000,0.100000},{0.787500,0.087500,0.050000,0.050000},{0.787500,0.087500,0.100000,0.100000},{0.812500,0.087500,0.050000,0.050000},{0.812500,0.087500,0.100000,0.100000},{0.837500,0.087500,0.050000,0.050000},{0.837500,0.087500,0.100000,0.100000},{0.862500,0.087500,0.050000,0.050000},{0.862500,0.087500,0.100000,0.100000},{0.887500,0.087500,0.050000,0.050000},{0.887500,0.087500,0.100000,0.100000},{0.912500,0.087500,0.050000,0.050000},{0.912500,0.087500,0.100000,0.100000},{0.937500,0.087500,0.050000,0.050000},{0.937500,0.087500,0.100000,0.100000},{0.962500,0.087500,0.050000,0.050000},{0.962500,0.087500,0.100000,0.100000},{0.987500,0.087500,0.050000,0.050000},{0.987500,0.087500,0.100000,0.100000},{0.012500,0.112500,0.050000,0.050000},{0.012500,0.112500,0.100000,0.100000},{0.037500,0.112500,0.050000,0.050000},{0.037500,0.112500,0.100000,0.100000},{0.062500,0.112500,0.050000,0.050000},{0.062500,0.112500,0.100000,0.100000},{0.087500,0.112500,0.050000,0.050000},{0.087500,0.112500,0.100000,0.100000},{0.112500,0.112500,0.050000,0.050000},{0.112500,0.112500,0.100000,0.100000},{0.137500,0.112500,0.050000,0.050000},{0.137500,0.112500,0.100000,0.100000},{0.162500,0.112500,0.050000,0.050000},{0.162500,0.112500,0.100000,0.100000},{0.187500,0.112500,0.050000,0.050000},{0.187500,0.112500,0.100000,0.100000},{0.212500,0.112500,0.050000,0.050000},{0.212500,0.112500,0.100000,0.100000},{0.237500,0.112500,0.050000,0.050000},{0.237500,0.112500,0.100000,0.100000},{0.262500,0.112500,0.050000,0.050000},{0.262500,0.112500,0.100000,0.100000},{0.287500,0.112500,0.050000,0.050000},{0.287500,0.112500,0.100000,0.100000},{0.312500,0.112500,0.050000,0.050000},{0.312500,0.112500,0.100000,0.100000},{0.337500,0.112500,0.050000,0.050000},{0.337500,0.112500,0.100000,0.100000},{0.362500,0.112500,0.050000,0.050000},{0.362500,0.112500,0.100000,0.100000},{0.387500,0.112500,0.050000,0.050000},{0.387500,0.112500,0.100000,0.100000},{0.412500,0.112500,0.050000,0.050000},{0.412500,0.112500,0.100000,0.100000},{0.437500,0.112500,0.050000,0.050000},{0.437500,0.112500,0.100000,0.100000},{0.462500,0.112500,0.050000,0.050000},{0.462500,0.112500,0.100000,0.100000},{0.487500,0.112500,0.050000,0.050000},{0.487500,0.112500,0.100000,0.100000},{0.512500,0.112500,0.050000,0.050000},{0.512500,0.112500,0.100000,0.100000},{0.537500,0.112500,0.050000,0.050000},{0.537500,0.112500,0.100000,0.100000},{0.562500,0.112500,0.050000,0.050000},{0.562500,0.112500,0.100000,0.100000},{0.587500,0.112500,0.050000,0.050000},{0.587500,0.112500,0.100000,0.100000},{0.612500,0.112500,0.050000,0.050000},{0.612500,0.112500,0.100000,0.100000},{0.637500,0.112500,0.050000,0.050000},{0.637500,0.112500,0.100000,0.100000},{0.662500,0.112500,0.050000,0.050000},{0.662500,0.112500,0.100000,0.100000},{0.687500,0.112500,0.050000,0.050000},{0.687500,0.112500,0.100000,0.100000},{0.712500,0.112500,0.050000,0.050000},{0.712500,0.112500,0.100000,0.100000},{0.737500,0.112500,0.050000,0.050000},{0.737500,0.112500,0.100000,0.100000},{0.762500,0.112500,0.050000,0.050000},{0.762500,0.112500,0.100000,0.100000},{0.787500,0.112500,0.050000,0.050000},{0.787500,0.112500,0.100000,0.100000},{0.812500,0.112500,0.050000,0.050000},{0.812500,0.112500,0.100000,0.100000},{0.837500,0.112500,0.050000,0.050000},{0.837500,0.112500,0.100000,0.100000},{0.862500,0.112500,0.050000,0.050000},{0.862500,0.112500,0.100000,0.100000},{0.887500,0.112500,0.050000,0.050000},{0.887500,0.112500,0.100000,0.100000},{0.912500,0.112500,0.050000,0.050000},{0.912500,0.112500,0.100000,0.100000},{0.937500,0.112500,0.050000,0.050000},{0.937500,0.112500,0.100000,0.100000},{0.962500,0.112500,0.050000,0.050000},{0.962500,0.112500,0.100000,0.100000},{0.987500,0.112500,0.050000,0.050000},{0.987500,0.112500,0.100000,0.100000},{0.012500,0.137500,0.050000,0.050000},{0.012500,0.137500,0.100000,0.100000},{0.037500,0.137500,0.050000,0.050000},{0.037500,0.137500,0.100000,0.100000},{0.062500,0.137500,0.050000,0.050000},{0.062500,0.137500,0.100000,0.100000},{0.087500,0.137500,0.050000,0.050000},{0.087500,0.137500,0.100000,0.100000},{0.112500,0.137500,0.050000,0.050000},{0.112500,0.137500,0.100000,0.100000},{0.137500,0.137500,0.050000,0.050000},{0.137500,0.137500,0.100000,0.100000},{0.162500,0.137500,0.050000,0.050000},{0.162500,0.137500,0.100000,0.100000},{0.187500,0.137500,0.050000,0.050000},{0.187500,0.137500,0.100000,0.100000},{0.212500,0.137500,0.050000,0.050000},{0.212500,0.137500,0.100000,0.100000},{0.237500,0.137500,0.050000,0.050000},{0.237500,0.137500,0.100000,0.100000},{0.262500,0.137500,0.050000,0.050000},{0.262500,0.137500,0.100000,0.100000},{0.287500,0.137500,0.050000,0.050000},{0.287500,0.137500,0.100000,0.100000},{0.312500,0.137500,0.050000,0.050000},{0.312500,0.137500,0.100000,0.100000},{0.337500,0.137500,0.050000,0.050000},{0.337500,0.137500,0.100000,0.100000},{0.362500,0.137500,0.050000,0.050000},{0.362500,0.137500,0.100000,0.100000},{0.387500,0.137500,0.050000,0.050000},{0.387500,0.137500,0.100000,0.100000},{0.412500,0.137500,0.050000,0.050000},{0.412500,0.137500,0.100000,0.100000},{0.437500,0.137500,0.050000,0.050000},{0.437500,0.137500,0.100000,0.100000},{0.462500,0.137500,0.050000,0.050000},{0.462500,0.137500,0.100000,0.100000},{0.487500,0.137500,0.050000,0.050000},{0.487500,0.137500,0.100000,0.100000},{0.512500,0.137500,0.050000,0.050000},{0.512500,0.137500,0.100000,0.100000},{0.537500,0.137500,0.050000,0.050000},{0.537500,0.137500,0.100000,0.100000},{0.562500,0.137500,0.050000,0.050000},{0.562500,0.137500,0.100000,0.100000},{0.587500,0.137500,0.050000,0.050000},{0.587500,0.137500,0.100000,0.100000},{0.612500,0.137500,0.050000,0.050000},{0.612500,0.137500,0.100000,0.100000},{0.637500,0.137500,0.050000,0.050000},{0.637500,0.137500,0.100000,0.100000},{0.662500,0.137500,0.050000,0.050000},{0.662500,0.137500,0.100000,0.100000},{0.687500,0.137500,0.050000,0.050000},{0.687500,0.137500,0.100000,0.100000},{0.712500,0.137500,0.050000,0.050000},{0.712500,0.137500,0.100000,0.100000},{0.737500,0.137500,0.050000,0.050000},{0.737500,0.137500,0.100000,0.100000},{0.762500,0.137500,0.050000,0.050000},{0.762500,0.137500,0.100000,0.100000},{0.787500,0.137500,0.050000,0.050000},{0.787500,0.137500,0.100000,0.100000},{0.812500,0.137500,0.050000,0.050000},{0.812500,0.137500,0.100000,0.100000},{0.837500,0.137500,0.050000,0.050000},{0.837500,0.137500,0.100000,0.100000},{0.862500,0.137500,0.050000,0.050000},{0.862500,0.137500,0.100000,0.100000},{0.887500,0.137500,0.050000,0.050000},{0.887500,0.137500,0.100000,0.100000},{0.912500,0.137500,0.050000,0.050000},{0.912500,0.137500,0.100000,0.100000},{0.937500,0.137500,0.050000,0.050000},{0.937500,0.137500,0.100000,0.100000},{0.962500,0.137500,0.050000,0.050000},{0.962500,0.137500,0.100000,0.100000},{0.987500,0.137500,0.050000,0.050000},{0.987500,0.137500,0.100000,0.100000},{0.012500,0.162500,0.050000,0.050000},{0.012500,0.162500,0.100000,0.100000},{0.037500,0.162500,0.050000,0.050000},{0.037500,0.162500,0.100000,0.100000},{0.062500,0.162500,0.050000,0.050000},{0.062500,0.162500,0.100000,0.100000},{0.087500,0.162500,0.050000,0.050000},{0.087500,0.162500,0.100000,0.100000},{0.112500,0.162500,0.050000,0.050000},{0.112500,0.162500,0.100000,0.100000},{0.137500,0.162500,0.050000,0.050000},{0.137500,0.162500,0.100000,0.100000},{0.162500,0.162500,0.050000,0.050000},{0.162500,0.162500,0.100000,0.100000},{0.187500,0.162500,0.050000,0.050000},{0.187500,0.162500,0.100000,0.100000},{0.212500,0.162500,0.050000,0.050000},{0.212500,0.162500,0.100000,0.100000},{0.237500,0.162500,0.050000,0.050000},{0.237500,0.162500,0.100000,0.100000},{0.262500,0.162500,0.050000,0.050000},{0.262500,0.162500,0.100000,0.100000},{0.287500,0.162500,0.050000,0.050000},{0.287500,0.162500,0.100000,0.100000},{0.312500,0.162500,0.050000,0.050000},{0.312500,0.162500,0.100000,0.100000},{0.337500,0.162500,0.050000,0.050000},{0.337500,0.162500,0.100000,0.100000},{0.362500,0.162500,0.050000,0.050000},{0.362500,0.162500,0.100000,0.100000},{0.387500,0.162500,0.050000,0.050000},{0.387500,0.162500,0.100000,0.100000},{0.412500,0.162500,0.050000,0.050000},{0.412500,0.162500,0.100000,0.100000},{0.437500,0.162500,0.050000,0.050000},{0.437500,0.162500,0.100000,0.100000},{0.462500,0.162500,0.050000,0.050000},{0.462500,0.162500,0.100000,0.100000},{0.487500,0.162500,0.050000,0.050000},{0.487500,0.162500,0.100000,0.100000},{0.512500,0.162500,0.050000,0.050000},{0.512500,0.162500,0.100000,0.100000},{0.537500,0.162500,0.050000,0.050000},{0.537500,0.162500,0.100000,0.100000},{0.562500,0.162500,0.050000,0.050000},{0.562500,0.162500,0.100000,0.100000},{0.587500,0.162500,0.050000,0.050000},{0.587500,0.162500,0.100000,0.100000},{0.612500,0.162500,0.050000,0.050000},{0.612500,0.162500,0.100000,0.100000},{0.637500,0.162500,0.050000,0.050000},{0.637500,0.162500,0.100000,0.100000},{0.662500,0.162500,0.050000,0.050000},{0.662500,0.162500,0.100000,0.100000},{0.687500,0.162500,0.050000,0.050000},{0.687500,0.162500,0.100000,0.100000},{0.712500,0.162500,0.050000,0.050000},{0.712500,0.162500,0.100000,0.100000},{0.737500,0.162500,0.050000,0.050000},{0.737500,0.162500,0.100000,0.100000},{0.762500,0.162500,0.050000,0.050000},{0.762500,0.162500,0.100000,0.100000},{0.787500,0.162500,0.050000,0.050000},{0.787500,0.162500,0.100000,0.100000},{0.812500,0.162500,0.050000,0.050000},{0.812500,0.162500,0.100000,0.100000},{0.837500,0.162500,0.050000,0.050000},{0.837500,0.162500,0.100000,0.100000},{0.862500,0.162500,0.050000,0.050000},{0.862500,0.162500,0.100000,0.100000},{0.887500,0.162500,0.050000,0.050000},{0.887500,0.162500,0.100000,0.100000},{0.912500,0.162500,0.050000,0.050000},{0.912500,0.162500,0.100000,0.100000},{0.937500,0.162500,0.050000,0.050000},{0.937500,0.162500,0.100000,0.100000},{0.962500,0.162500,0.050000,0.050000},{0.962500,0.162500,0.100000,0.100000},{0.987500,0.162500,0.050000,0.050000},{0.987500,0.162500,0.100000,0.100000},{0.012500,0.187500,0.050000,0.050000},{0.012500,0.187500,0.100000,0.100000},{0.037500,0.187500,0.050000,0.050000},{0.037500,0.187500,0.100000,0.100000},{0.062500,0.187500,0.050000,0.050000},{0.062500,0.187500,0.100000,0.100000},{0.087500,0.187500,0.050000,0.050000},{0.087500,0.187500,0.100000,0.100000},{0.112500,0.187500,0.050000,0.050000},{0.112500,0.187500,0.100000,0.100000},{0.137500,0.187500,0.050000,0.050000},{0.137500,0.187500,0.100000,0.100000},{0.162500,0.187500,0.050000,0.050000},{0.162500,0.187500,0.100000,0.100000},{0.187500,0.187500,0.050000,0.050000},{0.187500,0.187500,0.100000,0.100000},{0.212500,0.187500,0.050000,0.050000},{0.212500,0.187500,0.100000,0.100000},{0.237500,0.187500,0.050000,0.050000},{0.237500,0.187500,0.100000,0.100000},{0.262500,0.187500,0.050000,0.050000},{0.262500,0.187500,0.100000,0.100000},{0.287500,0.187500,0.050000,0.050000},{0.287500,0.187500,0.100000,0.100000},{0.312500,0.187500,0.050000,0.050000},{0.312500,0.187500,0.100000,0.100000},{0.337500,0.187500,0.050000,0.050000},{0.337500,0.187500,0.100000,0.100000},{0.362500,0.187500,0.050000,0.050000},{0.362500,0.187500,0.100000,0.100000},{0.387500,0.187500,0.050000,0.050000},{0.387500,0.187500,0.100000,0.100000},{0.412500,0.187500,0.050000,0.050000},{0.412500,0.187500,0.100000,0.100000},{0.437500,0.187500,0.050000,0.050000},{0.437500,0.187500,0.100000,0.100000},{0.462500,0.187500,0.050000,0.050000},{0.462500,0.187500,0.100000,0.100000},{0.487500,0.187500,0.050000,0.050000},{0.487500,0.187500,0.100000,0.100000},{0.512500,0.187500,0.050000,0.050000},{0.512500,0.187500,0.100000,0.100000},{0.537500,0.187500,0.050000,0.050000},{0.537500,0.187500,0.100000,0.100000},{0.562500,0.187500,0.050000,0.050000},{0.562500,0.187500,0.100000,0.100000},{0.587500,0.187500,0.050000,0.050000},{0.587500,0.187500,0.100000,0.100000},{0.612500,0.187500,0.050000,0.050000},{0.612500,0.187500,0.100000,0.100000},{0.637500,0.187500,0.050000,0.050000},{0.637500,0.187500,0.100000,0.100000},{0.662500,0.187500,0.050000,0.050000},{0.662500,0.187500,0.100000,0.100000},{0.687500,0.187500,0.050000,0.050000},{0.687500,0.187500,0.100000,0.100000},{0.712500,0.187500,0.050000,0.050000},{0.712500,0.187500,0.100000,0.100000},{0.737500,0.187500,0.050000,0.050000},{0.737500,0.187500,0.100000,0.100000},{0.762500,0.187500,0.050000,0.050000},{0.762500,0.187500,0.100000,0.100000},{0.787500,0.187500,0.050000,0.050000},{0.787500,0.187500,0.100000,0.100000},{0.812500,0.187500,0.050000,0.050000},{0.812500,0.187500,0.100000,0.100000},{0.837500,0.187500,0.050000,0.050000},{0.837500,0.187500,0.100000,0.100000},{0.862500,0.187500,0.050000,0.050000},{0.862500,0.187500,0.100000,0.100000},{0.887500,0.187500,0.050000,0.050000},{0.887500,0.187500,0.100000,0.100000},{0.912500,0.187500,0.050000,0.050000},{0.912500,0.187500,0.100000,0.100000},{0.937500,0.187500,0.050000,0.050000},{0.937500,0.187500,0.100000,0.100000},{0.962500,0.187500,0.050000,0.050000},{0.962500,0.187500,0.100000,0.100000},{0.987500,0.187500,0.050000,0.050000},{0.987500,0.187500,0.100000,0.100000},{0.012500,0.212500,0.050000,0.050000},{0.012500,0.212500,0.100000,0.100000},{0.037500,0.212500,0.050000,0.050000},{0.037500,0.212500,0.100000,0.100000},{0.062500,0.212500,0.050000,0.050000},{0.062500,0.212500,0.100000,0.100000},{0.087500,0.212500,0.050000,0.050000},{0.087500,0.212500,0.100000,0.100000},{0.112500,0.212500,0.050000,0.050000},{0.112500,0.212500,0.100000,0.100000},{0.137500,0.212500,0.050000,0.050000},{0.137500,0.212500,0.100000,0.100000},{0.162500,0.212500,0.050000,0.050000},{0.162500,0.212500,0.100000,0.100000},{0.187500,0.212500,0.050000,0.050000},{0.187500,0.212500,0.100000,0.100000},{0.212500,0.212500,0.050000,0.050000},{0.212500,0.212500,0.100000,0.100000},{0.237500,0.212500,0.050000,0.050000},{0.237500,0.212500,0.100000,0.100000},{0.262500,0.212500,0.050000,0.050000},{0.262500,0.212500,0.100000,0.100000},{0.287500,0.212500,0.050000,0.050000},{0.287500,0.212500,0.100000,0.100000},{0.312500,0.212500,0.050000,0.050000},{0.312500,0.212500,0.100000,0.100000},{0.337500,0.212500,0.050000,0.050000},{0.337500,0.212500,0.100000,0.100000},{0.362500,0.212500,0.050000,0.050000},{0.362500,0.212500,0.100000,0.100000},{0.387500,0.212500,0.050000,0.050000},{0.387500,0.212500,0.100000,0.100000},{0.412500,0.212500,0.050000,0.050000},{0.412500,0.212500,0.100000,0.100000},{0.437500,0.212500,0.050000,0.050000},{0.437500,0.212500,0.100000,0.100000},{0.462500,0.212500,0.050000,0.050000},{0.462500,0.212500,0.100000,0.100000},{0.487500,0.212500,0.050000,0.050000},{0.487500,0.212500,0.100000,0.100000},{0.512500,0.212500,0.050000,0.050000},{0.512500,0.212500,0.100000,0.100000},{0.537500,0.212500,0.050000,0.050000},{0.537500,0.212500,0.100000,0.100000},{0.562500,0.212500,0.050000,0.050000},{0.562500,0.212500,0.100000,0.100000},{0.587500,0.212500,0.050000,0.050000},{0.587500,0.212500,0.100000,0.100000},{0.612500,0.212500,0.050000,0.050000},{0.612500,0.212500,0.100000,0.100000},{0.637500,0.212500,0.050000,0.050000},{0.637500,0.212500,0.100000,0.100000},{0.662500,0.212500,0.050000,0.050000},{0.662500,0.212500,0.100000,0.100000},{0.687500,0.212500,0.050000,0.050000},{0.687500,0.212500,0.100000,0.100000},{0.712500,0.212500,0.050000,0.050000},{0.712500,0.212500,0.100000,0.100000},{0.737500,0.212500,0.050000,0.050000},{0.737500,0.212500,0.100000,0.100000},{0.762500,0.212500,0.050000,0.050000},{0.762500,0.212500,0.100000,0.100000},{0.787500,0.212500,0.050000,0.050000},{0.787500,0.212500,0.100000,0.100000},{0.812500,0.212500,0.050000,0.050000},{0.812500,0.212500,0.100000,0.100000},{0.837500,0.212500,0.050000,0.050000},{0.837500,0.212500,0.100000,0.100000},{0.862500,0.212500,0.050000,0.050000},{0.862500,0.212500,0.100000,0.100000},{0.887500,0.212500,0.050000,0.050000},{0.887500,0.212500,0.100000,0.100000},{0.912500,0.212500,0.050000,0.050000},{0.912500,0.212500,0.100000,0.100000},{0.937500,0.212500,0.050000,0.050000},{0.937500,0.212500,0.100000,0.100000},{0.962500,0.212500,0.050000,0.050000},{0.962500,0.212500,0.100000,0.100000},{0.987500,0.212500,0.050000,0.050000},{0.987500,0.212500,0.100000,0.100000},{0.012500,0.237500,0.050000,0.050000},{0.012500,0.237500,0.100000,0.100000},{0.037500,0.237500,0.050000,0.050000},{0.037500,0.237500,0.100000,0.100000},{0.062500,0.237500,0.050000,0.050000},{0.062500,0.237500,0.100000,0.100000},{0.087500,0.237500,0.050000,0.050000},{0.087500,0.237500,0.100000,0.100000},{0.112500,0.237500,0.050000,0.050000},{0.112500,0.237500,0.100000,0.100000},{0.137500,0.237500,0.050000,0.050000},{0.137500,0.237500,0.100000,0.100000},{0.162500,0.237500,0.050000,0.050000},{0.162500,0.237500,0.100000,0.100000},{0.187500,0.237500,0.050000,0.050000},{0.187500,0.237500,0.100000,0.100000},{0.212500,0.237500,0.050000,0.050000},{0.212500,0.237500,0.100000,0.100000},{0.237500,0.237500,0.050000,0.050000},{0.237500,0.237500,0.100000,0.100000},{0.262500,0.237500,0.050000,0.050000},{0.262500,0.237500,0.100000,0.100000},{0.287500,0.237500,0.050000,0.050000},{0.287500,0.237500,0.100000,0.100000},{0.312500,0.237500,0.050000,0.050000},{0.312500,0.237500,0.100000,0.100000},{0.337500,0.237500,0.050000,0.050000},{0.337500,0.237500,0.100000,0.100000},{0.362500,0.237500,0.050000,0.050000},{0.362500,0.237500,0.100000,0.100000},{0.387500,0.237500,0.050000,0.050000},{0.387500,0.237500,0.100000,0.100000},{0.412500,0.237500,0.050000,0.050000},{0.412500,0.237500,0.100000,0.100000},{0.437500,0.237500,0.050000,0.050000},{0.437500,0.237500,0.100000,0.100000},{0.462500,0.237500,0.050000,0.050000},{0.462500,0.237500,0.100000,0.100000},{0.487500,0.237500,0.050000,0.050000},{0.487500,0.237500,0.100000,0.100000},{0.512500,0.237500,0.050000,0.050000},{0.512500,0.237500,0.100000,0.100000},{0.537500,0.237500,0.050000,0.050000},{0.537500,0.237500,0.100000,0.100000},{0.562500,0.237500,0.050000,0.050000},{0.562500,0.237500,0.100000,0.100000},{0.587500,0.237500,0.050000,0.050000},{0.587500,0.237500,0.100000,0.100000},{0.612500,0.237500,0.050000,0.050000},{0.612500,0.237500,0.100000,0.100000},{0.637500,0.237500,0.050000,0.050000},{0.637500,0.237500,0.100000,0.100000},{0.662500,0.237500,0.050000,0.050000},{0.662500,0.237500,0.100000,0.100000},{0.687500,0.237500,0.050000,0.050000},{0.687500,0.237500,0.100000,0.100000},{0.712500,0.237500,0.050000,0.050000},{0.712500,0.237500,0.100000,0.100000},{0.737500,0.237500,0.050000,0.050000},{0.737500,0.237500,0.100000,0.100000},{0.762500,0.237500,0.050000,0.050000},{0.762500,0.237500,0.100000,0.100000},{0.787500,0.237500,0.050000,0.050000},{0.787500,0.237500,0.100000,0.100000},{0.812500,0.237500,0.050000,0.050000},{0.812500,0.237500,0.100000,0.100000},{0.837500,0.237500,0.050000,0.050000},{0.837500,0.237500,0.100000,0.100000},{0.862500,0.237500,0.050000,0.050000},{0.862500,0.237500,0.100000,0.100000},{0.887500,0.237500,0.050000,0.050000},{0.887500,0.237500,0.100000,0.100000},{0.912500,0.237500,0.050000,0.050000},{0.912500,0.237500,0.100000,0.100000},{0.937500,0.237500,0.050000,0.050000},{0.937500,0.237500,0.100000,0.100000},{0.962500,0.237500,0.050000,0.050000},{0.962500,0.237500,0.100000,0.100000},{0.987500,0.237500,0.050000,0.050000},{0.987500,0.237500,0.100000,0.100000},{0.012500,0.262500,0.050000,0.050000},{0.012500,0.262500,0.100000,0.100000},{0.037500,0.262500,0.050000,0.050000},{0.037500,0.262500,0.100000,0.100000},{0.062500,0.262500,0.050000,0.050000},{0.062500,0.262500,0.100000,0.100000},{0.087500,0.262500,0.050000,0.050000},{0.087500,0.262500,0.100000,0.100000},{0.112500,0.262500,0.050000,0.050000},{0.112500,0.262500,0.100000,0.100000},{0.137500,0.262500,0.050000,0.050000},{0.137500,0.262500,0.100000,0.100000},{0.162500,0.262500,0.050000,0.050000},{0.162500,0.262500,0.100000,0.100000},{0.187500,0.262500,0.050000,0.050000},{0.187500,0.262500,0.100000,0.100000},{0.212500,0.262500,0.050000,0.050000},{0.212500,0.262500,0.100000,0.100000},{0.237500,0.262500,0.050000,0.050000},{0.237500,0.262500,0.100000,0.100000},{0.262500,0.262500,0.050000,0.050000},{0.262500,0.262500,0.100000,0.100000},{0.287500,0.262500,0.050000,0.050000},{0.287500,0.262500,0.100000,0.100000},{0.312500,0.262500,0.050000,0.050000},{0.312500,0.262500,0.100000,0.100000},{0.337500,0.262500,0.050000,0.050000},{0.337500,0.262500,0.100000,0.100000},{0.362500,0.262500,0.050000,0.050000},{0.362500,0.262500,0.100000,0.100000},{0.387500,0.262500,0.050000,0.050000},{0.387500,0.262500,0.100000,0.100000},{0.412500,0.262500,0.050000,0.050000},{0.412500,0.262500,0.100000,0.100000},{0.437500,0.262500,0.050000,0.050000},{0.437500,0.262500,0.100000,0.100000},{0.462500,0.262500,0.050000,0.050000},{0.462500,0.262500,0.100000,0.100000},{0.487500,0.262500,0.050000,0.050000},{0.487500,0.262500,0.100000,0.100000},{0.512500,0.262500,0.050000,0.050000},{0.512500,0.262500,0.100000,0.100000},{0.537500,0.262500,0.050000,0.050000},{0.537500,0.262500,0.100000,0.100000},{0.562500,0.262500,0.050000,0.050000},{0.562500,0.262500,0.100000,0.100000},{0.587500,0.262500,0.050000,0.050000},{0.587500,0.262500,0.100000,0.100000},{0.612500,0.262500,0.050000,0.050000},{0.612500,0.262500,0.100000,0.100000},{0.637500,0.262500,0.050000,0.050000},{0.637500,0.262500,0.100000,0.100000},{0.662500,0.262500,0.050000,0.050000},{0.662500,0.262500,0.100000,0.100000},{0.687500,0.262500,0.050000,0.050000},{0.687500,0.262500,0.100000,0.100000},{0.712500,0.262500,0.050000,0.050000},{0.712500,0.262500,0.100000,0.100000},{0.737500,0.262500,0.050000,0.050000},{0.737500,0.262500,0.100000,0.100000},{0.762500,0.262500,0.050000,0.050000},{0.762500,0.262500,0.100000,0.100000},{0.787500,0.262500,0.050000,0.050000},{0.787500,0.262500,0.100000,0.100000},{0.812500,0.262500,0.050000,0.050000},{0.812500,0.262500,0.100000,0.100000},{0.837500,0.262500,0.050000,0.050000},{0.837500,0.262500,0.100000,0.100000},{0.862500,0.262500,0.050000,0.050000},{0.862500,0.262500,0.100000,0.100000},{0.887500,0.262500,0.050000,0.050000},{0.887500,0.262500,0.100000,0.100000},{0.912500,0.262500,0.050000,0.050000},{0.912500,0.262500,0.100000,0.100000},{0.937500,0.262500,0.050000,0.050000},{0.937500,0.262500,0.100000,0.100000},{0.962500,0.262500,0.050000,0.050000},{0.962500,0.262500,0.100000,0.100000},{0.987500,0.262500,0.050000,0.050000},{0.987500,0.262500,0.100000,0.100000},{0.012500,0.287500,0.050000,0.050000},{0.012500,0.287500,0.100000,0.100000},{0.037500,0.287500,0.050000,0.050000},{0.037500,0.287500,0.100000,0.100000},{0.062500,0.287500,0.050000,0.050000},{0.062500,0.287500,0.100000,0.100000},{0.087500,0.287500,0.050000,0.050000},{0.087500,0.287500,0.100000,0.100000},{0.112500,0.287500,0.050000,0.050000},{0.112500,0.287500,0.100000,0.100000},{0.137500,0.287500,0.050000,0.050000},{0.137500,0.287500,0.100000,0.100000},{0.162500,0.287500,0.050000,0.050000},{0.162500,0.287500,0.100000,0.100000},{0.187500,0.287500,0.050000,0.050000},{0.187500,0.287500,0.100000,0.100000},{0.212500,0.287500,0.050000,0.050000},{0.212500,0.287500,0.100000,0.100000},{0.237500,0.287500,0.050000,0.050000},{0.237500,0.287500,0.100000,0.100000},{0.262500,0.287500,0.050000,0.050000},{0.262500,0.287500,0.100000,0.100000},{0.287500,0.287500,0.050000,0.050000},{0.287500,0.287500,0.100000,0.100000},{0.312500,0.287500,0.050000,0.050000},{0.312500,0.287500,0.100000,0.100000},{0.337500,0.287500,0.050000,0.050000},{0.337500,0.287500,0.100000,0.100000},{0.362500,0.287500,0.050000,0.050000},{0.362500,0.287500,0.100000,0.100000},{0.387500,0.287500,0.050000,0.050000},{0.387500,0.287500,0.100000,0.100000},{0.412500,0.287500,0.050000,0.050000},{0.412500,0.287500,0.100000,0.100000},{0.437500,0.287500,0.050000,0.050000},{0.437500,0.287500,0.100000,0.100000},{0.462500,0.287500,0.050000,0.050000},{0.462500,0.287500,0.100000,0.100000},{0.487500,0.287500,0.050000,0.050000},{0.487500,0.287500,0.100000,0.100000},{0.512500,0.287500,0.050000,0.050000},{0.512500,0.287500,0.100000,0.100000},{0.537500,0.287500,0.050000,0.050000},{0.537500,0.287500,0.100000,0.100000},{0.562500,0.287500,0.050000,0.050000},{0.562500,0.287500,0.100000,0.100000},{0.587500,0.287500,0.050000,0.050000},{0.587500,0.287500,0.100000,0.100000},{0.612500,0.287500,0.050000,0.050000},{0.612500,0.287500,0.100000,0.100000},{0.637500,0.287500,0.050000,0.050000},{0.637500,0.287500,0.100000,0.100000},{0.662500,0.287500,0.050000,0.050000},{0.662500,0.287500,0.100000,0.100000},{0.687500,0.287500,0.050000,0.050000},{0.687500,0.287500,0.100000,0.100000},{0.712500,0.287500,0.050000,0.050000},{0.712500,0.287500,0.100000,0.100000},{0.737500,0.287500,0.050000,0.050000},{0.737500,0.287500,0.100000,0.100000},{0.762500,0.287500,0.050000,0.050000},{0.762500,0.287500,0.100000,0.100000},{0.787500,0.287500,0.050000,0.050000},{0.787500,0.287500,0.100000,0.100000},{0.812500,0.287500,0.050000,0.050000},{0.812500,0.287500,0.100000,0.100000},{0.837500,0.287500,0.050000,0.050000},{0.837500,0.287500,0.100000,0.100000},{0.862500,0.287500,0.050000,0.050000},{0.862500,0.287500,0.100000,0.100000},{0.887500,0.287500,0.050000,0.050000},{0.887500,0.287500,0.100000,0.100000},{0.912500,0.287500,0.050000,0.050000},{0.912500,0.287500,0.100000,0.100000},{0.937500,0.287500,0.050000,0.050000},{0.937500,0.287500,0.100000,0.100000},{0.962500,0.287500,0.050000,0.050000},{0.962500,0.287500,0.100000,0.100000},{0.987500,0.287500,0.050000,0.050000},{0.987500,0.287500,0.100000,0.100000},{0.012500,0.312500,0.050000,0.050000},{0.012500,0.312500,0.100000,0.100000},{0.037500,0.312500,0.050000,0.050000},{0.037500,0.312500,0.100000,0.100000},{0.062500,0.312500,0.050000,0.050000},{0.062500,0.312500,0.100000,0.100000},{0.087500,0.312500,0.050000,0.050000},{0.087500,0.312500,0.100000,0.100000},{0.112500,0.312500,0.050000,0.050000},{0.112500,0.312500,0.100000,0.100000},{0.137500,0.312500,0.050000,0.050000},{0.137500,0.312500,0.100000,0.100000},{0.162500,0.312500,0.050000,0.050000},{0.162500,0.312500,0.100000,0.100000},{0.187500,0.312500,0.050000,0.050000},{0.187500,0.312500,0.100000,0.100000},{0.212500,0.312500,0.050000,0.050000},{0.212500,0.312500,0.100000,0.100000},{0.237500,0.312500,0.050000,0.050000},{0.237500,0.312500,0.100000,0.100000},{0.262500,0.312500,0.050000,0.050000},{0.262500,0.312500,0.100000,0.100000},{0.287500,0.312500,0.050000,0.050000},{0.287500,0.312500,0.100000,0.100000},{0.312500,0.312500,0.050000,0.050000},{0.312500,0.312500,0.100000,0.100000},{0.337500,0.312500,0.050000,0.050000},{0.337500,0.312500,0.100000,0.100000},{0.362500,0.312500,0.050000,0.050000},{0.362500,0.312500,0.100000,0.100000},{0.387500,0.312500,0.050000,0.050000},{0.387500,0.312500,0.100000,0.100000},{0.412500,0.312500,0.050000,0.050000},{0.412500,0.312500,0.100000,0.100000},{0.437500,0.312500,0.050000,0.050000},{0.437500,0.312500,0.100000,0.100000},{0.462500,0.312500,0.050000,0.050000},{0.462500,0.312500,0.100000,0.100000},{0.487500,0.312500,0.050000,0.050000},{0.487500,0.312500,0.100000,0.100000},{0.512500,0.312500,0.050000,0.050000},{0.512500,0.312500,0.100000,0.100000},{0.537500,0.312500,0.050000,0.050000},{0.537500,0.312500,0.100000,0.100000},{0.562500,0.312500,0.050000,0.050000},{0.562500,0.312500,0.100000,0.100000},{0.587500,0.312500,0.050000,0.050000},{0.587500,0.312500,0.100000,0.100000},{0.612500,0.312500,0.050000,0.050000},{0.612500,0.312500,0.100000,0.100000},{0.637500,0.312500,0.050000,0.050000},{0.637500,0.312500,0.100000,0.100000},{0.662500,0.312500,0.050000,0.050000},{0.662500,0.312500,0.100000,0.100000},{0.687500,0.312500,0.050000,0.050000},{0.687500,0.312500,0.100000,0.100000},{0.712500,0.312500,0.050000,0.050000},{0.712500,0.312500,0.100000,0.100000},{0.737500,0.312500,0.050000,0.050000},{0.737500,0.312500,0.100000,0.100000},{0.762500,0.312500,0.050000,0.050000},{0.762500,0.312500,0.100000,0.100000},{0.787500,0.312500,0.050000,0.050000},{0.787500,0.312500,0.100000,0.100000},{0.812500,0.312500,0.050000,0.050000},{0.812500,0.312500,0.100000,0.100000},{0.837500,0.312500,0.050000,0.050000},{0.837500,0.312500,0.100000,0.100000},{0.862500,0.312500,0.050000,0.050000},{0.862500,0.312500,0.100000,0.100000},{0.887500,0.312500,0.050000,0.050000},{0.887500,0.312500,0.100000,0.100000},{0.912500,0.312500,0.050000,0.050000},{0.912500,0.312500,0.100000,0.100000},{0.937500,0.312500,0.050000,0.050000},{0.937500,0.312500,0.100000,0.100000},{0.962500,0.312500,0.050000,0.050000},{0.962500,0.312500,0.100000,0.100000},{0.987500,0.312500,0.050000,0.050000},{0.987500,0.312500,0.100000,0.100000},{0.012500,0.337500,0.050000,0.050000},{0.012500,0.337500,0.100000,0.100000},{0.037500,0.337500,0.050000,0.050000},{0.037500,0.337500,0.100000,0.100000},{0.062500,0.337500,0.050000,0.050000},{0.062500,0.337500,0.100000,0.100000},{0.087500,0.337500,0.050000,0.050000},{0.087500,0.337500,0.100000,0.100000},{0.112500,0.337500,0.050000,0.050000},{0.112500,0.337500,0.100000,0.100000},{0.137500,0.337500,0.050000,0.050000},{0.137500,0.337500,0.100000,0.100000},{0.162500,0.337500,0.050000,0.050000},{0.162500,0.337500,0.100000,0.100000},{0.187500,0.337500,0.050000,0.050000},{0.187500,0.337500,0.100000,0.100000},{0.212500,0.337500,0.050000,0.050000},{0.212500,0.337500,0.100000,0.100000},{0.237500,0.337500,0.050000,0.050000},{0.237500,0.337500,0.100000,0.100000},{0.262500,0.337500,0.050000,0.050000},{0.262500,0.337500,0.100000,0.100000},{0.287500,0.337500,0.050000,0.050000},{0.287500,0.337500,0.100000,0.100000},{0.312500,0.337500,0.050000,0.050000},{0.312500,0.337500,0.100000,0.100000},{0.337500,0.337500,0.050000,0.050000},{0.337500,0.337500,0.100000,0.100000},{0.362500,0.337500,0.050000,0.050000},{0.362500,0.337500,0.100000,0.100000},{0.387500,0.337500,0.050000,0.050000},{0.387500,0.337500,0.100000,0.100000},{0.412500,0.337500,0.050000,0.050000},{0.412500,0.337500,0.100000,0.100000},{0.437500,0.337500,0.050000,0.050000},{0.437500,0.337500,0.100000,0.100000},{0.462500,0.337500,0.050000,0.050000},{0.462500,0.337500,0.100000,0.100000},{0.487500,0.337500,0.050000,0.050000},{0.487500,0.337500,0.100000,0.100000},{0.512500,0.337500,0.050000,0.050000},{0.512500,0.337500,0.100000,0.100000},{0.537500,0.337500,0.050000,0.050000},{0.537500,0.337500,0.100000,0.100000},{0.562500,0.337500,0.050000,0.050000},{0.562500,0.337500,0.100000,0.100000},{0.587500,0.337500,0.050000,0.050000},{0.587500,0.337500,0.100000,0.100000},{0.612500,0.337500,0.050000,0.050000},{0.612500,0.337500,0.100000,0.100000},{0.637500,0.337500,0.050000,0.050000},{0.637500,0.337500,0.100000,0.100000},{0.662500,0.337500,0.050000,0.050000},{0.662500,0.337500,0.100000,0.100000},{0.687500,0.337500,0.050000,0.050000},{0.687500,0.337500,0.100000,0.100000},{0.712500,0.337500,0.050000,0.050000},{0.712500,0.337500,0.100000,0.100000},{0.737500,0.337500,0.050000,0.050000},{0.737500,0.337500,0.100000,0.100000},{0.762500,0.337500,0.050000,0.050000},{0.762500,0.337500,0.100000,0.100000},{0.787500,0.337500,0.050000,0.050000},{0.787500,0.337500,0.100000,0.100000},{0.812500,0.337500,0.050000,0.050000},{0.812500,0.337500,0.100000,0.100000},{0.837500,0.337500,0.050000,0.050000},{0.837500,0.337500,0.100000,0.100000},{0.862500,0.337500,0.050000,0.050000},{0.862500,0.337500,0.100000,0.100000},{0.887500,0.337500,0.050000,0.050000},{0.887500,0.337500,0.100000,0.100000},{0.912500,0.337500,0.050000,0.050000},{0.912500,0.337500,0.100000,0.100000},{0.937500,0.337500,0.050000,0.050000},{0.937500,0.337500,0.100000,0.100000},{0.962500,0.337500,0.050000,0.050000},{0.962500,0.337500,0.100000,0.100000},{0.987500,0.337500,0.050000,0.050000},{0.987500,0.337500,0.100000,0.100000},{0.012500,0.362500,0.050000,0.050000},{0.012500,0.362500,0.100000,0.100000},{0.037500,0.362500,0.050000,0.050000},{0.037500,0.362500,0.100000,0.100000},{0.062500,0.362500,0.050000,0.050000},{0.062500,0.362500,0.100000,0.100000},{0.087500,0.362500,0.050000,0.050000},{0.087500,0.362500,0.100000,0.100000},{0.112500,0.362500,0.050000,0.050000},{0.112500,0.362500,0.100000,0.100000},{0.137500,0.362500,0.050000,0.050000},{0.137500,0.362500,0.100000,0.100000},{0.162500,0.362500,0.050000,0.050000},{0.162500,0.362500,0.100000,0.100000},{0.187500,0.362500,0.050000,0.050000},{0.187500,0.362500,0.100000,0.100000},{0.212500,0.362500,0.050000,0.050000},{0.212500,0.362500,0.100000,0.100000},{0.237500,0.362500,0.050000,0.050000},{0.237500,0.362500,0.100000,0.100000},{0.262500,0.362500,0.050000,0.050000},{0.262500,0.362500,0.100000,0.100000},{0.287500,0.362500,0.050000,0.050000},{0.287500,0.362500,0.100000,0.100000},{0.312500,0.362500,0.050000,0.050000},{0.312500,0.362500,0.100000,0.100000},{0.337500,0.362500,0.050000,0.050000},{0.337500,0.362500,0.100000,0.100000},{0.362500,0.362500,0.050000,0.050000},{0.362500,0.362500,0.100000,0.100000},{0.387500,0.362500,0.050000,0.050000},{0.387500,0.362500,0.100000,0.100000},{0.412500,0.362500,0.050000,0.050000},{0.412500,0.362500,0.100000,0.100000},{0.437500,0.362500,0.050000,0.050000},{0.437500,0.362500,0.100000,0.100000},{0.462500,0.362500,0.050000,0.050000},{0.462500,0.362500,0.100000,0.100000},{0.487500,0.362500,0.050000,0.050000},{0.487500,0.362500,0.100000,0.100000},{0.512500,0.362500,0.050000,0.050000},{0.512500,0.362500,0.100000,0.100000},{0.537500,0.362500,0.050000,0.050000},{0.537500,0.362500,0.100000,0.100000},{0.562500,0.362500,0.050000,0.050000},{0.562500,0.362500,0.100000,0.100000},{0.587500,0.362500,0.050000,0.050000},{0.587500,0.362500,0.100000,0.100000},{0.612500,0.362500,0.050000,0.050000},{0.612500,0.362500,0.100000,0.100000},{0.637500,0.362500,0.050000,0.050000},{0.637500,0.362500,0.100000,0.100000},{0.662500,0.362500,0.050000,0.050000},{0.662500,0.362500,0.100000,0.100000},{0.687500,0.362500,0.050000,0.050000},{0.687500,0.362500,0.100000,0.100000},{0.712500,0.362500,0.050000,0.050000},{0.712500,0.362500,0.100000,0.100000},{0.737500,0.362500,0.050000,0.050000},{0.737500,0.362500,0.100000,0.100000},{0.762500,0.362500,0.050000,0.050000},{0.762500,0.362500,0.100000,0.100000},{0.787500,0.362500,0.050000,0.050000},{0.787500,0.362500,0.100000,0.100000},{0.812500,0.362500,0.050000,0.050000},{0.812500,0.362500,0.100000,0.100000},{0.837500,0.362500,0.050000,0.050000},{0.837500,0.362500,0.100000,0.100000},{0.862500,0.362500,0.050000,0.050000},{0.862500,0.362500,0.100000,0.100000},{0.887500,0.362500,0.050000,0.050000},{0.887500,0.362500,0.100000,0.100000},{0.912500,0.362500,0.050000,0.050000},{0.912500,0.362500,0.100000,0.100000},{0.937500,0.362500,0.050000,0.050000},{0.937500,0.362500,0.100000,0.100000},{0.962500,0.362500,0.050000,0.050000},{0.962500,0.362500,0.100000,0.100000},{0.987500,0.362500,0.050000,0.050000},{0.987500,0.362500,0.100000,0.100000},{0.012500,0.387500,0.050000,0.050000},{0.012500,0.387500,0.100000,0.100000},{0.037500,0.387500,0.050000,0.050000},{0.037500,0.387500,0.100000,0.100000},{0.062500,0.387500,0.050000,0.050000},{0.062500,0.387500,0.100000,0.100000},{0.087500,0.387500,0.050000,0.050000},{0.087500,0.387500,0.100000,0.100000},{0.112500,0.387500,0.050000,0.050000},{0.112500,0.387500,0.100000,0.100000},{0.137500,0.387500,0.050000,0.050000},{0.137500,0.387500,0.100000,0.100000},{0.162500,0.387500,0.050000,0.050000},{0.162500,0.387500,0.100000,0.100000},{0.187500,0.387500,0.050000,0.050000},{0.187500,0.387500,0.100000,0.100000},{0.212500,0.387500,0.050000,0.050000},{0.212500,0.387500,0.100000,0.100000},{0.237500,0.387500,0.050000,0.050000},{0.237500,0.387500,0.100000,0.100000},{0.262500,0.387500,0.050000,0.050000},{0.262500,0.387500,0.100000,0.100000},{0.287500,0.387500,0.050000,0.050000},{0.287500,0.387500,0.100000,0.100000},{0.312500,0.387500,0.050000,0.050000},{0.312500,0.387500,0.100000,0.100000},{0.337500,0.387500,0.050000,0.050000},{0.337500,0.387500,0.100000,0.100000},{0.362500,0.387500,0.050000,0.050000},{0.362500,0.387500,0.100000,0.100000},{0.387500,0.387500,0.050000,0.050000},{0.387500,0.387500,0.100000,0.100000},{0.412500,0.387500,0.050000,0.050000},{0.412500,0.387500,0.100000,0.100000},{0.437500,0.387500,0.050000,0.050000},{0.437500,0.387500,0.100000,0.100000},{0.462500,0.387500,0.050000,0.050000},{0.462500,0.387500,0.100000,0.100000},{0.487500,0.387500,0.050000,0.050000},{0.487500,0.387500,0.100000,0.100000},{0.512500,0.387500,0.050000,0.050000},{0.512500,0.387500,0.100000,0.100000},{0.537500,0.387500,0.050000,0.050000},{0.537500,0.387500,0.100000,0.100000},{0.562500,0.387500,0.050000,0.050000},{0.562500,0.387500,0.100000,0.100000},{0.587500,0.387500,0.050000,0.050000},{0.587500,0.387500,0.100000,0.100000},{0.612500,0.387500,0.050000,0.050000},{0.612500,0.387500,0.100000,0.100000},{0.637500,0.387500,0.050000,0.050000},{0.637500,0.387500,0.100000,0.100000},{0.662500,0.387500,0.050000,0.050000},{0.662500,0.387500,0.100000,0.100000},{0.687500,0.387500,0.050000,0.050000},{0.687500,0.387500,0.100000,0.100000},{0.712500,0.387500,0.050000,0.050000},{0.712500,0.387500,0.100000,0.100000},{0.737500,0.387500,0.050000,0.050000},{0.737500,0.387500,0.100000,0.100000},{0.762500,0.387500,0.050000,0.050000},{0.762500,0.387500,0.100000,0.100000},{0.787500,0.387500,0.050000,0.050000},{0.787500,0.387500,0.100000,0.100000},{0.812500,0.387500,0.050000,0.050000},{0.812500,0.387500,0.100000,0.100000},{0.837500,0.387500,0.050000,0.050000},{0.837500,0.387500,0.100000,0.100000},{0.862500,0.387500,0.050000,0.050000},{0.862500,0.387500,0.100000,0.100000},{0.887500,0.387500,0.050000,0.050000},{0.887500,0.387500,0.100000,0.100000},{0.912500,0.387500,0.050000,0.050000},{0.912500,0.387500,0.100000,0.100000},{0.937500,0.387500,0.050000,0.050000},{0.937500,0.387500,0.100000,0.100000},{0.962500,0.387500,0.050000,0.050000},{0.962500,0.387500,0.100000,0.100000},{0.987500,0.387500,0.050000,0.050000},{0.987500,0.387500,0.100000,0.100000},{0.012500,0.412500,0.050000,0.050000},{0.012500,0.412500,0.100000,0.100000},{0.037500,0.412500,0.050000,0.050000},{0.037500,0.412500,0.100000,0.100000},{0.062500,0.412500,0.050000,0.050000},{0.062500,0.412500,0.100000,0.100000},{0.087500,0.412500,0.050000,0.050000},{0.087500,0.412500,0.100000,0.100000},{0.112500,0.412500,0.050000,0.050000},{0.112500,0.412500,0.100000,0.100000},{0.137500,0.412500,0.050000,0.050000},{0.137500,0.412500,0.100000,0.100000},{0.162500,0.412500,0.050000,0.050000},{0.162500,0.412500,0.100000,0.100000},{0.187500,0.412500,0.050000,0.050000},{0.187500,0.412500,0.100000,0.100000},{0.212500,0.412500,0.050000,0.050000},{0.212500,0.412500,0.100000,0.100000},{0.237500,0.412500,0.050000,0.050000},{0.237500,0.412500,0.100000,0.100000},{0.262500,0.412500,0.050000,0.050000},{0.262500,0.412500,0.100000,0.100000},{0.287500,0.412500,0.050000,0.050000},{0.287500,0.412500,0.100000,0.100000},{0.312500,0.412500,0.050000,0.050000},{0.312500,0.412500,0.100000,0.100000},{0.337500,0.412500,0.050000,0.050000},{0.337500,0.412500,0.100000,0.100000},{0.362500,0.412500,0.050000,0.050000},{0.362500,0.412500,0.100000,0.100000},{0.387500,0.412500,0.050000,0.050000},{0.387500,0.412500,0.100000,0.100000},{0.412500,0.412500,0.050000,0.050000},{0.412500,0.412500,0.100000,0.100000},{0.437500,0.412500,0.050000,0.050000},{0.437500,0.412500,0.100000,0.100000},{0.462500,0.412500,0.050000,0.050000},{0.462500,0.412500,0.100000,0.100000},{0.487500,0.412500,0.050000,0.050000},{0.487500,0.412500,0.100000,0.100000},{0.512500,0.412500,0.050000,0.050000},{0.512500,0.412500,0.100000,0.100000},{0.537500,0.412500,0.050000,0.050000},{0.537500,0.412500,0.100000,0.100000},{0.562500,0.412500,0.050000,0.050000},{0.562500,0.412500,0.100000,0.100000},{0.587500,0.412500,0.050000,0.050000},{0.587500,0.412500,0.100000,0.100000},{0.612500,0.412500,0.050000,0.050000},{0.612500,0.412500,0.100000,0.100000},{0.637500,0.412500,0.050000,0.050000},{0.637500,0.412500,0.100000,0.100000},{0.662500,0.412500,0.050000,0.050000},{0.662500,0.412500,0.100000,0.100000},{0.687500,0.412500,0.050000,0.050000},{0.687500,0.412500,0.100000,0.100000},{0.712500,0.412500,0.050000,0.050000},{0.712500,0.412500,0.100000,0.100000},{0.737500,0.412500,0.050000,0.050000},{0.737500,0.412500,0.100000,0.100000},{0.762500,0.412500,0.050000,0.050000},{0.762500,0.412500,0.100000,0.100000},{0.787500,0.412500,0.050000,0.050000},{0.787500,0.412500,0.100000,0.100000},{0.812500,0.412500,0.050000,0.050000},{0.812500,0.412500,0.100000,0.100000},{0.837500,0.412500,0.050000,0.050000},{0.837500,0.412500,0.100000,0.100000},{0.862500,0.412500,0.050000,0.050000},{0.862500,0.412500,0.100000,0.100000},{0.887500,0.412500,0.050000,0.050000},{0.887500,0.412500,0.100000,0.100000},{0.912500,0.412500,0.050000,0.050000},{0.912500,0.412500,0.100000,0.100000},{0.937500,0.412500,0.050000,0.050000},{0.937500,0.412500,0.100000,0.100000},{0.962500,0.412500,0.050000,0.050000},{0.962500,0.412500,0.100000,0.100000},{0.987500,0.412500,0.050000,0.050000},{0.987500,0.412500,0.100000,0.100000},{0.012500,0.437500,0.050000,0.050000},{0.012500,0.437500,0.100000,0.100000},{0.037500,0.437500,0.050000,0.050000},{0.037500,0.437500,0.100000,0.100000},{0.062500,0.437500,0.050000,0.050000},{0.062500,0.437500,0.100000,0.100000},{0.087500,0.437500,0.050000,0.050000},{0.087500,0.437500,0.100000,0.100000},{0.112500,0.437500,0.050000,0.050000},{0.112500,0.437500,0.100000,0.100000},{0.137500,0.437500,0.050000,0.050000},{0.137500,0.437500,0.100000,0.100000},{0.162500,0.437500,0.050000,0.050000},{0.162500,0.437500,0.100000,0.100000},{0.187500,0.437500,0.050000,0.050000},{0.187500,0.437500,0.100000,0.100000},{0.212500,0.437500,0.050000,0.050000},{0.212500,0.437500,0.100000,0.100000},{0.237500,0.437500,0.050000,0.050000},{0.237500,0.437500,0.100000,0.100000},{0.262500,0.437500,0.050000,0.050000},{0.262500,0.437500,0.100000,0.100000},{0.287500,0.437500,0.050000,0.050000},{0.287500,0.437500,0.100000,0.100000},{0.312500,0.437500,0.050000,0.050000},{0.312500,0.437500,0.100000,0.100000},{0.337500,0.437500,0.050000,0.050000},{0.337500,0.437500,0.100000,0.100000},{0.362500,0.437500,0.050000,0.050000},{0.362500,0.437500,0.100000,0.100000},{0.387500,0.437500,0.050000,0.050000},{0.387500,0.437500,0.100000,0.100000},{0.412500,0.437500,0.050000,0.050000},{0.412500,0.437500,0.100000,0.100000},{0.437500,0.437500,0.050000,0.050000},{0.437500,0.437500,0.100000,0.100000},{0.462500,0.437500,0.050000,0.050000},{0.462500,0.437500,0.100000,0.100000},{0.487500,0.437500,0.050000,0.050000},{0.487500,0.437500,0.100000,0.100000},{0.512500,0.437500,0.050000,0.050000},{0.512500,0.437500,0.100000,0.100000},{0.537500,0.437500,0.050000,0.050000},{0.537500,0.437500,0.100000,0.100000},{0.562500,0.437500,0.050000,0.050000},{0.562500,0.437500,0.100000,0.100000},{0.587500,0.437500,0.050000,0.050000},{0.587500,0.437500,0.100000,0.100000},{0.612500,0.437500,0.050000,0.050000},{0.612500,0.437500,0.100000,0.100000},{0.637500,0.437500,0.050000,0.050000},{0.637500,0.437500,0.100000,0.100000},{0.662500,0.437500,0.050000,0.050000},{0.662500,0.437500,0.100000,0.100000},{0.687500,0.437500,0.050000,0.050000},{0.687500,0.437500,0.100000,0.100000},{0.712500,0.437500,0.050000,0.050000},{0.712500,0.437500,0.100000,0.100000},{0.737500,0.437500,0.050000,0.050000},{0.737500,0.437500,0.100000,0.100000},{0.762500,0.437500,0.050000,0.050000},{0.762500,0.437500,0.100000,0.100000},{0.787500,0.437500,0.050000,0.050000},{0.787500,0.437500,0.100000,0.100000},{0.812500,0.437500,0.050000,0.050000},{0.812500,0.437500,0.100000,0.100000},{0.837500,0.437500,0.050000,0.050000},{0.837500,0.437500,0.100000,0.100000},{0.862500,0.437500,0.050000,0.050000},{0.862500,0.437500,0.100000,0.100000},{0.887500,0.437500,0.050000,0.050000},{0.887500,0.437500,0.100000,0.100000},{0.912500,0.437500,0.050000,0.050000},{0.912500,0.437500,0.100000,0.100000},{0.937500,0.437500,0.050000,0.050000},{0.937500,0.437500,0.100000,0.100000},{0.962500,0.437500,0.050000,0.050000},{0.962500,0.437500,0.100000,0.100000},{0.987500,0.437500,0.050000,0.050000},{0.987500,0.437500,0.100000,0.100000},{0.012500,0.462500,0.050000,0.050000},{0.012500,0.462500,0.100000,0.100000},{0.037500,0.462500,0.050000,0.050000},{0.037500,0.462500,0.100000,0.100000},{0.062500,0.462500,0.050000,0.050000},{0.062500,0.462500,0.100000,0.100000},{0.087500,0.462500,0.050000,0.050000},{0.087500,0.462500,0.100000,0.100000},{0.112500,0.462500,0.050000,0.050000},{0.112500,0.462500,0.100000,0.100000},{0.137500,0.462500,0.050000,0.050000},{0.137500,0.462500,0.100000,0.100000},{0.162500,0.462500,0.050000,0.050000},{0.162500,0.462500,0.100000,0.100000},{0.187500,0.462500,0.050000,0.050000},{0.187500,0.462500,0.100000,0.100000},{0.212500,0.462500,0.050000,0.050000},{0.212500,0.462500,0.100000,0.100000},{0.237500,0.462500,0.050000,0.050000},{0.237500,0.462500,0.100000,0.100000},{0.262500,0.462500,0.050000,0.050000},{0.262500,0.462500,0.100000,0.100000},{0.287500,0.462500,0.050000,0.050000},{0.287500,0.462500,0.100000,0.100000},{0.312500,0.462500,0.050000,0.050000},{0.312500,0.462500,0.100000,0.100000},{0.337500,0.462500,0.050000,0.050000},{0.337500,0.462500,0.100000,0.100000},{0.362500,0.462500,0.050000,0.050000},{0.362500,0.462500,0.100000,0.100000},{0.387500,0.462500,0.050000,0.050000},{0.387500,0.462500,0.100000,0.100000},{0.412500,0.462500,0.050000,0.050000},{0.412500,0.462500,0.100000,0.100000},{0.437500,0.462500,0.050000,0.050000},{0.437500,0.462500,0.100000,0.100000},{0.462500,0.462500,0.050000,0.050000},{0.462500,0.462500,0.100000,0.100000},{0.487500,0.462500,0.050000,0.050000},{0.487500,0.462500,0.100000,0.100000},{0.512500,0.462500,0.050000,0.050000},{0.512500,0.462500,0.100000,0.100000},{0.537500,0.462500,0.050000,0.050000},{0.537500,0.462500,0.100000,0.100000},{0.562500,0.462500,0.050000,0.050000},{0.562500,0.462500,0.100000,0.100000},{0.587500,0.462500,0.050000,0.050000},{0.587500,0.462500,0.100000,0.100000},{0.612500,0.462500,0.050000,0.050000},{0.612500,0.462500,0.100000,0.100000},{0.637500,0.462500,0.050000,0.050000},{0.637500,0.462500,0.100000,0.100000},{0.662500,0.462500,0.050000,0.050000},{0.662500,0.462500,0.100000,0.100000},{0.687500,0.462500,0.050000,0.050000},{0.687500,0.462500,0.100000,0.100000},{0.712500,0.462500,0.050000,0.050000},{0.712500,0.462500,0.100000,0.100000},{0.737500,0.462500,0.050000,0.050000},{0.737500,0.462500,0.100000,0.100000},{0.762500,0.462500,0.050000,0.050000},{0.762500,0.462500,0.100000,0.100000},{0.787500,0.462500,0.050000,0.050000},{0.787500,0.462500,0.100000,0.100000},{0.812500,0.462500,0.050000,0.050000},{0.812500,0.462500,0.100000,0.100000},{0.837500,0.462500,0.050000,0.050000},{0.837500,0.462500,0.100000,0.100000},{0.862500,0.462500,0.050000,0.050000},{0.862500,0.462500,0.100000,0.100000},{0.887500,0.462500,0.050000,0.050000},{0.887500,0.462500,0.100000,0.100000},{0.912500,0.462500,0.050000,0.050000},{0.912500,0.462500,0.100000,0.100000},{0.937500,0.462500,0.050000,0.050000},{0.937500,0.462500,0.100000,0.100000},{0.962500,0.462500,0.050000,0.050000},{0.962500,0.462500,0.100000,0.100000},{0.987500,0.462500,0.050000,0.050000},{0.987500,0.462500,0.100000,0.100000},{0.012500,0.487500,0.050000,0.050000},{0.012500,0.487500,0.100000,0.100000},{0.037500,0.487500,0.050000,0.050000},{0.037500,0.487500,0.100000,0.100000},{0.062500,0.487500,0.050000,0.050000},{0.062500,0.487500,0.100000,0.100000},{0.087500,0.487500,0.050000,0.050000},{0.087500,0.487500,0.100000,0.100000},{0.112500,0.487500,0.050000,0.050000},{0.112500,0.487500,0.100000,0.100000},{0.137500,0.487500,0.050000,0.050000},{0.137500,0.487500,0.100000,0.100000},{0.162500,0.487500,0.050000,0.050000},{0.162500,0.487500,0.100000,0.100000},{0.187500,0.487500,0.050000,0.050000},{0.187500,0.487500,0.100000,0.100000},{0.212500,0.487500,0.050000,0.050000},{0.212500,0.487500,0.100000,0.100000},{0.237500,0.487500,0.050000,0.050000},{0.237500,0.487500,0.100000,0.100000},{0.262500,0.487500,0.050000,0.050000},{0.262500,0.487500,0.100000,0.100000},{0.287500,0.487500,0.050000,0.050000},{0.287500,0.487500,0.100000,0.100000},{0.312500,0.487500,0.050000,0.050000},{0.312500,0.487500,0.100000,0.100000},{0.337500,0.487500,0.050000,0.050000},{0.337500,0.487500,0.100000,0.100000},{0.362500,0.487500,0.050000,0.050000},{0.362500,0.487500,0.100000,0.100000},{0.387500,0.487500,0.050000,0.050000},{0.387500,0.487500,0.100000,0.100000},{0.412500,0.487500,0.050000,0.050000},{0.412500,0.487500,0.100000,0.100000},{0.437500,0.487500,0.050000,0.050000},{0.437500,0.487500,0.100000,0.100000},{0.462500,0.487500,0.050000,0.050000},{0.462500,0.487500,0.100000,0.100000},{0.487500,0.487500,0.050000,0.050000},{0.487500,0.487500,0.100000,0.100000},{0.512500,0.487500,0.050000,0.050000},{0.512500,0.487500,0.100000,0.100000},{0.537500,0.487500,0.050000,0.050000},{0.537500,0.487500,0.100000,0.100000},{0.562500,0.487500,0.050000,0.050000},{0.562500,0.487500,0.100000,0.100000},{0.587500,0.487500,0.050000,0.050000},{0.587500,0.487500,0.100000,0.100000},{0.612500,0.487500,0.050000,0.050000},{0.612500,0.487500,0.100000,0.100000},{0.637500,0.487500,0.050000,0.050000},{0.637500,0.487500,0.100000,0.100000},{0.662500,0.487500,0.050000,0.050000},{0.662500,0.487500,0.100000,0.100000},{0.687500,0.487500,0.050000,0.050000},{0.687500,0.487500,0.100000,0.100000},{0.712500,0.487500,0.050000,0.050000},{0.712500,0.487500,0.100000,0.100000},{0.737500,0.487500,0.050000,0.050000},{0.737500,0.487500,0.100000,0.100000},{0.762500,0.487500,0.050000,0.050000},{0.762500,0.487500,0.100000,0.100000},{0.787500,0.487500,0.050000,0.050000},{0.787500,0.487500,0.100000,0.100000},{0.812500,0.487500,0.050000,0.050000},{0.812500,0.487500,0.100000,0.100000},{0.837500,0.487500,0.050000,0.050000},{0.837500,0.487500,0.100000,0.100000},{0.862500,0.487500,0.050000,0.050000},{0.862500,0.487500,0.100000,0.100000},{0.887500,0.487500,0.050000,0.050000},{0.887500,0.487500,0.100000,0.100000},{0.912500,0.487500,0.050000,0.050000},{0.912500,0.487500,0.100000,0.100000},{0.937500,0.487500,0.050000,0.050000},{0.937500,0.487500,0.100000,0.100000},{0.962500,0.487500,0.050000,0.050000},{0.962500,0.487500,0.100000,0.100000},{0.987500,0.487500,0.050000,0.050000},{0.987500,0.487500,0.100000,0.100000},{0.012500,0.512500,0.050000,0.050000},{0.012500,0.512500,0.100000,0.100000},{0.037500,0.512500,0.050000,0.050000},{0.037500,0.512500,0.100000,0.100000},{0.062500,0.512500,0.050000,0.050000},{0.062500,0.512500,0.100000,0.100000},{0.087500,0.512500,0.050000,0.050000},{0.087500,0.512500,0.100000,0.100000},{0.112500,0.512500,0.050000,0.050000},{0.112500,0.512500,0.100000,0.100000},{0.137500,0.512500,0.050000,0.050000},{0.137500,0.512500,0.100000,0.100000},{0.162500,0.512500,0.050000,0.050000},{0.162500,0.512500,0.100000,0.100000},{0.187500,0.512500,0.050000,0.050000},{0.187500,0.512500,0.100000,0.100000},{0.212500,0.512500,0.050000,0.050000},{0.212500,0.512500,0.100000,0.100000},{0.237500,0.512500,0.050000,0.050000},{0.237500,0.512500,0.100000,0.100000},{0.262500,0.512500,0.050000,0.050000},{0.262500,0.512500,0.100000,0.100000},{0.287500,0.512500,0.050000,0.050000},{0.287500,0.512500,0.100000,0.100000},{0.312500,0.512500,0.050000,0.050000},{0.312500,0.512500,0.100000,0.100000},{0.337500,0.512500,0.050000,0.050000},{0.337500,0.512500,0.100000,0.100000},{0.362500,0.512500,0.050000,0.050000},{0.362500,0.512500,0.100000,0.100000},{0.387500,0.512500,0.050000,0.050000},{0.387500,0.512500,0.100000,0.100000},{0.412500,0.512500,0.050000,0.050000},{0.412500,0.512500,0.100000,0.100000},{0.437500,0.512500,0.050000,0.050000},{0.437500,0.512500,0.100000,0.100000},{0.462500,0.512500,0.050000,0.050000},{0.462500,0.512500,0.100000,0.100000},{0.487500,0.512500,0.050000,0.050000},{0.487500,0.512500,0.100000,0.100000},{0.512500,0.512500,0.050000,0.050000},{0.512500,0.512500,0.100000,0.100000},{0.537500,0.512500,0.050000,0.050000},{0.537500,0.512500,0.100000,0.100000},{0.562500,0.512500,0.050000,0.050000},{0.562500,0.512500,0.100000,0.100000},{0.587500,0.512500,0.050000,0.050000},{0.587500,0.512500,0.100000,0.100000},{0.612500,0.512500,0.050000,0.050000},{0.612500,0.512500,0.100000,0.100000},{0.637500,0.512500,0.050000,0.050000},{0.637500,0.512500,0.100000,0.100000},{0.662500,0.512500,0.050000,0.050000},{0.662500,0.512500,0.100000,0.100000},{0.687500,0.512500,0.050000,0.050000},{0.687500,0.512500,0.100000,0.100000},{0.712500,0.512500,0.050000,0.050000},{0.712500,0.512500,0.100000,0.100000},{0.737500,0.512500,0.050000,0.050000},{0.737500,0.512500,0.100000,0.100000},{0.762500,0.512500,0.050000,0.050000},{0.762500,0.512500,0.100000,0.100000},{0.787500,0.512500,0.050000,0.050000},{0.787500,0.512500,0.100000,0.100000},{0.812500,0.512500,0.050000,0.050000},{0.812500,0.512500,0.100000,0.100000},{0.837500,0.512500,0.050000,0.050000},{0.837500,0.512500,0.100000,0.100000},{0.862500,0.512500,0.050000,0.050000},{0.862500,0.512500,0.100000,0.100000},{0.887500,0.512500,0.050000,0.050000},{0.887500,0.512500,0.100000,0.100000},{0.912500,0.512500,0.050000,0.050000},{0.912500,0.512500,0.100000,0.100000},{0.937500,0.512500,0.050000,0.050000},{0.937500,0.512500,0.100000,0.100000},{0.962500,0.512500,0.050000,0.050000},{0.962500,0.512500,0.100000,0.100000},{0.987500,0.512500,0.050000,0.050000},{0.987500,0.512500,0.100000,0.100000},{0.012500,0.537500,0.050000,0.050000},{0.012500,0.537500,0.100000,0.100000},{0.037500,0.537500,0.050000,0.050000},{0.037500,0.537500,0.100000,0.100000},{0.062500,0.537500,0.050000,0.050000},{0.062500,0.537500,0.100000,0.100000},{0.087500,0.537500,0.050000,0.050000},{0.087500,0.537500,0.100000,0.100000},{0.112500,0.537500,0.050000,0.050000},{0.112500,0.537500,0.100000,0.100000},{0.137500,0.537500,0.050000,0.050000},{0.137500,0.537500,0.100000,0.100000},{0.162500,0.537500,0.050000,0.050000},{0.162500,0.537500,0.100000,0.100000},{0.187500,0.537500,0.050000,0.050000},{0.187500,0.537500,0.100000,0.100000},{0.212500,0.537500,0.050000,0.050000},{0.212500,0.537500,0.100000,0.100000},{0.237500,0.537500,0.050000,0.050000},{0.237500,0.537500,0.100000,0.100000},{0.262500,0.537500,0.050000,0.050000},{0.262500,0.537500,0.100000,0.100000},{0.287500,0.537500,0.050000,0.050000},{0.287500,0.537500,0.100000,0.100000},{0.312500,0.537500,0.050000,0.050000},{0.312500,0.537500,0.100000,0.100000},{0.337500,0.537500,0.050000,0.050000},{0.337500,0.537500,0.100000,0.100000},{0.362500,0.537500,0.050000,0.050000},{0.362500,0.537500,0.100000,0.100000},{0.387500,0.537500,0.050000,0.050000},{0.387500,0.537500,0.100000,0.100000},{0.412500,0.537500,0.050000,0.050000},{0.412500,0.537500,0.100000,0.100000},{0.437500,0.537500,0.050000,0.050000},{0.437500,0.537500,0.100000,0.100000},{0.462500,0.537500,0.050000,0.050000},{0.462500,0.537500,0.100000,0.100000},{0.487500,0.537500,0.050000,0.050000},{0.487500,0.537500,0.100000,0.100000},{0.512500,0.537500,0.050000,0.050000},{0.512500,0.537500,0.100000,0.100000},{0.537500,0.537500,0.050000,0.050000},{0.537500,0.537500,0.100000,0.100000},{0.562500,0.537500,0.050000,0.050000},{0.562500,0.537500,0.100000,0.100000},{0.587500,0.537500,0.050000,0.050000},{0.587500,0.537500,0.100000,0.100000},{0.612500,0.537500,0.050000,0.050000},{0.612500,0.537500,0.100000,0.100000},{0.637500,0.537500,0.050000,0.050000},{0.637500,0.537500,0.100000,0.100000},{0.662500,0.537500,0.050000,0.050000},{0.662500,0.537500,0.100000,0.100000},{0.687500,0.537500,0.050000,0.050000},{0.687500,0.537500,0.100000,0.100000},{0.712500,0.537500,0.050000,0.050000},{0.712500,0.537500,0.100000,0.100000},{0.737500,0.537500,0.050000,0.050000},{0.737500,0.537500,0.100000,0.100000},{0.762500,0.537500,0.050000,0.050000},{0.762500,0.537500,0.100000,0.100000},{0.787500,0.537500,0.050000,0.050000},{0.787500,0.537500,0.100000,0.100000},{0.812500,0.537500,0.050000,0.050000},{0.812500,0.537500,0.100000,0.100000},{0.837500,0.537500,0.050000,0.050000},{0.837500,0.537500,0.100000,0.100000},{0.862500,0.537500,0.050000,0.050000},{0.862500,0.537500,0.100000,0.100000},{0.887500,0.537500,0.050000,0.050000},{0.887500,0.537500,0.100000,0.100000},{0.912500,0.537500,0.050000,0.050000},{0.912500,0.537500,0.100000,0.100000},{0.937500,0.537500,0.050000,0.050000},{0.937500,0.537500,0.100000,0.100000},{0.962500,0.537500,0.050000,0.050000},{0.962500,0.537500,0.100000,0.100000},{0.987500,0.537500,0.050000,0.050000},{0.987500,0.537500,0.100000,0.100000},{0.012500,0.562500,0.050000,0.050000},{0.012500,0.562500,0.100000,0.100000},{0.037500,0.562500,0.050000,0.050000},{0.037500,0.562500,0.100000,0.100000},{0.062500,0.562500,0.050000,0.050000},{0.062500,0.562500,0.100000,0.100000},{0.087500,0.562500,0.050000,0.050000},{0.087500,0.562500,0.100000,0.100000},{0.112500,0.562500,0.050000,0.050000},{0.112500,0.562500,0.100000,0.100000},{0.137500,0.562500,0.050000,0.050000},{0.137500,0.562500,0.100000,0.100000},{0.162500,0.562500,0.050000,0.050000},{0.162500,0.562500,0.100000,0.100000},{0.187500,0.562500,0.050000,0.050000},{0.187500,0.562500,0.100000,0.100000},{0.212500,0.562500,0.050000,0.050000},{0.212500,0.562500,0.100000,0.100000},{0.237500,0.562500,0.050000,0.050000},{0.237500,0.562500,0.100000,0.100000},{0.262500,0.562500,0.050000,0.050000},{0.262500,0.562500,0.100000,0.100000},{0.287500,0.562500,0.050000,0.050000},{0.287500,0.562500,0.100000,0.100000},{0.312500,0.562500,0.050000,0.050000},{0.312500,0.562500,0.100000,0.100000},{0.337500,0.562500,0.050000,0.050000},{0.337500,0.562500,0.100000,0.100000},{0.362500,0.562500,0.050000,0.050000},{0.362500,0.562500,0.100000,0.100000},{0.387500,0.562500,0.050000,0.050000},{0.387500,0.562500,0.100000,0.100000},{0.412500,0.562500,0.050000,0.050000},{0.412500,0.562500,0.100000,0.100000},{0.437500,0.562500,0.050000,0.050000},{0.437500,0.562500,0.100000,0.100000},{0.462500,0.562500,0.050000,0.050000},{0.462500,0.562500,0.100000,0.100000},{0.487500,0.562500,0.050000,0.050000},{0.487500,0.562500,0.100000,0.100000},{0.512500,0.562500,0.050000,0.050000},{0.512500,0.562500,0.100000,0.100000},{0.537500,0.562500,0.050000,0.050000},{0.537500,0.562500,0.100000,0.100000},{0.562500,0.562500,0.050000,0.050000},{0.562500,0.562500,0.100000,0.100000},{0.587500,0.562500,0.050000,0.050000},{0.587500,0.562500,0.100000,0.100000},{0.612500,0.562500,0.050000,0.050000},{0.612500,0.562500,0.100000,0.100000},{0.637500,0.562500,0.050000,0.050000},{0.637500,0.562500,0.100000,0.100000},{0.662500,0.562500,0.050000,0.050000},{0.662500,0.562500,0.100000,0.100000},{0.687500,0.562500,0.050000,0.050000},{0.687500,0.562500,0.100000,0.100000},{0.712500,0.562500,0.050000,0.050000},{0.712500,0.562500,0.100000,0.100000},{0.737500,0.562500,0.050000,0.050000},{0.737500,0.562500,0.100000,0.100000},{0.762500,0.562500,0.050000,0.050000},{0.762500,0.562500,0.100000,0.100000},{0.787500,0.562500,0.050000,0.050000},{0.787500,0.562500,0.100000,0.100000},{0.812500,0.562500,0.050000,0.050000},{0.812500,0.562500,0.100000,0.100000},{0.837500,0.562500,0.050000,0.050000},{0.837500,0.562500,0.100000,0.100000},{0.862500,0.562500,0.050000,0.050000},{0.862500,0.562500,0.100000,0.100000},{0.887500,0.562500,0.050000,0.050000},{0.887500,0.562500,0.100000,0.100000},{0.912500,0.562500,0.050000,0.050000},{0.912500,0.562500,0.100000,0.100000},{0.937500,0.562500,0.050000,0.050000},{0.937500,0.562500,0.100000,0.100000},{0.962500,0.562500,0.050000,0.050000},{0.962500,0.562500,0.100000,0.100000},{0.987500,0.562500,0.050000,0.050000},{0.987500,0.562500,0.100000,0.100000},{0.012500,0.587500,0.050000,0.050000},{0.012500,0.587500,0.100000,0.100000},{0.037500,0.587500,0.050000,0.050000},{0.037500,0.587500,0.100000,0.100000},{0.062500,0.587500,0.050000,0.050000},{0.062500,0.587500,0.100000,0.100000},{0.087500,0.587500,0.050000,0.050000},{0.087500,0.587500,0.100000,0.100000},{0.112500,0.587500,0.050000,0.050000},{0.112500,0.587500,0.100000,0.100000},{0.137500,0.587500,0.050000,0.050000},{0.137500,0.587500,0.100000,0.100000},{0.162500,0.587500,0.050000,0.050000},{0.162500,0.587500,0.100000,0.100000},{0.187500,0.587500,0.050000,0.050000},{0.187500,0.587500,0.100000,0.100000},{0.212500,0.587500,0.050000,0.050000},{0.212500,0.587500,0.100000,0.100000},{0.237500,0.587500,0.050000,0.050000},{0.237500,0.587500,0.100000,0.100000},{0.262500,0.587500,0.050000,0.050000},{0.262500,0.587500,0.100000,0.100000},{0.287500,0.587500,0.050000,0.050000},{0.287500,0.587500,0.100000,0.100000},{0.312500,0.587500,0.050000,0.050000},{0.312500,0.587500,0.100000,0.100000},{0.337500,0.587500,0.050000,0.050000},{0.337500,0.587500,0.100000,0.100000},{0.362500,0.587500,0.050000,0.050000},{0.362500,0.587500,0.100000,0.100000},{0.387500,0.587500,0.050000,0.050000},{0.387500,0.587500,0.100000,0.100000},{0.412500,0.587500,0.050000,0.050000},{0.412500,0.587500,0.100000,0.100000},{0.437500,0.587500,0.050000,0.050000},{0.437500,0.587500,0.100000,0.100000},{0.462500,0.587500,0.050000,0.050000},{0.462500,0.587500,0.100000,0.100000},{0.487500,0.587500,0.050000,0.050000},{0.487500,0.587500,0.100000,0.100000},{0.512500,0.587500,0.050000,0.050000},{0.512500,0.587500,0.100000,0.100000},{0.537500,0.587500,0.050000,0.050000},{0.537500,0.587500,0.100000,0.100000},{0.562500,0.587500,0.050000,0.050000},{0.562500,0.587500,0.100000,0.100000},{0.587500,0.587500,0.050000,0.050000},{0.587500,0.587500,0.100000,0.100000},{0.612500,0.587500,0.050000,0.050000},{0.612500,0.587500,0.100000,0.100000},{0.637500,0.587500,0.050000,0.050000},{0.637500,0.587500,0.100000,0.100000},{0.662500,0.587500,0.050000,0.050000},{0.662500,0.587500,0.100000,0.100000},{0.687500,0.587500,0.050000,0.050000},{0.687500,0.587500,0.100000,0.100000},{0.712500,0.587500,0.050000,0.050000},{0.712500,0.587500,0.100000,0.100000},{0.737500,0.587500,0.050000,0.050000},{0.737500,0.587500,0.100000,0.100000},{0.762500,0.587500,0.050000,0.050000},{0.762500,0.587500,0.100000,0.100000},{0.787500,0.587500,0.050000,0.050000},{0.787500,0.587500,0.100000,0.100000},{0.812500,0.587500,0.050000,0.050000},{0.812500,0.587500,0.100000,0.100000},{0.837500,0.587500,0.050000,0.050000},{0.837500,0.587500,0.100000,0.100000},{0.862500,0.587500,0.050000,0.050000},{0.862500,0.587500,0.100000,0.100000},{0.887500,0.587500,0.050000,0.050000},{0.887500,0.587500,0.100000,0.100000},{0.912500,0.587500,0.050000,0.050000},{0.912500,0.587500,0.100000,0.100000},{0.937500,0.587500,0.050000,0.050000},{0.937500,0.587500,0.100000,0.100000},{0.962500,0.587500,0.050000,0.050000},{0.962500,0.587500,0.100000,0.100000},{0.987500,0.587500,0.050000,0.050000},{0.987500,0.587500,0.100000,0.100000},{0.012500,0.612500,0.050000,0.050000},{0.012500,0.612500,0.100000,0.100000},{0.037500,0.612500,0.050000,0.050000},{0.037500,0.612500,0.100000,0.100000},{0.062500,0.612500,0.050000,0.050000},{0.062500,0.612500,0.100000,0.100000},{0.087500,0.612500,0.050000,0.050000},{0.087500,0.612500,0.100000,0.100000},{0.112500,0.612500,0.050000,0.050000},{0.112500,0.612500,0.100000,0.100000},{0.137500,0.612500,0.050000,0.050000},{0.137500,0.612500,0.100000,0.100000},{0.162500,0.612500,0.050000,0.050000},{0.162500,0.612500,0.100000,0.100000},{0.187500,0.612500,0.050000,0.050000},{0.187500,0.612500,0.100000,0.100000},{0.212500,0.612500,0.050000,0.050000},{0.212500,0.612500,0.100000,0.100000},{0.237500,0.612500,0.050000,0.050000},{0.237500,0.612500,0.100000,0.100000},{0.262500,0.612500,0.050000,0.050000},{0.262500,0.612500,0.100000,0.100000},{0.287500,0.612500,0.050000,0.050000},{0.287500,0.612500,0.100000,0.100000},{0.312500,0.612500,0.050000,0.050000},{0.312500,0.612500,0.100000,0.100000},{0.337500,0.612500,0.050000,0.050000},{0.337500,0.612500,0.100000,0.100000},{0.362500,0.612500,0.050000,0.050000},{0.362500,0.612500,0.100000,0.100000},{0.387500,0.612500,0.050000,0.050000},{0.387500,0.612500,0.100000,0.100000},{0.412500,0.612500,0.050000,0.050000},{0.412500,0.612500,0.100000,0.100000},{0.437500,0.612500,0.050000,0.050000},{0.437500,0.612500,0.100000,0.100000},{0.462500,0.612500,0.050000,0.050000},{0.462500,0.612500,0.100000,0.100000},{0.487500,0.612500,0.050000,0.050000},{0.487500,0.612500,0.100000,0.100000},{0.512500,0.612500,0.050000,0.050000},{0.512500,0.612500,0.100000,0.100000},{0.537500,0.612500,0.050000,0.050000},{0.537500,0.612500,0.100000,0.100000},{0.562500,0.612500,0.050000,0.050000},{0.562500,0.612500,0.100000,0.100000},{0.587500,0.612500,0.050000,0.050000},{0.587500,0.612500,0.100000,0.100000},{0.612500,0.612500,0.050000,0.050000},{0.612500,0.612500,0.100000,0.100000},{0.637500,0.612500,0.050000,0.050000},{0.637500,0.612500,0.100000,0.100000},{0.662500,0.612500,0.050000,0.050000},{0.662500,0.612500,0.100000,0.100000},{0.687500,0.612500,0.050000,0.050000},{0.687500,0.612500,0.100000,0.100000},{0.712500,0.612500,0.050000,0.050000},{0.712500,0.612500,0.100000,0.100000},{0.737500,0.612500,0.050000,0.050000},{0.737500,0.612500,0.100000,0.100000},{0.762500,0.612500,0.050000,0.050000},{0.762500,0.612500,0.100000,0.100000},{0.787500,0.612500,0.050000,0.050000},{0.787500,0.612500,0.100000,0.100000},{0.812500,0.612500,0.050000,0.050000},{0.812500,0.612500,0.100000,0.100000},{0.837500,0.612500,0.050000,0.050000},{0.837500,0.612500,0.100000,0.100000},{0.862500,0.612500,0.050000,0.050000},{0.862500,0.612500,0.100000,0.100000},{0.887500,0.612500,0.050000,0.050000},{0.887500,0.612500,0.100000,0.100000},{0.912500,0.612500,0.050000,0.050000},{0.912500,0.612500,0.100000,0.100000},{0.937500,0.612500,0.050000,0.050000},{0.937500,0.612500,0.100000,0.100000},{0.962500,0.612500,0.050000,0.050000},{0.962500,0.612500,0.100000,0.100000},{0.987500,0.612500,0.050000,0.050000},{0.987500,0.612500,0.100000,0.100000},{0.012500,0.637500,0.050000,0.050000},{0.012500,0.637500,0.100000,0.100000},{0.037500,0.637500,0.050000,0.050000},{0.037500,0.637500,0.100000,0.100000},{0.062500,0.637500,0.050000,0.050000},{0.062500,0.637500,0.100000,0.100000},{0.087500,0.637500,0.050000,0.050000},{0.087500,0.637500,0.100000,0.100000},{0.112500,0.637500,0.050000,0.050000},{0.112500,0.637500,0.100000,0.100000},{0.137500,0.637500,0.050000,0.050000},{0.137500,0.637500,0.100000,0.100000},{0.162500,0.637500,0.050000,0.050000},{0.162500,0.637500,0.100000,0.100000},{0.187500,0.637500,0.050000,0.050000},{0.187500,0.637500,0.100000,0.100000},{0.212500,0.637500,0.050000,0.050000},{0.212500,0.637500,0.100000,0.100000},{0.237500,0.637500,0.050000,0.050000},{0.237500,0.637500,0.100000,0.100000},{0.262500,0.637500,0.050000,0.050000},{0.262500,0.637500,0.100000,0.100000},{0.287500,0.637500,0.050000,0.050000},{0.287500,0.637500,0.100000,0.100000},{0.312500,0.637500,0.050000,0.050000},{0.312500,0.637500,0.100000,0.100000},{0.337500,0.637500,0.050000,0.050000},{0.337500,0.637500,0.100000,0.100000},{0.362500,0.637500,0.050000,0.050000},{0.362500,0.637500,0.100000,0.100000},{0.387500,0.637500,0.050000,0.050000},{0.387500,0.637500,0.100000,0.100000},{0.412500,0.637500,0.050000,0.050000},{0.412500,0.637500,0.100000,0.100000},{0.437500,0.637500,0.050000,0.050000},{0.437500,0.637500,0.100000,0.100000},{0.462500,0.637500,0.050000,0.050000},{0.462500,0.637500,0.100000,0.100000},{0.487500,0.637500,0.050000,0.050000},{0.487500,0.637500,0.100000,0.100000},{0.512500,0.637500,0.050000,0.050000},{0.512500,0.637500,0.100000,0.100000},{0.537500,0.637500,0.050000,0.050000},{0.537500,0.637500,0.100000,0.100000},{0.562500,0.637500,0.050000,0.050000},{0.562500,0.637500,0.100000,0.100000},{0.587500,0.637500,0.050000,0.050000},{0.587500,0.637500,0.100000,0.100000},{0.612500,0.637500,0.050000,0.050000},{0.612500,0.637500,0.100000,0.100000},{0.637500,0.637500,0.050000,0.050000},{0.637500,0.637500,0.100000,0.100000},{0.662500,0.637500,0.050000,0.050000},{0.662500,0.637500,0.100000,0.100000},{0.687500,0.637500,0.050000,0.050000},{0.687500,0.637500,0.100000,0.100000},{0.712500,0.637500,0.050000,0.050000},{0.712500,0.637500,0.100000,0.100000},{0.737500,0.637500,0.050000,0.050000},{0.737500,0.637500,0.100000,0.100000},{0.762500,0.637500,0.050000,0.050000},{0.762500,0.637500,0.100000,0.100000},{0.787500,0.637500,0.050000,0.050000},{0.787500,0.637500,0.100000,0.100000},{0.812500,0.637500,0.050000,0.050000},{0.812500,0.637500,0.100000,0.100000},{0.837500,0.637500,0.050000,0.050000},{0.837500,0.637500,0.100000,0.100000},{0.862500,0.637500,0.050000,0.050000},{0.862500,0.637500,0.100000,0.100000},{0.887500,0.637500,0.050000,0.050000},{0.887500,0.637500,0.100000,0.100000},{0.912500,0.637500,0.050000,0.050000},{0.912500,0.637500,0.100000,0.100000},{0.937500,0.637500,0.050000,0.050000},{0.937500,0.637500,0.100000,0.100000},{0.962500,0.637500,0.050000,0.050000},{0.962500,0.637500,0.100000,0.100000},{0.987500,0.637500,0.050000,0.050000},{0.987500,0.637500,0.100000,0.100000},{0.012500,0.662500,0.050000,0.050000},{0.012500,0.662500,0.100000,0.100000},{0.037500,0.662500,0.050000,0.050000},{0.037500,0.662500,0.100000,0.100000},{0.062500,0.662500,0.050000,0.050000},{0.062500,0.662500,0.100000,0.100000},{0.087500,0.662500,0.050000,0.050000},{0.087500,0.662500,0.100000,0.100000},{0.112500,0.662500,0.050000,0.050000},{0.112500,0.662500,0.100000,0.100000},{0.137500,0.662500,0.050000,0.050000},{0.137500,0.662500,0.100000,0.100000},{0.162500,0.662500,0.050000,0.050000},{0.162500,0.662500,0.100000,0.100000},{0.187500,0.662500,0.050000,0.050000},{0.187500,0.662500,0.100000,0.100000},{0.212500,0.662500,0.050000,0.050000},{0.212500,0.662500,0.100000,0.100000},{0.237500,0.662500,0.050000,0.050000},{0.237500,0.662500,0.100000,0.100000},{0.262500,0.662500,0.050000,0.050000},{0.262500,0.662500,0.100000,0.100000},{0.287500,0.662500,0.050000,0.050000},{0.287500,0.662500,0.100000,0.100000},{0.312500,0.662500,0.050000,0.050000},{0.312500,0.662500,0.100000,0.100000},{0.337500,0.662500,0.050000,0.050000},{0.337500,0.662500,0.100000,0.100000},{0.362500,0.662500,0.050000,0.050000},{0.362500,0.662500,0.100000,0.100000},{0.387500,0.662500,0.050000,0.050000},{0.387500,0.662500,0.100000,0.100000},{0.412500,0.662500,0.050000,0.050000},{0.412500,0.662500,0.100000,0.100000},{0.437500,0.662500,0.050000,0.050000},{0.437500,0.662500,0.100000,0.100000},{0.462500,0.662500,0.050000,0.050000},{0.462500,0.662500,0.100000,0.100000},{0.487500,0.662500,0.050000,0.050000},{0.487500,0.662500,0.100000,0.100000},{0.512500,0.662500,0.050000,0.050000},{0.512500,0.662500,0.100000,0.100000},{0.537500,0.662500,0.050000,0.050000},{0.537500,0.662500,0.100000,0.100000},{0.562500,0.662500,0.050000,0.050000},{0.562500,0.662500,0.100000,0.100000},{0.587500,0.662500,0.050000,0.050000},{0.587500,0.662500,0.100000,0.100000},{0.612500,0.662500,0.050000,0.050000},{0.612500,0.662500,0.100000,0.100000},{0.637500,0.662500,0.050000,0.050000},{0.637500,0.662500,0.100000,0.100000},{0.662500,0.662500,0.050000,0.050000},{0.662500,0.662500,0.100000,0.100000},{0.687500,0.662500,0.050000,0.050000},{0.687500,0.662500,0.100000,0.100000},{0.712500,0.662500,0.050000,0.050000},{0.712500,0.662500,0.100000,0.100000},{0.737500,0.662500,0.050000,0.050000},{0.737500,0.662500,0.100000,0.100000},{0.762500,0.662500,0.050000,0.050000},{0.762500,0.662500,0.100000,0.100000},{0.787500,0.662500,0.050000,0.050000},{0.787500,0.662500,0.100000,0.100000},{0.812500,0.662500,0.050000,0.050000},{0.812500,0.662500,0.100000,0.100000},{0.837500,0.662500,0.050000,0.050000},{0.837500,0.662500,0.100000,0.100000},{0.862500,0.662500,0.050000,0.050000},{0.862500,0.662500,0.100000,0.100000},{0.887500,0.662500,0.050000,0.050000},{0.887500,0.662500,0.100000,0.100000},{0.912500,0.662500,0.050000,0.050000},{0.912500,0.662500,0.100000,0.100000},{0.937500,0.662500,0.050000,0.050000},{0.937500,0.662500,0.100000,0.100000},{0.962500,0.662500,0.050000,0.050000},{0.962500,0.662500,0.100000,0.100000},{0.987500,0.662500,0.050000,0.050000},{0.987500,0.662500,0.100000,0.100000},{0.012500,0.687500,0.050000,0.050000},{0.012500,0.687500,0.100000,0.100000},{0.037500,0.687500,0.050000,0.050000},{0.037500,0.687500,0.100000,0.100000},{0.062500,0.687500,0.050000,0.050000},{0.062500,0.687500,0.100000,0.100000},{0.087500,0.687500,0.050000,0.050000},{0.087500,0.687500,0.100000,0.100000},{0.112500,0.687500,0.050000,0.050000},{0.112500,0.687500,0.100000,0.100000},{0.137500,0.687500,0.050000,0.050000},{0.137500,0.687500,0.100000,0.100000},{0.162500,0.687500,0.050000,0.050000},{0.162500,0.687500,0.100000,0.100000},{0.187500,0.687500,0.050000,0.050000},{0.187500,0.687500,0.100000,0.100000},{0.212500,0.687500,0.050000,0.050000},{0.212500,0.687500,0.100000,0.100000},{0.237500,0.687500,0.050000,0.050000},{0.237500,0.687500,0.100000,0.100000},{0.262500,0.687500,0.050000,0.050000},{0.262500,0.687500,0.100000,0.100000},{0.287500,0.687500,0.050000,0.050000},{0.287500,0.687500,0.100000,0.100000},{0.312500,0.687500,0.050000,0.050000},{0.312500,0.687500,0.100000,0.100000},{0.337500,0.687500,0.050000,0.050000},{0.337500,0.687500,0.100000,0.100000},{0.362500,0.687500,0.050000,0.050000},{0.362500,0.687500,0.100000,0.100000},{0.387500,0.687500,0.050000,0.050000},{0.387500,0.687500,0.100000,0.100000},{0.412500,0.687500,0.050000,0.050000},{0.412500,0.687500,0.100000,0.100000},{0.437500,0.687500,0.050000,0.050000},{0.437500,0.687500,0.100000,0.100000},{0.462500,0.687500,0.050000,0.050000},{0.462500,0.687500,0.100000,0.100000},{0.487500,0.687500,0.050000,0.050000},{0.487500,0.687500,0.100000,0.100000},{0.512500,0.687500,0.050000,0.050000},{0.512500,0.687500,0.100000,0.100000},{0.537500,0.687500,0.050000,0.050000},{0.537500,0.687500,0.100000,0.100000},{0.562500,0.687500,0.050000,0.050000},{0.562500,0.687500,0.100000,0.100000},{0.587500,0.687500,0.050000,0.050000},{0.587500,0.687500,0.100000,0.100000},{0.612500,0.687500,0.050000,0.050000},{0.612500,0.687500,0.100000,0.100000},{0.637500,0.687500,0.050000,0.050000},{0.637500,0.687500,0.100000,0.100000},{0.662500,0.687500,0.050000,0.050000},{0.662500,0.687500,0.100000,0.100000},{0.687500,0.687500,0.050000,0.050000},{0.687500,0.687500,0.100000,0.100000},{0.712500,0.687500,0.050000,0.050000},{0.712500,0.687500,0.100000,0.100000},{0.737500,0.687500,0.050000,0.050000},{0.737500,0.687500,0.100000,0.100000},{0.762500,0.687500,0.050000,0.050000},{0.762500,0.687500,0.100000,0.100000},{0.787500,0.687500,0.050000,0.050000},{0.787500,0.687500,0.100000,0.100000},{0.812500,0.687500,0.050000,0.050000},{0.812500,0.687500,0.100000,0.100000},{0.837500,0.687500,0.050000,0.050000},{0.837500,0.687500,0.100000,0.100000},{0.862500,0.687500,0.050000,0.050000},{0.862500,0.687500,0.100000,0.100000},{0.887500,0.687500,0.050000,0.050000},{0.887500,0.687500,0.100000,0.100000},{0.912500,0.687500,0.050000,0.050000},{0.912500,0.687500,0.100000,0.100000},{0.937500,0.687500,0.050000,0.050000},{0.937500,0.687500,0.100000,0.100000},{0.962500,0.687500,0.050000,0.050000},{0.962500,0.687500,0.100000,0.100000},{0.987500,0.687500,0.050000,0.050000},{0.987500,0.687500,0.100000,0.100000},{0.012500,0.712500,0.050000,0.050000},{0.012500,0.712500,0.100000,0.100000},{0.037500,0.712500,0.050000,0.050000},{0.037500,0.712500,0.100000,0.100000},{0.062500,0.712500,0.050000,0.050000},{0.062500,0.712500,0.100000,0.100000},{0.087500,0.712500,0.050000,0.050000},{0.087500,0.712500,0.100000,0.100000},{0.112500,0.712500,0.050000,0.050000},{0.112500,0.712500,0.100000,0.100000},{0.137500,0.712500,0.050000,0.050000},{0.137500,0.712500,0.100000,0.100000},{0.162500,0.712500,0.050000,0.050000},{0.162500,0.712500,0.100000,0.100000},{0.187500,0.712500,0.050000,0.050000},{0.187500,0.712500,0.100000,0.100000},{0.212500,0.712500,0.050000,0.050000},{0.212500,0.712500,0.100000,0.100000},{0.237500,0.712500,0.050000,0.050000},{0.237500,0.712500,0.100000,0.100000},{0.262500,0.712500,0.050000,0.050000},{0.262500,0.712500,0.100000,0.100000},{0.287500,0.712500,0.050000,0.050000},{0.287500,0.712500,0.100000,0.100000},{0.312500,0.712500,0.050000,0.050000},{0.312500,0.712500,0.100000,0.100000},{0.337500,0.712500,0.050000,0.050000},{0.337500,0.712500,0.100000,0.100000},{0.362500,0.712500,0.050000,0.050000},{0.362500,0.712500,0.100000,0.100000},{0.387500,0.712500,0.050000,0.050000},{0.387500,0.712500,0.100000,0.100000},{0.412500,0.712500,0.050000,0.050000},{0.412500,0.712500,0.100000,0.100000},{0.437500,0.712500,0.050000,0.050000},{0.437500,0.712500,0.100000,0.100000},{0.462500,0.712500,0.050000,0.050000},{0.462500,0.712500,0.100000,0.100000},{0.487500,0.712500,0.050000,0.050000},{0.487500,0.712500,0.100000,0.100000},{0.512500,0.712500,0.050000,0.050000},{0.512500,0.712500,0.100000,0.100000},{0.537500,0.712500,0.050000,0.050000},{0.537500,0.712500,0.100000,0.100000},{0.562500,0.712500,0.050000,0.050000},{0.562500,0.712500,0.100000,0.100000},{0.587500,0.712500,0.050000,0.050000},{0.587500,0.712500,0.100000,0.100000},{0.612500,0.712500,0.050000,0.050000},{0.612500,0.712500,0.100000,0.100000},{0.637500,0.712500,0.050000,0.050000},{0.637500,0.712500,0.100000,0.100000},{0.662500,0.712500,0.050000,0.050000},{0.662500,0.712500,0.100000,0.100000},{0.687500,0.712500,0.050000,0.050000},{0.687500,0.712500,0.100000,0.100000},{0.712500,0.712500,0.050000,0.050000},{0.712500,0.712500,0.100000,0.100000},{0.737500,0.712500,0.050000,0.050000},{0.737500,0.712500,0.100000,0.100000},{0.762500,0.712500,0.050000,0.050000},{0.762500,0.712500,0.100000,0.100000},{0.787500,0.712500,0.050000,0.050000},{0.787500,0.712500,0.100000,0.100000},{0.812500,0.712500,0.050000,0.050000},{0.812500,0.712500,0.100000,0.100000},{0.837500,0.712500,0.050000,0.050000},{0.837500,0.712500,0.100000,0.100000},{0.862500,0.712500,0.050000,0.050000},{0.862500,0.712500,0.100000,0.100000},{0.887500,0.712500,0.050000,0.050000},{0.887500,0.712500,0.100000,0.100000},{0.912500,0.712500,0.050000,0.050000},{0.912500,0.712500,0.100000,0.100000},{0.937500,0.712500,0.050000,0.050000},{0.937500,0.712500,0.100000,0.100000},{0.962500,0.712500,0.050000,0.050000},{0.962500,0.712500,0.100000,0.100000},{0.987500,0.712500,0.050000,0.050000},{0.987500,0.712500,0.100000,0.100000},{0.012500,0.737500,0.050000,0.050000},{0.012500,0.737500,0.100000,0.100000},{0.037500,0.737500,0.050000,0.050000},{0.037500,0.737500,0.100000,0.100000},{0.062500,0.737500,0.050000,0.050000},{0.062500,0.737500,0.100000,0.100000},{0.087500,0.737500,0.050000,0.050000},{0.087500,0.737500,0.100000,0.100000},{0.112500,0.737500,0.050000,0.050000},{0.112500,0.737500,0.100000,0.100000},{0.137500,0.737500,0.050000,0.050000},{0.137500,0.737500,0.100000,0.100000},{0.162500,0.737500,0.050000,0.050000},{0.162500,0.737500,0.100000,0.100000},{0.187500,0.737500,0.050000,0.050000},{0.187500,0.737500,0.100000,0.100000},{0.212500,0.737500,0.050000,0.050000},{0.212500,0.737500,0.100000,0.100000},{0.237500,0.737500,0.050000,0.050000},{0.237500,0.737500,0.100000,0.100000},{0.262500,0.737500,0.050000,0.050000},{0.262500,0.737500,0.100000,0.100000},{0.287500,0.737500,0.050000,0.050000},{0.287500,0.737500,0.100000,0.100000},{0.312500,0.737500,0.050000,0.050000},{0.312500,0.737500,0.100000,0.100000},{0.337500,0.737500,0.050000,0.050000},{0.337500,0.737500,0.100000,0.100000},{0.362500,0.737500,0.050000,0.050000},{0.362500,0.737500,0.100000,0.100000},{0.387500,0.737500,0.050000,0.050000},{0.387500,0.737500,0.100000,0.100000},{0.412500,0.737500,0.050000,0.050000},{0.412500,0.737500,0.100000,0.100000},{0.437500,0.737500,0.050000,0.050000},{0.437500,0.737500,0.100000,0.100000},{0.462500,0.737500,0.050000,0.050000},{0.462500,0.737500,0.100000,0.100000},{0.487500,0.737500,0.050000,0.050000},{0.487500,0.737500,0.100000,0.100000},{0.512500,0.737500,0.050000,0.050000},{0.512500,0.737500,0.100000,0.100000},{0.537500,0.737500,0.050000,0.050000},{0.537500,0.737500,0.100000,0.100000},{0.562500,0.737500,0.050000,0.050000},{0.562500,0.737500,0.100000,0.100000},{0.587500,0.737500,0.050000,0.050000},{0.587500,0.737500,0.100000,0.100000},{0.612500,0.737500,0.050000,0.050000},{0.612500,0.737500,0.100000,0.100000},{0.637500,0.737500,0.050000,0.050000},{0.637500,0.737500,0.100000,0.100000},{0.662500,0.737500,0.050000,0.050000},{0.662500,0.737500,0.100000,0.100000},{0.687500,0.737500,0.050000,0.050000},{0.687500,0.737500,0.100000,0.100000},{0.712500,0.737500,0.050000,0.050000},{0.712500,0.737500,0.100000,0.100000},{0.737500,0.737500,0.050000,0.050000},{0.737500,0.737500,0.100000,0.100000},{0.762500,0.737500,0.050000,0.050000},{0.762500,0.737500,0.100000,0.100000},{0.787500,0.737500,0.050000,0.050000},{0.787500,0.737500,0.100000,0.100000},{0.812500,0.737500,0.050000,0.050000},{0.812500,0.737500,0.100000,0.100000},{0.837500,0.737500,0.050000,0.050000},{0.837500,0.737500,0.100000,0.100000},{0.862500,0.737500,0.050000,0.050000},{0.862500,0.737500,0.100000,0.100000},{0.887500,0.737500,0.050000,0.050000},{0.887500,0.737500,0.100000,0.100000},{0.912500,0.737500,0.050000,0.050000},{0.912500,0.737500,0.100000,0.100000},{0.937500,0.737500,0.050000,0.050000},{0.937500,0.737500,0.100000,0.100000},{0.962500,0.737500,0.050000,0.050000},{0.962500,0.737500,0.100000,0.100000},{0.987500,0.737500,0.050000,0.050000},{0.987500,0.737500,0.100000,0.100000},{0.012500,0.762500,0.050000,0.050000},{0.012500,0.762500,0.100000,0.100000},{0.037500,0.762500,0.050000,0.050000},{0.037500,0.762500,0.100000,0.100000},{0.062500,0.762500,0.050000,0.050000},{0.062500,0.762500,0.100000,0.100000},{0.087500,0.762500,0.050000,0.050000},{0.087500,0.762500,0.100000,0.100000},{0.112500,0.762500,0.050000,0.050000},{0.112500,0.762500,0.100000,0.100000},{0.137500,0.762500,0.050000,0.050000},{0.137500,0.762500,0.100000,0.100000},{0.162500,0.762500,0.050000,0.050000},{0.162500,0.762500,0.100000,0.100000},{0.187500,0.762500,0.050000,0.050000},{0.187500,0.762500,0.100000,0.100000},{0.212500,0.762500,0.050000,0.050000},{0.212500,0.762500,0.100000,0.100000},{0.237500,0.762500,0.050000,0.050000},{0.237500,0.762500,0.100000,0.100000},{0.262500,0.762500,0.050000,0.050000},{0.262500,0.762500,0.100000,0.100000},{0.287500,0.762500,0.050000,0.050000},{0.287500,0.762500,0.100000,0.100000},{0.312500,0.762500,0.050000,0.050000},{0.312500,0.762500,0.100000,0.100000},{0.337500,0.762500,0.050000,0.050000},{0.337500,0.762500,0.100000,0.100000},{0.362500,0.762500,0.050000,0.050000},{0.362500,0.762500,0.100000,0.100000},{0.387500,0.762500,0.050000,0.050000},{0.387500,0.762500,0.100000,0.100000},{0.412500,0.762500,0.050000,0.050000},{0.412500,0.762500,0.100000,0.100000},{0.437500,0.762500,0.050000,0.050000},{0.437500,0.762500,0.100000,0.100000},{0.462500,0.762500,0.050000,0.050000},{0.462500,0.762500,0.100000,0.100000},{0.487500,0.762500,0.050000,0.050000},{0.487500,0.762500,0.100000,0.100000},{0.512500,0.762500,0.050000,0.050000},{0.512500,0.762500,0.100000,0.100000},{0.537500,0.762500,0.050000,0.050000},{0.537500,0.762500,0.100000,0.100000},{0.562500,0.762500,0.050000,0.050000},{0.562500,0.762500,0.100000,0.100000},{0.587500,0.762500,0.050000,0.050000},{0.587500,0.762500,0.100000,0.100000},{0.612500,0.762500,0.050000,0.050000},{0.612500,0.762500,0.100000,0.100000},{0.637500,0.762500,0.050000,0.050000},{0.637500,0.762500,0.100000,0.100000},{0.662500,0.762500,0.050000,0.050000},{0.662500,0.762500,0.100000,0.100000},{0.687500,0.762500,0.050000,0.050000},{0.687500,0.762500,0.100000,0.100000},{0.712500,0.762500,0.050000,0.050000},{0.712500,0.762500,0.100000,0.100000},{0.737500,0.762500,0.050000,0.050000},{0.737500,0.762500,0.100000,0.100000},{0.762500,0.762500,0.050000,0.050000},{0.762500,0.762500,0.100000,0.100000},{0.787500,0.762500,0.050000,0.050000},{0.787500,0.762500,0.100000,0.100000},{0.812500,0.762500,0.050000,0.050000},{0.812500,0.762500,0.100000,0.100000},{0.837500,0.762500,0.050000,0.050000},{0.837500,0.762500,0.100000,0.100000},{0.862500,0.762500,0.050000,0.050000},{0.862500,0.762500,0.100000,0.100000},{0.887500,0.762500,0.050000,0.050000},{0.887500,0.762500,0.100000,0.100000},{0.912500,0.762500,0.050000,0.050000},{0.912500,0.762500,0.100000,0.100000},{0.937500,0.762500,0.050000,0.050000},{0.937500,0.762500,0.100000,0.100000},{0.962500,0.762500,0.050000,0.050000},{0.962500,0.762500,0.100000,0.100000},{0.987500,0.762500,0.050000,0.050000},{0.987500,0.762500,0.100000,0.100000},{0.012500,0.787500,0.050000,0.050000},{0.012500,0.787500,0.100000,0.100000},{0.037500,0.787500,0.050000,0.050000},{0.037500,0.787500,0.100000,0.100000},{0.062500,0.787500,0.050000,0.050000},{0.062500,0.787500,0.100000,0.100000},{0.087500,0.787500,0.050000,0.050000},{0.087500,0.787500,0.100000,0.100000},{0.112500,0.787500,0.050000,0.050000},{0.112500,0.787500,0.100000,0.100000},{0.137500,0.787500,0.050000,0.050000},{0.137500,0.787500,0.100000,0.100000},{0.162500,0.787500,0.050000,0.050000},{0.162500,0.787500,0.100000,0.100000},{0.187500,0.787500,0.050000,0.050000},{0.187500,0.787500,0.100000,0.100000},{0.212500,0.787500,0.050000,0.050000},{0.212500,0.787500,0.100000,0.100000},{0.237500,0.787500,0.050000,0.050000},{0.237500,0.787500,0.100000,0.100000},{0.262500,0.787500,0.050000,0.050000},{0.262500,0.787500,0.100000,0.100000},{0.287500,0.787500,0.050000,0.050000},{0.287500,0.787500,0.100000,0.100000},{0.312500,0.787500,0.050000,0.050000},{0.312500,0.787500,0.100000,0.100000},{0.337500,0.787500,0.050000,0.050000},{0.337500,0.787500,0.100000,0.100000},{0.362500,0.787500,0.050000,0.050000},{0.362500,0.787500,0.100000,0.100000},{0.387500,0.787500,0.050000,0.050000},{0.387500,0.787500,0.100000,0.100000},{0.412500,0.787500,0.050000,0.050000},{0.412500,0.787500,0.100000,0.100000},{0.437500,0.787500,0.050000,0.050000},{0.437500,0.787500,0.100000,0.100000},{0.462500,0.787500,0.050000,0.050000},{0.462500,0.787500,0.100000,0.100000},{0.487500,0.787500,0.050000,0.050000},{0.487500,0.787500,0.100000,0.100000},{0.512500,0.787500,0.050000,0.050000},{0.512500,0.787500,0.100000,0.100000},{0.537500,0.787500,0.050000,0.050000},{0.537500,0.787500,0.100000,0.100000},{0.562500,0.787500,0.050000,0.050000},{0.562500,0.787500,0.100000,0.100000},{0.587500,0.787500,0.050000,0.050000},{0.587500,0.787500,0.100000,0.100000},{0.612500,0.787500,0.050000,0.050000},{0.612500,0.787500,0.100000,0.100000},{0.637500,0.787500,0.050000,0.050000},{0.637500,0.787500,0.100000,0.100000},{0.662500,0.787500,0.050000,0.050000},{0.662500,0.787500,0.100000,0.100000},{0.687500,0.787500,0.050000,0.050000},{0.687500,0.787500,0.100000,0.100000},{0.712500,0.787500,0.050000,0.050000},{0.712500,0.787500,0.100000,0.100000},{0.737500,0.787500,0.050000,0.050000},{0.737500,0.787500,0.100000,0.100000},{0.762500,0.787500,0.050000,0.050000},{0.762500,0.787500,0.100000,0.100000},{0.787500,0.787500,0.050000,0.050000},{0.787500,0.787500,0.100000,0.100000},{0.812500,0.787500,0.050000,0.050000},{0.812500,0.787500,0.100000,0.100000},{0.837500,0.787500,0.050000,0.050000},{0.837500,0.787500,0.100000,0.100000},{0.862500,0.787500,0.050000,0.050000},{0.862500,0.787500,0.100000,0.100000},{0.887500,0.787500,0.050000,0.050000},{0.887500,0.787500,0.100000,0.100000},{0.912500,0.787500,0.050000,0.050000},{0.912500,0.787500,0.100000,0.100000},{0.937500,0.787500,0.050000,0.050000},{0.937500,0.787500,0.100000,0.100000},{0.962500,0.787500,0.050000,0.050000},{0.962500,0.787500,0.100000,0.100000},{0.987500,0.787500,0.050000,0.050000},{0.987500,0.787500,0.100000,0.100000},{0.012500,0.812500,0.050000,0.050000},{0.012500,0.812500,0.100000,0.100000},{0.037500,0.812500,0.050000,0.050000},{0.037500,0.812500,0.100000,0.100000},{0.062500,0.812500,0.050000,0.050000},{0.062500,0.812500,0.100000,0.100000},{0.087500,0.812500,0.050000,0.050000},{0.087500,0.812500,0.100000,0.100000},{0.112500,0.812500,0.050000,0.050000},{0.112500,0.812500,0.100000,0.100000},{0.137500,0.812500,0.050000,0.050000},{0.137500,0.812500,0.100000,0.100000},{0.162500,0.812500,0.050000,0.050000},{0.162500,0.812500,0.100000,0.100000},{0.187500,0.812500,0.050000,0.050000},{0.187500,0.812500,0.100000,0.100000},{0.212500,0.812500,0.050000,0.050000},{0.212500,0.812500,0.100000,0.100000},{0.237500,0.812500,0.050000,0.050000},{0.237500,0.812500,0.100000,0.100000},{0.262500,0.812500,0.050000,0.050000},{0.262500,0.812500,0.100000,0.100000},{0.287500,0.812500,0.050000,0.050000},{0.287500,0.812500,0.100000,0.100000},{0.312500,0.812500,0.050000,0.050000},{0.312500,0.812500,0.100000,0.100000},{0.337500,0.812500,0.050000,0.050000},{0.337500,0.812500,0.100000,0.100000},{0.362500,0.812500,0.050000,0.050000},{0.362500,0.812500,0.100000,0.100000},{0.387500,0.812500,0.050000,0.050000},{0.387500,0.812500,0.100000,0.100000},{0.412500,0.812500,0.050000,0.050000},{0.412500,0.812500,0.100000,0.100000},{0.437500,0.812500,0.050000,0.050000},{0.437500,0.812500,0.100000,0.100000},{0.462500,0.812500,0.050000,0.050000},{0.462500,0.812500,0.100000,0.100000},{0.487500,0.812500,0.050000,0.050000},{0.487500,0.812500,0.100000,0.100000},{0.512500,0.812500,0.050000,0.050000},{0.512500,0.812500,0.100000,0.100000},{0.537500,0.812500,0.050000,0.050000},{0.537500,0.812500,0.100000,0.100000},{0.562500,0.812500,0.050000,0.050000},{0.562500,0.812500,0.100000,0.100000},{0.587500,0.812500,0.050000,0.050000},{0.587500,0.812500,0.100000,0.100000},{0.612500,0.812500,0.050000,0.050000},{0.612500,0.812500,0.100000,0.100000},{0.637500,0.812500,0.050000,0.050000},{0.637500,0.812500,0.100000,0.100000},{0.662500,0.812500,0.050000,0.050000},{0.662500,0.812500,0.100000,0.100000},{0.687500,0.812500,0.050000,0.050000},{0.687500,0.812500,0.100000,0.100000},{0.712500,0.812500,0.050000,0.050000},{0.712500,0.812500,0.100000,0.100000},{0.737500,0.812500,0.050000,0.050000},{0.737500,0.812500,0.100000,0.100000},{0.762500,0.812500,0.050000,0.050000},{0.762500,0.812500,0.100000,0.100000},{0.787500,0.812500,0.050000,0.050000},{0.787500,0.812500,0.100000,0.100000},{0.812500,0.812500,0.050000,0.050000},{0.812500,0.812500,0.100000,0.100000},{0.837500,0.812500,0.050000,0.050000},{0.837500,0.812500,0.100000,0.100000},{0.862500,0.812500,0.050000,0.050000},{0.862500,0.812500,0.100000,0.100000},{0.887500,0.812500,0.050000,0.050000},{0.887500,0.812500,0.100000,0.100000},{0.912500,0.812500,0.050000,0.050000},{0.912500,0.812500,0.100000,0.100000},{0.937500,0.812500,0.050000,0.050000},{0.937500,0.812500,0.100000,0.100000},{0.962500,0.812500,0.050000,0.050000},{0.962500,0.812500,0.100000,0.100000},{0.987500,0.812500,0.050000,0.050000},{0.987500,0.812500,0.100000,0.100000},{0.012500,0.837500,0.050000,0.050000},{0.012500,0.837500,0.100000,0.100000},{0.037500,0.837500,0.050000,0.050000},{0.037500,0.837500,0.100000,0.100000},{0.062500,0.837500,0.050000,0.050000},{0.062500,0.837500,0.100000,0.100000},{0.087500,0.837500,0.050000,0.050000},{0.087500,0.837500,0.100000,0.100000},{0.112500,0.837500,0.050000,0.050000},{0.112500,0.837500,0.100000,0.100000},{0.137500,0.837500,0.050000,0.050000},{0.137500,0.837500,0.100000,0.100000},{0.162500,0.837500,0.050000,0.050000},{0.162500,0.837500,0.100000,0.100000},{0.187500,0.837500,0.050000,0.050000},{0.187500,0.837500,0.100000,0.100000},{0.212500,0.837500,0.050000,0.050000},{0.212500,0.837500,0.100000,0.100000},{0.237500,0.837500,0.050000,0.050000},{0.237500,0.837500,0.100000,0.100000},{0.262500,0.837500,0.050000,0.050000},{0.262500,0.837500,0.100000,0.100000},{0.287500,0.837500,0.050000,0.050000},{0.287500,0.837500,0.100000,0.100000},{0.312500,0.837500,0.050000,0.050000},{0.312500,0.837500,0.100000,0.100000},{0.337500,0.837500,0.050000,0.050000},{0.337500,0.837500,0.100000,0.100000},{0.362500,0.837500,0.050000,0.050000},{0.362500,0.837500,0.100000,0.100000},{0.387500,0.837500,0.050000,0.050000},{0.387500,0.837500,0.100000,0.100000},{0.412500,0.837500,0.050000,0.050000},{0.412500,0.837500,0.100000,0.100000},{0.437500,0.837500,0.050000,0.050000},{0.437500,0.837500,0.100000,0.100000},{0.462500,0.837500,0.050000,0.050000},{0.462500,0.837500,0.100000,0.100000},{0.487500,0.837500,0.050000,0.050000},{0.487500,0.837500,0.100000,0.100000},{0.512500,0.837500,0.050000,0.050000},{0.512500,0.837500,0.100000,0.100000},{0.537500,0.837500,0.050000,0.050000},{0.537500,0.837500,0.100000,0.100000},{0.562500,0.837500,0.050000,0.050000},{0.562500,0.837500,0.100000,0.100000},{0.587500,0.837500,0.050000,0.050000},{0.587500,0.837500,0.100000,0.100000},{0.612500,0.837500,0.050000,0.050000},{0.612500,0.837500,0.100000,0.100000},{0.637500,0.837500,0.050000,0.050000},{0.637500,0.837500,0.100000,0.100000},{0.662500,0.837500,0.050000,0.050000},{0.662500,0.837500,0.100000,0.100000},{0.687500,0.837500,0.050000,0.050000},{0.687500,0.837500,0.100000,0.100000},{0.712500,0.837500,0.050000,0.050000},{0.712500,0.837500,0.100000,0.100000},{0.737500,0.837500,0.050000,0.050000},{0.737500,0.837500,0.100000,0.100000},{0.762500,0.837500,0.050000,0.050000},{0.762500,0.837500,0.100000,0.100000},{0.787500,0.837500,0.050000,0.050000},{0.787500,0.837500,0.100000,0.100000},{0.812500,0.837500,0.050000,0.050000},{0.812500,0.837500,0.100000,0.100000},{0.837500,0.837500,0.050000,0.050000},{0.837500,0.837500,0.100000,0.100000},{0.862500,0.837500,0.050000,0.050000},{0.862500,0.837500,0.100000,0.100000},{0.887500,0.837500,0.050000,0.050000},{0.887500,0.837500,0.100000,0.100000},{0.912500,0.837500,0.050000,0.050000},{0.912500,0.837500,0.100000,0.100000},{0.937500,0.837500,0.050000,0.050000},{0.937500,0.837500,0.100000,0.100000},{0.962500,0.837500,0.050000,0.050000},{0.962500,0.837500,0.100000,0.100000},{0.987500,0.837500,0.050000,0.050000},{0.987500,0.837500,0.100000,0.100000},{0.012500,0.862500,0.050000,0.050000},{0.012500,0.862500,0.100000,0.100000},{0.037500,0.862500,0.050000,0.050000},{0.037500,0.862500,0.100000,0.100000},{0.062500,0.862500,0.050000,0.050000},{0.062500,0.862500,0.100000,0.100000},{0.087500,0.862500,0.050000,0.050000},{0.087500,0.862500,0.100000,0.100000},{0.112500,0.862500,0.050000,0.050000},{0.112500,0.862500,0.100000,0.100000},{0.137500,0.862500,0.050000,0.050000},{0.137500,0.862500,0.100000,0.100000},{0.162500,0.862500,0.050000,0.050000},{0.162500,0.862500,0.100000,0.100000},{0.187500,0.862500,0.050000,0.050000},{0.187500,0.862500,0.100000,0.100000},{0.212500,0.862500,0.050000,0.050000},{0.212500,0.862500,0.100000,0.100000},{0.237500,0.862500,0.050000,0.050000},{0.237500,0.862500,0.100000,0.100000},{0.262500,0.862500,0.050000,0.050000},{0.262500,0.862500,0.100000,0.100000},{0.287500,0.862500,0.050000,0.050000},{0.287500,0.862500,0.100000,0.100000},{0.312500,0.862500,0.050000,0.050000},{0.312500,0.862500,0.100000,0.100000},{0.337500,0.862500,0.050000,0.050000},{0.337500,0.862500,0.100000,0.100000},{0.362500,0.862500,0.050000,0.050000},{0.362500,0.862500,0.100000,0.100000},{0.387500,0.862500,0.050000,0.050000},{0.387500,0.862500,0.100000,0.100000},{0.412500,0.862500,0.050000,0.050000},{0.412500,0.862500,0.100000,0.100000},{0.437500,0.862500,0.050000,0.050000},{0.437500,0.862500,0.100000,0.100000},{0.462500,0.862500,0.050000,0.050000},{0.462500,0.862500,0.100000,0.100000},{0.487500,0.862500,0.050000,0.050000},{0.487500,0.862500,0.100000,0.100000},{0.512500,0.862500,0.050000,0.050000},{0.512500,0.862500,0.100000,0.100000},{0.537500,0.862500,0.050000,0.050000},{0.537500,0.862500,0.100000,0.100000},{0.562500,0.862500,0.050000,0.050000},{0.562500,0.862500,0.100000,0.100000},{0.587500,0.862500,0.050000,0.050000},{0.587500,0.862500,0.100000,0.100000},{0.612500,0.862500,0.050000,0.050000},{0.612500,0.862500,0.100000,0.100000},{0.637500,0.862500,0.050000,0.050000},{0.637500,0.862500,0.100000,0.100000},{0.662500,0.862500,0.050000,0.050000},{0.662500,0.862500,0.100000,0.100000},{0.687500,0.862500,0.050000,0.050000},{0.687500,0.862500,0.100000,0.100000},{0.712500,0.862500,0.050000,0.050000},{0.712500,0.862500,0.100000,0.100000},{0.737500,0.862500,0.050000,0.050000},{0.737500,0.862500,0.100000,0.100000},{0.762500,0.862500,0.050000,0.050000},{0.762500,0.862500,0.100000,0.100000},{0.787500,0.862500,0.050000,0.050000},{0.787500,0.862500,0.100000,0.100000},{0.812500,0.862500,0.050000,0.050000},{0.812500,0.862500,0.100000,0.100000},{0.837500,0.862500,0.050000,0.050000},{0.837500,0.862500,0.100000,0.100000},{0.862500,0.862500,0.050000,0.050000},{0.862500,0.862500,0.100000,0.100000},{0.887500,0.862500,0.050000,0.050000},{0.887500,0.862500,0.100000,0.100000},{0.912500,0.862500,0.050000,0.050000},{0.912500,0.862500,0.100000,0.100000},{0.937500,0.862500,0.050000,0.050000},{0.937500,0.862500,0.100000,0.100000},{0.962500,0.862500,0.050000,0.050000},{0.962500,0.862500,0.100000,0.100000},{0.987500,0.862500,0.050000,0.050000},{0.987500,0.862500,0.100000,0.100000},{0.012500,0.887500,0.050000,0.050000},{0.012500,0.887500,0.100000,0.100000},{0.037500,0.887500,0.050000,0.050000},{0.037500,0.887500,0.100000,0.100000},{0.062500,0.887500,0.050000,0.050000},{0.062500,0.887500,0.100000,0.100000},{0.087500,0.887500,0.050000,0.050000},{0.087500,0.887500,0.100000,0.100000},{0.112500,0.887500,0.050000,0.050000},{0.112500,0.887500,0.100000,0.100000},{0.137500,0.887500,0.050000,0.050000},{0.137500,0.887500,0.100000,0.100000},{0.162500,0.887500,0.050000,0.050000},{0.162500,0.887500,0.100000,0.100000},{0.187500,0.887500,0.050000,0.050000},{0.187500,0.887500,0.100000,0.100000},{0.212500,0.887500,0.050000,0.050000},{0.212500,0.887500,0.100000,0.100000},{0.237500,0.887500,0.050000,0.050000},{0.237500,0.887500,0.100000,0.100000},{0.262500,0.887500,0.050000,0.050000},{0.262500,0.887500,0.100000,0.100000},{0.287500,0.887500,0.050000,0.050000},{0.287500,0.887500,0.100000,0.100000},{0.312500,0.887500,0.050000,0.050000},{0.312500,0.887500,0.100000,0.100000},{0.337500,0.887500,0.050000,0.050000},{0.337500,0.887500,0.100000,0.100000},{0.362500,0.887500,0.050000,0.050000},{0.362500,0.887500,0.100000,0.100000},{0.387500,0.887500,0.050000,0.050000},{0.387500,0.887500,0.100000,0.100000},{0.412500,0.887500,0.050000,0.050000},{0.412500,0.887500,0.100000,0.100000},{0.437500,0.887500,0.050000,0.050000},{0.437500,0.887500,0.100000,0.100000},{0.462500,0.887500,0.050000,0.050000},{0.462500,0.887500,0.100000,0.100000},{0.487500,0.887500,0.050000,0.050000},{0.487500,0.887500,0.100000,0.100000},{0.512500,0.887500,0.050000,0.050000},{0.512500,0.887500,0.100000,0.100000},{0.537500,0.887500,0.050000,0.050000},{0.537500,0.887500,0.100000,0.100000},{0.562500,0.887500,0.050000,0.050000},{0.562500,0.887500,0.100000,0.100000},{0.587500,0.887500,0.050000,0.050000},{0.587500,0.887500,0.100000,0.100000},{0.612500,0.887500,0.050000,0.050000},{0.612500,0.887500,0.100000,0.100000},{0.637500,0.887500,0.050000,0.050000},{0.637500,0.887500,0.100000,0.100000},{0.662500,0.887500,0.050000,0.050000},{0.662500,0.887500,0.100000,0.100000},{0.687500,0.887500,0.050000,0.050000},{0.687500,0.887500,0.100000,0.100000},{0.712500,0.887500,0.050000,0.050000},{0.712500,0.887500,0.100000,0.100000},{0.737500,0.887500,0.050000,0.050000},{0.737500,0.887500,0.100000,0.100000},{0.762500,0.887500,0.050000,0.050000},{0.762500,0.887500,0.100000,0.100000},{0.787500,0.887500,0.050000,0.050000},{0.787500,0.887500,0.100000,0.100000},{0.812500,0.887500,0.050000,0.050000},{0.812500,0.887500,0.100000,0.100000},{0.837500,0.887500,0.050000,0.050000},{0.837500,0.887500,0.100000,0.100000},{0.862500,0.887500,0.050000,0.050000},{0.862500,0.887500,0.100000,0.100000},{0.887500,0.887500,0.050000,0.050000},{0.887500,0.887500,0.100000,0.100000},{0.912500,0.887500,0.050000,0.050000},{0.912500,0.887500,0.100000,0.100000},{0.937500,0.887500,0.050000,0.050000},{0.937500,0.887500,0.100000,0.100000},{0.962500,0.887500,0.050000,0.050000},{0.962500,0.887500,0.100000,0.100000},{0.987500,0.887500,0.050000,0.050000},{0.987500,0.887500,0.100000,0.100000},{0.012500,0.912500,0.050000,0.050000},{0.012500,0.912500,0.100000,0.100000},{0.037500,0.912500,0.050000,0.050000},{0.037500,0.912500,0.100000,0.100000},{0.062500,0.912500,0.050000,0.050000},{0.062500,0.912500,0.100000,0.100000},{0.087500,0.912500,0.050000,0.050000},{0.087500,0.912500,0.100000,0.100000},{0.112500,0.912500,0.050000,0.050000},{0.112500,0.912500,0.100000,0.100000},{0.137500,0.912500,0.050000,0.050000},{0.137500,0.912500,0.100000,0.100000},{0.162500,0.912500,0.050000,0.050000},{0.162500,0.912500,0.100000,0.100000},{0.187500,0.912500,0.050000,0.050000},{0.187500,0.912500,0.100000,0.100000},{0.212500,0.912500,0.050000,0.050000},{0.212500,0.912500,0.100000,0.100000},{0.237500,0.912500,0.050000,0.050000},{0.237500,0.912500,0.100000,0.100000},{0.262500,0.912500,0.050000,0.050000},{0.262500,0.912500,0.100000,0.100000},{0.287500,0.912500,0.050000,0.050000},{0.287500,0.912500,0.100000,0.100000},{0.312500,0.912500,0.050000,0.050000},{0.312500,0.912500,0.100000,0.100000},{0.337500,0.912500,0.050000,0.050000},{0.337500,0.912500,0.100000,0.100000},{0.362500,0.912500,0.050000,0.050000},{0.362500,0.912500,0.100000,0.100000},{0.387500,0.912500,0.050000,0.050000},{0.387500,0.912500,0.100000,0.100000},{0.412500,0.912500,0.050000,0.050000},{0.412500,0.912500,0.100000,0.100000},{0.437500,0.912500,0.050000,0.050000},{0.437500,0.912500,0.100000,0.100000},{0.462500,0.912500,0.050000,0.050000},{0.462500,0.912500,0.100000,0.100000},{0.487500,0.912500,0.050000,0.050000},{0.487500,0.912500,0.100000,0.100000},{0.512500,0.912500,0.050000,0.050000},{0.512500,0.912500,0.100000,0.100000},{0.537500,0.912500,0.050000,0.050000},{0.537500,0.912500,0.100000,0.100000},{0.562500,0.912500,0.050000,0.050000},{0.562500,0.912500,0.100000,0.100000},{0.587500,0.912500,0.050000,0.050000},{0.587500,0.912500,0.100000,0.100000},{0.612500,0.912500,0.050000,0.050000},{0.612500,0.912500,0.100000,0.100000},{0.637500,0.912500,0.050000,0.050000},{0.637500,0.912500,0.100000,0.100000},{0.662500,0.912500,0.050000,0.050000},{0.662500,0.912500,0.100000,0.100000},{0.687500,0.912500,0.050000,0.050000},{0.687500,0.912500,0.100000,0.100000},{0.712500,0.912500,0.050000,0.050000},{0.712500,0.912500,0.100000,0.100000},{0.737500,0.912500,0.050000,0.050000},{0.737500,0.912500,0.100000,0.100000},{0.762500,0.912500,0.050000,0.050000},{0.762500,0.912500,0.100000,0.100000},{0.787500,0.912500,0.050000,0.050000},{0.787500,0.912500,0.100000,0.100000},{0.812500,0.912500,0.050000,0.050000},{0.812500,0.912500,0.100000,0.100000},{0.837500,0.912500,0.050000,0.050000},{0.837500,0.912500,0.100000,0.100000},{0.862500,0.912500,0.050000,0.050000},{0.862500,0.912500,0.100000,0.100000},{0.887500,0.912500,0.050000,0.050000},{0.887500,0.912500,0.100000,0.100000},{0.912500,0.912500,0.050000,0.050000},{0.912500,0.912500,0.100000,0.100000},{0.937500,0.912500,0.050000,0.050000},{0.937500,0.912500,0.100000,0.100000},{0.962500,0.912500,0.050000,0.050000},{0.962500,0.912500,0.100000,0.100000},{0.987500,0.912500,0.050000,0.050000},{0.987500,0.912500,0.100000,0.100000},{0.012500,0.937500,0.050000,0.050000},{0.012500,0.937500,0.100000,0.100000},{0.037500,0.937500,0.050000,0.050000},{0.037500,0.937500,0.100000,0.100000},{0.062500,0.937500,0.050000,0.050000},{0.062500,0.937500,0.100000,0.100000},{0.087500,0.937500,0.050000,0.050000},{0.087500,0.937500,0.100000,0.100000},{0.112500,0.937500,0.050000,0.050000},{0.112500,0.937500,0.100000,0.100000},{0.137500,0.937500,0.050000,0.050000},{0.137500,0.937500,0.100000,0.100000},{0.162500,0.937500,0.050000,0.050000},{0.162500,0.937500,0.100000,0.100000},{0.187500,0.937500,0.050000,0.050000},{0.187500,0.937500,0.100000,0.100000},{0.212500,0.937500,0.050000,0.050000},{0.212500,0.937500,0.100000,0.100000},{0.237500,0.937500,0.050000,0.050000},{0.237500,0.937500,0.100000,0.100000},{0.262500,0.937500,0.050000,0.050000},{0.262500,0.937500,0.100000,0.100000},{0.287500,0.937500,0.050000,0.050000},{0.287500,0.937500,0.100000,0.100000},{0.312500,0.937500,0.050000,0.050000},{0.312500,0.937500,0.100000,0.100000},{0.337500,0.937500,0.050000,0.050000},{0.337500,0.937500,0.100000,0.100000},{0.362500,0.937500,0.050000,0.050000},{0.362500,0.937500,0.100000,0.100000},{0.387500,0.937500,0.050000,0.050000},{0.387500,0.937500,0.100000,0.100000},{0.412500,0.937500,0.050000,0.050000},{0.412500,0.937500,0.100000,0.100000},{0.437500,0.937500,0.050000,0.050000},{0.437500,0.937500,0.100000,0.100000},{0.462500,0.937500,0.050000,0.050000},{0.462500,0.937500,0.100000,0.100000},{0.487500,0.937500,0.050000,0.050000},{0.487500,0.937500,0.100000,0.100000},{0.512500,0.937500,0.050000,0.050000},{0.512500,0.937500,0.100000,0.100000},{0.537500,0.937500,0.050000,0.050000},{0.537500,0.937500,0.100000,0.100000},{0.562500,0.937500,0.050000,0.050000},{0.562500,0.937500,0.100000,0.100000},{0.587500,0.937500,0.050000,0.050000},{0.587500,0.937500,0.100000,0.100000},{0.612500,0.937500,0.050000,0.050000},{0.612500,0.937500,0.100000,0.100000},{0.637500,0.937500,0.050000,0.050000},{0.637500,0.937500,0.100000,0.100000},{0.662500,0.937500,0.050000,0.050000},{0.662500,0.937500,0.100000,0.100000},{0.687500,0.937500,0.050000,0.050000},{0.687500,0.937500,0.100000,0.100000},{0.712500,0.937500,0.050000,0.050000},{0.712500,0.937500,0.100000,0.100000},{0.737500,0.937500,0.050000,0.050000},{0.737500,0.937500,0.100000,0.100000},{0.762500,0.937500,0.050000,0.050000},{0.762500,0.937500,0.100000,0.100000},{0.787500,0.937500,0.050000,0.050000},{0.787500,0.937500,0.100000,0.100000},{0.812500,0.937500,0.050000,0.050000},{0.812500,0.937500,0.100000,0.100000},{0.837500,0.937500,0.050000,0.050000},{0.837500,0.937500,0.100000,0.100000},{0.862500,0.937500,0.050000,0.050000},{0.862500,0.937500,0.100000,0.100000},{0.887500,0.937500,0.050000,0.050000},{0.887500,0.937500,0.100000,0.100000},{0.912500,0.937500,0.050000,0.050000},{0.912500,0.937500,0.100000,0.100000},{0.937500,0.937500,0.050000,0.050000},{0.937500,0.937500,0.100000,0.100000},{0.962500,0.937500,0.050000,0.050000},{0.962500,0.937500,0.100000,0.100000},{0.987500,0.937500,0.050000,0.050000},{0.987500,0.937500,0.100000,0.100000},{0.012500,0.962500,0.050000,0.050000},{0.012500,0.962500,0.100000,0.100000},{0.037500,0.962500,0.050000,0.050000},{0.037500,0.962500,0.100000,0.100000},{0.062500,0.962500,0.050000,0.050000},{0.062500,0.962500,0.100000,0.100000},{0.087500,0.962500,0.050000,0.050000},{0.087500,0.962500,0.100000,0.100000},{0.112500,0.962500,0.050000,0.050000},{0.112500,0.962500,0.100000,0.100000},{0.137500,0.962500,0.050000,0.050000},{0.137500,0.962500,0.100000,0.100000},{0.162500,0.962500,0.050000,0.050000},{0.162500,0.962500,0.100000,0.100000},{0.187500,0.962500,0.050000,0.050000},{0.187500,0.962500,0.100000,0.100000},{0.212500,0.962500,0.050000,0.050000},{0.212500,0.962500,0.100000,0.100000},{0.237500,0.962500,0.050000,0.050000},{0.237500,0.962500,0.100000,0.100000},{0.262500,0.962500,0.050000,0.050000},{0.262500,0.962500,0.100000,0.100000},{0.287500,0.962500,0.050000,0.050000},{0.287500,0.962500,0.100000,0.100000},{0.312500,0.962500,0.050000,0.050000},{0.312500,0.962500,0.100000,0.100000},{0.337500,0.962500,0.050000,0.050000},{0.337500,0.962500,0.100000,0.100000},{0.362500,0.962500,0.050000,0.050000},{0.362500,0.962500,0.100000,0.100000},{0.387500,0.962500,0.050000,0.050000},{0.387500,0.962500,0.100000,0.100000},{0.412500,0.962500,0.050000,0.050000},{0.412500,0.962500,0.100000,0.100000},{0.437500,0.962500,0.050000,0.050000},{0.437500,0.962500,0.100000,0.100000},{0.462500,0.962500,0.050000,0.050000},{0.462500,0.962500,0.100000,0.100000},{0.487500,0.962500,0.050000,0.050000},{0.487500,0.962500,0.100000,0.100000},{0.512500,0.962500,0.050000,0.050000},{0.512500,0.962500,0.100000,0.100000},{0.537500,0.962500,0.050000,0.050000},{0.537500,0.962500,0.100000,0.100000},{0.562500,0.962500,0.050000,0.050000},{0.562500,0.962500,0.100000,0.100000},{0.587500,0.962500,0.050000,0.050000},{0.587500,0.962500,0.100000,0.100000},{0.612500,0.962500,0.050000,0.050000},{0.612500,0.962500,0.100000,0.100000},{0.637500,0.962500,0.050000,0.050000},{0.637500,0.962500,0.100000,0.100000},{0.662500,0.962500,0.050000,0.050000},{0.662500,0.962500,0.100000,0.100000},{0.687500,0.962500,0.050000,0.050000},{0.687500,0.962500,0.100000,0.100000},{0.712500,0.962500,0.050000,0.050000},{0.712500,0.962500,0.100000,0.100000},{0.737500,0.962500,0.050000,0.050000},{0.737500,0.962500,0.100000,0.100000},{0.762500,0.962500,0.050000,0.050000},{0.762500,0.962500,0.100000,0.100000},{0.787500,0.962500,0.050000,0.050000},{0.787500,0.962500,0.100000,0.100000},{0.812500,0.962500,0.050000,0.050000},{0.812500,0.962500,0.100000,0.100000},{0.837500,0.962500,0.050000,0.050000},{0.837500,0.962500,0.100000,0.100000},{0.862500,0.962500,0.050000,0.050000},{0.862500,0.962500,0.100000,0.100000},{0.887500,0.962500,0.050000,0.050000},{0.887500,0.962500,0.100000,0.100000},{0.912500,0.962500,0.050000,0.050000},{0.912500,0.962500,0.100000,0.100000},{0.937500,0.962500,0.050000,0.050000},{0.937500,0.962500,0.100000,0.100000},{0.962500,0.962500,0.050000,0.050000},{0.962500,0.962500,0.100000,0.100000},{0.987500,0.962500,0.050000,0.050000},{0.987500,0.962500,0.100000,0.100000},{0.012500,0.987500,0.050000,0.050000},{0.012500,0.987500,0.100000,0.100000},{0.037500,0.987500,0.050000,0.050000},{0.037500,0.987500,0.100000,0.100000},{0.062500,0.987500,0.050000,0.050000},{0.062500,0.987500,0.100000,0.100000},{0.087500,0.987500,0.050000,0.050000},{0.087500,0.987500,0.100000,0.100000},{0.112500,0.987500,0.050000,0.050000},{0.112500,0.987500,0.100000,0.100000},{0.137500,0.987500,0.050000,0.050000},{0.137500,0.987500,0.100000,0.100000},{0.162500,0.987500,0.050000,0.050000},{0.162500,0.987500,0.100000,0.100000},{0.187500,0.987500,0.050000,0.050000},{0.187500,0.987500,0.100000,0.100000},{0.212500,0.987500,0.050000,0.050000},{0.212500,0.987500,0.100000,0.100000},{0.237500,0.987500,0.050000,0.050000},{0.237500,0.987500,0.100000,0.100000},{0.262500,0.987500,0.050000,0.050000},{0.262500,0.987500,0.100000,0.100000},{0.287500,0.987500,0.050000,0.050000},{0.287500,0.987500,0.100000,0.100000},{0.312500,0.987500,0.050000,0.050000},{0.312500,0.987500,0.100000,0.100000},{0.337500,0.987500,0.050000,0.050000},{0.337500,0.987500,0.100000,0.100000},{0.362500,0.987500,0.050000,0.050000},{0.362500,0.987500,0.100000,0.100000},{0.387500,0.987500,0.050000,0.050000},{0.387500,0.987500,0.100000,0.100000},{0.412500,0.987500,0.050000,0.050000},{0.412500,0.987500,0.100000,0.100000},{0.437500,0.987500,0.050000,0.050000},{0.437500,0.987500,0.100000,0.100000},{0.462500,0.987500,0.050000,0.050000},{0.462500,0.987500,0.100000,0.100000},{0.487500,0.987500,0.050000,0.050000},{0.487500,0.987500,0.100000,0.100000},{0.512500,0.987500,0.050000,0.050000},{0.512500,0.987500,0.100000,0.100000},{0.537500,0.987500,0.050000,0.050000},{0.537500,0.987500,0.100000,0.100000},{0.562500,0.987500,0.050000,0.050000},{0.562500,0.987500,0.100000,0.100000},{0.587500,0.987500,0.050000,0.050000},{0.587500,0.987500,0.100000,0.100000},{0.612500,0.987500,0.050000,0.050000},{0.612500,0.987500,0.100000,0.100000},{0.637500,0.987500,0.050000,0.050000},{0.637500,0.987500,0.100000,0.100000},{0.662500,0.987500,0.050000,0.050000},{0.662500,0.987500,0.100000,0.100000},{0.687500,0.987500,0.050000,0.050000},{0.687500,0.987500,0.100000,0.100000},{0.712500,0.987500,0.050000,0.050000},{0.712500,0.987500,0.100000,0.100000},{0.737500,0.987500,0.050000,0.050000},{0.737500,0.987500,0.100000,0.100000},{0.762500,0.987500,0.050000,0.050000},{0.762500,0.987500,0.100000,0.100000},{0.787500,0.987500,0.050000,0.050000},{0.787500,0.987500,0.100000,0.100000},{0.812500,0.987500,0.050000,0.050000},{0.812500,0.987500,0.100000,0.100000},{0.837500,0.987500,0.050000,0.050000},{0.837500,0.987500,0.100000,0.100000},{0.862500,0.987500,0.050000,0.050000},{0.862500,0.987500,0.100000,0.100000},{0.887500,0.987500,0.050000,0.050000},{0.887500,0.987500,0.100000,0.100000},{0.912500,0.987500,0.050000,0.050000},{0.912500,0.987500,0.100000,0.100000},{0.937500,0.987500,0.050000,0.050000},{0.937500,0.987500,0.100000,0.100000},{0.962500,0.987500,0.050000,0.050000},{0.962500,0.987500,0.100000,0.100000},{0.987500,0.987500,0.050000,0.050000},{0.987500,0.987500,0.100000,0.100000},{0.025000,0.025000,0.200000,0.200000},{0.025000,0.025000,0.400000,0.400000},{0.075000,0.025000,0.200000,0.200000},{0.075000,0.025000,0.400000,0.400000},{0.125000,0.025000,0.200000,0.200000},{0.125000,0.025000,0.400000,0.400000},{0.175000,0.025000,0.200000,0.200000},{0.175000,0.025000,0.400000,0.400000},{0.225000,0.025000,0.200000,0.200000},{0.225000,0.025000,0.400000,0.400000},{0.275000,0.025000,0.200000,0.200000},{0.275000,0.025000,0.400000,0.400000},{0.325000,0.025000,0.200000,0.200000},{0.325000,0.025000,0.400000,0.400000},{0.375000,0.025000,0.200000,0.200000},{0.375000,0.025000,0.400000,0.400000},{0.425000,0.025000,0.200000,0.200000},{0.425000,0.025000,0.400000,0.400000},{0.475000,0.025000,0.200000,0.200000},{0.475000,0.025000,0.400000,0.400000},{0.525000,0.025000,0.200000,0.200000},{0.525000,0.025000,0.400000,0.400000},{0.575000,0.025000,0.200000,0.200000},{0.575000,0.025000,0.400000,0.400000},{0.625000,0.025000,0.200000,0.200000},{0.625000,0.025000,0.400000,0.400000},{0.675000,0.025000,0.200000,0.200000},{0.675000,0.025000,0.400000,0.400000},{0.725000,0.025000,0.200000,0.200000},{0.725000,0.025000,0.400000,0.400000},{0.775000,0.025000,0.200000,0.200000},{0.775000,0.025000,0.400000,0.400000},{0.825000,0.025000,0.200000,0.200000},{0.825000,0.025000,0.400000,0.400000},{0.875000,0.025000,0.200000,0.200000},{0.875000,0.025000,0.400000,0.400000},{0.925000,0.025000,0.200000,0.200000},{0.925000,0.025000,0.400000,0.400000},{0.975000,0.025000,0.200000,0.200000},{0.975000,0.025000,0.400000,0.400000},{0.025000,0.075000,0.200000,0.200000},{0.025000,0.075000,0.400000,0.400000},{0.075000,0.075000,0.200000,0.200000},{0.075000,0.075000,0.400000,0.400000},{0.125000,0.075000,0.200000,0.200000},{0.125000,0.075000,0.400000,0.400000},{0.175000,0.075000,0.200000,0.200000},{0.175000,0.075000,0.400000,0.400000},{0.225000,0.075000,0.200000,0.200000},{0.225000,0.075000,0.400000,0.400000},{0.275000,0.075000,0.200000,0.200000},{0.275000,0.075000,0.400000,0.400000},{0.325000,0.075000,0.200000,0.200000},{0.325000,0.075000,0.400000,0.400000},{0.375000,0.075000,0.200000,0.200000},{0.375000,0.075000,0.400000,0.400000},{0.425000,0.075000,0.200000,0.200000},{0.425000,0.075000,0.400000,0.400000},{0.475000,0.075000,0.200000,0.200000},{0.475000,0.075000,0.400000,0.400000},{0.525000,0.075000,0.200000,0.200000},{0.525000,0.075000,0.400000,0.400000},{0.575000,0.075000,0.200000,0.200000},{0.575000,0.075000,0.400000,0.400000},{0.625000,0.075000,0.200000,0.200000},{0.625000,0.075000,0.400000,0.400000},{0.675000,0.075000,0.200000,0.200000},{0.675000,0.075000,0.400000,0.400000},{0.725000,0.075000,0.200000,0.200000},{0.725000,0.075000,0.400000,0.400000},{0.775000,0.075000,0.200000,0.200000},{0.775000,0.075000,0.400000,0.400000},{0.825000,0.075000,0.200000,0.200000},{0.825000,0.075000,0.400000,0.400000},{0.875000,0.075000,0.200000,0.200000},{0.875000,0.075000,0.400000,0.400000},{0.925000,0.075000,0.200000,0.200000},{0.925000,0.075000,0.400000,0.400000},{0.975000,0.075000,0.200000,0.200000},{0.975000,0.075000,0.400000,0.400000},{0.025000,0.125000,0.200000,0.200000},{0.025000,0.125000,0.400000,0.400000},{0.075000,0.125000,0.200000,0.200000},{0.075000,0.125000,0.400000,0.400000},{0.125000,0.125000,0.200000,0.200000},{0.125000,0.125000,0.400000,0.400000},{0.175000,0.125000,0.200000,0.200000},{0.175000,0.125000,0.400000,0.400000},{0.225000,0.125000,0.200000,0.200000},{0.225000,0.125000,0.400000,0.400000},{0.275000,0.125000,0.200000,0.200000},{0.275000,0.125000,0.400000,0.400000},{0.325000,0.125000,0.200000,0.200000},{0.325000,0.125000,0.400000,0.400000},{0.375000,0.125000,0.200000,0.200000},{0.375000,0.125000,0.400000,0.400000},{0.425000,0.125000,0.200000,0.200000},{0.425000,0.125000,0.400000,0.400000},{0.475000,0.125000,0.200000,0.200000},{0.475000,0.125000,0.400000,0.400000},{0.525000,0.125000,0.200000,0.200000},{0.525000,0.125000,0.400000,0.400000},{0.575000,0.125000,0.200000,0.200000},{0.575000,0.125000,0.400000,0.400000},{0.625000,0.125000,0.200000,0.200000},{0.625000,0.125000,0.400000,0.400000},{0.675000,0.125000,0.200000,0.200000},{0.675000,0.125000,0.400000,0.400000},{0.725000,0.125000,0.200000,0.200000},{0.725000,0.125000,0.400000,0.400000},{0.775000,0.125000,0.200000,0.200000},{0.775000,0.125000,0.400000,0.400000},{0.825000,0.125000,0.200000,0.200000},{0.825000,0.125000,0.400000,0.400000},{0.875000,0.125000,0.200000,0.200000},{0.875000,0.125000,0.400000,0.400000},{0.925000,0.125000,0.200000,0.200000},{0.925000,0.125000,0.400000,0.400000},{0.975000,0.125000,0.200000,0.200000},{0.975000,0.125000,0.400000,0.400000},{0.025000,0.175000,0.200000,0.200000},{0.025000,0.175000,0.400000,0.400000},{0.075000,0.175000,0.200000,0.200000},{0.075000,0.175000,0.400000,0.400000},{0.125000,0.175000,0.200000,0.200000},{0.125000,0.175000,0.400000,0.400000},{0.175000,0.175000,0.200000,0.200000},{0.175000,0.175000,0.400000,0.400000},{0.225000,0.175000,0.200000,0.200000},{0.225000,0.175000,0.400000,0.400000},{0.275000,0.175000,0.200000,0.200000},{0.275000,0.175000,0.400000,0.400000},{0.325000,0.175000,0.200000,0.200000},{0.325000,0.175000,0.400000,0.400000},{0.375000,0.175000,0.200000,0.200000},{0.375000,0.175000,0.400000,0.400000},{0.425000,0.175000,0.200000,0.200000},{0.425000,0.175000,0.400000,0.400000},{0.475000,0.175000,0.200000,0.200000},{0.475000,0.175000,0.400000,0.400000},{0.525000,0.175000,0.200000,0.200000},{0.525000,0.175000,0.400000,0.400000},{0.575000,0.175000,0.200000,0.200000},{0.575000,0.175000,0.400000,0.400000},{0.625000,0.175000,0.200000,0.200000},{0.625000,0.175000,0.400000,0.400000},{0.675000,0.175000,0.200000,0.200000},{0.675000,0.175000,0.400000,0.400000},{0.725000,0.175000,0.200000,0.200000},{0.725000,0.175000,0.400000,0.400000},{0.775000,0.175000,0.200000,0.200000},{0.775000,0.175000,0.400000,0.400000},{0.825000,0.175000,0.200000,0.200000},{0.825000,0.175000,0.400000,0.400000},{0.875000,0.175000,0.200000,0.200000},{0.875000,0.175000,0.400000,0.400000},{0.925000,0.175000,0.200000,0.200000},{0.925000,0.175000,0.400000,0.400000},{0.975000,0.175000,0.200000,0.200000},{0.975000,0.175000,0.400000,0.400000},{0.025000,0.225000,0.200000,0.200000},{0.025000,0.225000,0.400000,0.400000},{0.075000,0.225000,0.200000,0.200000},{0.075000,0.225000,0.400000,0.400000},{0.125000,0.225000,0.200000,0.200000},{0.125000,0.225000,0.400000,0.400000},{0.175000,0.225000,0.200000,0.200000},{0.175000,0.225000,0.400000,0.400000},{0.225000,0.225000,0.200000,0.200000},{0.225000,0.225000,0.400000,0.400000},{0.275000,0.225000,0.200000,0.200000},{0.275000,0.225000,0.400000,0.400000},{0.325000,0.225000,0.200000,0.200000},{0.325000,0.225000,0.400000,0.400000},{0.375000,0.225000,0.200000,0.200000},{0.375000,0.225000,0.400000,0.400000},{0.425000,0.225000,0.200000,0.200000},{0.425000,0.225000,0.400000,0.400000},{0.475000,0.225000,0.200000,0.200000},{0.475000,0.225000,0.400000,0.400000},{0.525000,0.225000,0.200000,0.200000},{0.525000,0.225000,0.400000,0.400000},{0.575000,0.225000,0.200000,0.200000},{0.575000,0.225000,0.400000,0.400000},{0.625000,0.225000,0.200000,0.200000},{0.625000,0.225000,0.400000,0.400000},{0.675000,0.225000,0.200000,0.200000},{0.675000,0.225000,0.400000,0.400000},{0.725000,0.225000,0.200000,0.200000},{0.725000,0.225000,0.400000,0.400000},{0.775000,0.225000,0.200000,0.200000},{0.775000,0.225000,0.400000,0.400000},{0.825000,0.225000,0.200000,0.200000},{0.825000,0.225000,0.400000,0.400000},{0.875000,0.225000,0.200000,0.200000},{0.875000,0.225000,0.400000,0.400000},{0.925000,0.225000,0.200000,0.200000},{0.925000,0.225000,0.400000,0.400000},{0.975000,0.225000,0.200000,0.200000},{0.975000,0.225000,0.400000,0.400000},{0.025000,0.275000,0.200000,0.200000},{0.025000,0.275000,0.400000,0.400000},{0.075000,0.275000,0.200000,0.200000},{0.075000,0.275000,0.400000,0.400000},{0.125000,0.275000,0.200000,0.200000},{0.125000,0.275000,0.400000,0.400000},{0.175000,0.275000,0.200000,0.200000},{0.175000,0.275000,0.400000,0.400000},{0.225000,0.275000,0.200000,0.200000},{0.225000,0.275000,0.400000,0.400000},{0.275000,0.275000,0.200000,0.200000},{0.275000,0.275000,0.400000,0.400000},{0.325000,0.275000,0.200000,0.200000},{0.325000,0.275000,0.400000,0.400000},{0.375000,0.275000,0.200000,0.200000},{0.375000,0.275000,0.400000,0.400000},{0.425000,0.275000,0.200000,0.200000},{0.425000,0.275000,0.400000,0.400000},{0.475000,0.275000,0.200000,0.200000},{0.475000,0.275000,0.400000,0.400000},{0.525000,0.275000,0.200000,0.200000},{0.525000,0.275000,0.400000,0.400000},{0.575000,0.275000,0.200000,0.200000},{0.575000,0.275000,0.400000,0.400000},{0.625000,0.275000,0.200000,0.200000},{0.625000,0.275000,0.400000,0.400000},{0.675000,0.275000,0.200000,0.200000},{0.675000,0.275000,0.400000,0.400000},{0.725000,0.275000,0.200000,0.200000},{0.725000,0.275000,0.400000,0.400000},{0.775000,0.275000,0.200000,0.200000},{0.775000,0.275000,0.400000,0.400000},{0.825000,0.275000,0.200000,0.200000},{0.825000,0.275000,0.400000,0.400000},{0.875000,0.275000,0.200000,0.200000},{0.875000,0.275000,0.400000,0.400000},{0.925000,0.275000,0.200000,0.200000},{0.925000,0.275000,0.400000,0.400000},{0.975000,0.275000,0.200000,0.200000},{0.975000,0.275000,0.400000,0.400000},{0.025000,0.325000,0.200000,0.200000},{0.025000,0.325000,0.400000,0.400000},{0.075000,0.325000,0.200000,0.200000},{0.075000,0.325000,0.400000,0.400000},{0.125000,0.325000,0.200000,0.200000},{0.125000,0.325000,0.400000,0.400000},{0.175000,0.325000,0.200000,0.200000},{0.175000,0.325000,0.400000,0.400000},{0.225000,0.325000,0.200000,0.200000},{0.225000,0.325000,0.400000,0.400000},{0.275000,0.325000,0.200000,0.200000},{0.275000,0.325000,0.400000,0.400000},{0.325000,0.325000,0.200000,0.200000},{0.325000,0.325000,0.400000,0.400000},{0.375000,0.325000,0.200000,0.200000},{0.375000,0.325000,0.400000,0.400000},{0.425000,0.325000,0.200000,0.200000},{0.425000,0.325000,0.400000,0.400000},{0.475000,0.325000,0.200000,0.200000},{0.475000,0.325000,0.400000,0.400000},{0.525000,0.325000,0.200000,0.200000},{0.525000,0.325000,0.400000,0.400000},{0.575000,0.325000,0.200000,0.200000},{0.575000,0.325000,0.400000,0.400000},{0.625000,0.325000,0.200000,0.200000},{0.625000,0.325000,0.400000,0.400000},{0.675000,0.325000,0.200000,0.200000},{0.675000,0.325000,0.400000,0.400000},{0.725000,0.325000,0.200000,0.200000},{0.725000,0.325000,0.400000,0.400000},{0.775000,0.325000,0.200000,0.200000},{0.775000,0.325000,0.400000,0.400000},{0.825000,0.325000,0.200000,0.200000},{0.825000,0.325000,0.400000,0.400000},{0.875000,0.325000,0.200000,0.200000},{0.875000,0.325000,0.400000,0.400000},{0.925000,0.325000,0.200000,0.200000},{0.925000,0.325000,0.400000,0.400000},{0.975000,0.325000,0.200000,0.200000},{0.975000,0.325000,0.400000,0.400000},{0.025000,0.375000,0.200000,0.200000},{0.025000,0.375000,0.400000,0.400000},{0.075000,0.375000,0.200000,0.200000},{0.075000,0.375000,0.400000,0.400000},{0.125000,0.375000,0.200000,0.200000},{0.125000,0.375000,0.400000,0.400000},{0.175000,0.375000,0.200000,0.200000},{0.175000,0.375000,0.400000,0.400000},{0.225000,0.375000,0.200000,0.200000},{0.225000,0.375000,0.400000,0.400000},{0.275000,0.375000,0.200000,0.200000},{0.275000,0.375000,0.400000,0.400000},{0.325000,0.375000,0.200000,0.200000},{0.325000,0.375000,0.400000,0.400000},{0.375000,0.375000,0.200000,0.200000},{0.375000,0.375000,0.400000,0.400000},{0.425000,0.375000,0.200000,0.200000},{0.425000,0.375000,0.400000,0.400000},{0.475000,0.375000,0.200000,0.200000},{0.475000,0.375000,0.400000,0.400000},{0.525000,0.375000,0.200000,0.200000},{0.525000,0.375000,0.400000,0.400000},{0.575000,0.375000,0.200000,0.200000},{0.575000,0.375000,0.400000,0.400000},{0.625000,0.375000,0.200000,0.200000},{0.625000,0.375000,0.400000,0.400000},{0.675000,0.375000,0.200000,0.200000},{0.675000,0.375000,0.400000,0.400000},{0.725000,0.375000,0.200000,0.200000},{0.725000,0.375000,0.400000,0.400000},{0.775000,0.375000,0.200000,0.200000},{0.775000,0.375000,0.400000,0.400000},{0.825000,0.375000,0.200000,0.200000},{0.825000,0.375000,0.400000,0.400000},{0.875000,0.375000,0.200000,0.200000},{0.875000,0.375000,0.400000,0.400000},{0.925000,0.375000,0.200000,0.200000},{0.925000,0.375000,0.400000,0.400000},{0.975000,0.375000,0.200000,0.200000},{0.975000,0.375000,0.400000,0.400000},{0.025000,0.425000,0.200000,0.200000},{0.025000,0.425000,0.400000,0.400000},{0.075000,0.425000,0.200000,0.200000},{0.075000,0.425000,0.400000,0.400000},{0.125000,0.425000,0.200000,0.200000},{0.125000,0.425000,0.400000,0.400000},{0.175000,0.425000,0.200000,0.200000},{0.175000,0.425000,0.400000,0.400000},{0.225000,0.425000,0.200000,0.200000},{0.225000,0.425000,0.400000,0.400000},{0.275000,0.425000,0.200000,0.200000},{0.275000,0.425000,0.400000,0.400000},{0.325000,0.425000,0.200000,0.200000},{0.325000,0.425000,0.400000,0.400000},{0.375000,0.425000,0.200000,0.200000},{0.375000,0.425000,0.400000,0.400000},{0.425000,0.425000,0.200000,0.200000},{0.425000,0.425000,0.400000,0.400000},{0.475000,0.425000,0.200000,0.200000},{0.475000,0.425000,0.400000,0.400000},{0.525000,0.425000,0.200000,0.200000},{0.525000,0.425000,0.400000,0.400000},{0.575000,0.425000,0.200000,0.200000},{0.575000,0.425000,0.400000,0.400000},{0.625000,0.425000,0.200000,0.200000},{0.625000,0.425000,0.400000,0.400000},{0.675000,0.425000,0.200000,0.200000},{0.675000,0.425000,0.400000,0.400000},{0.725000,0.425000,0.200000,0.200000},{0.725000,0.425000,0.400000,0.400000},{0.775000,0.425000,0.200000,0.200000},{0.775000,0.425000,0.400000,0.400000},{0.825000,0.425000,0.200000,0.200000},{0.825000,0.425000,0.400000,0.400000},{0.875000,0.425000,0.200000,0.200000},{0.875000,0.425000,0.400000,0.400000},{0.925000,0.425000,0.200000,0.200000},{0.925000,0.425000,0.400000,0.400000},{0.975000,0.425000,0.200000,0.200000},{0.975000,0.425000,0.400000,0.400000},{0.025000,0.475000,0.200000,0.200000},{0.025000,0.475000,0.400000,0.400000},{0.075000,0.475000,0.200000,0.200000},{0.075000,0.475000,0.400000,0.400000},{0.125000,0.475000,0.200000,0.200000},{0.125000,0.475000,0.400000,0.400000},{0.175000,0.475000,0.200000,0.200000},{0.175000,0.475000,0.400000,0.400000},{0.225000,0.475000,0.200000,0.200000},{0.225000,0.475000,0.400000,0.400000},{0.275000,0.475000,0.200000,0.200000},{0.275000,0.475000,0.400000,0.400000},{0.325000,0.475000,0.200000,0.200000},{0.325000,0.475000,0.400000,0.400000},{0.375000,0.475000,0.200000,0.200000},{0.375000,0.475000,0.400000,0.400000},{0.425000,0.475000,0.200000,0.200000},{0.425000,0.475000,0.400000,0.400000},{0.475000,0.475000,0.200000,0.200000},{0.475000,0.475000,0.400000,0.400000},{0.525000,0.475000,0.200000,0.200000},{0.525000,0.475000,0.400000,0.400000},{0.575000,0.475000,0.200000,0.200000},{0.575000,0.475000,0.400000,0.400000},{0.625000,0.475000,0.200000,0.200000},{0.625000,0.475000,0.400000,0.400000},{0.675000,0.475000,0.200000,0.200000},{0.675000,0.475000,0.400000,0.400000},{0.725000,0.475000,0.200000,0.200000},{0.725000,0.475000,0.400000,0.400000},{0.775000,0.475000,0.200000,0.200000},{0.775000,0.475000,0.400000,0.400000},{0.825000,0.475000,0.200000,0.200000},{0.825000,0.475000,0.400000,0.400000},{0.875000,0.475000,0.200000,0.200000},{0.875000,0.475000,0.400000,0.400000},{0.925000,0.475000,0.200000,0.200000},{0.925000,0.475000,0.400000,0.400000},{0.975000,0.475000,0.200000,0.200000},{0.975000,0.475000,0.400000,0.400000},{0.025000,0.525000,0.200000,0.200000},{0.025000,0.525000,0.400000,0.400000},{0.075000,0.525000,0.200000,0.200000},{0.075000,0.525000,0.400000,0.400000},{0.125000,0.525000,0.200000,0.200000},{0.125000,0.525000,0.400000,0.400000},{0.175000,0.525000,0.200000,0.200000},{0.175000,0.525000,0.400000,0.400000},{0.225000,0.525000,0.200000,0.200000},{0.225000,0.525000,0.400000,0.400000},{0.275000,0.525000,0.200000,0.200000},{0.275000,0.525000,0.400000,0.400000},{0.325000,0.525000,0.200000,0.200000},{0.325000,0.525000,0.400000,0.400000},{0.375000,0.525000,0.200000,0.200000},{0.375000,0.525000,0.400000,0.400000},{0.425000,0.525000,0.200000,0.200000},{0.425000,0.525000,0.400000,0.400000},{0.475000,0.525000,0.200000,0.200000},{0.475000,0.525000,0.400000,0.400000},{0.525000,0.525000,0.200000,0.200000},{0.525000,0.525000,0.400000,0.400000},{0.575000,0.525000,0.200000,0.200000},{0.575000,0.525000,0.400000,0.400000},{0.625000,0.525000,0.200000,0.200000},{0.625000,0.525000,0.400000,0.400000},{0.675000,0.525000,0.200000,0.200000},{0.675000,0.525000,0.400000,0.400000},{0.725000,0.525000,0.200000,0.200000},{0.725000,0.525000,0.400000,0.400000},{0.775000,0.525000,0.200000,0.200000},{0.775000,0.525000,0.400000,0.400000},{0.825000,0.525000,0.200000,0.200000},{0.825000,0.525000,0.400000,0.400000},{0.875000,0.525000,0.200000,0.200000},{0.875000,0.525000,0.400000,0.400000},{0.925000,0.525000,0.200000,0.200000},{0.925000,0.525000,0.400000,0.400000},{0.975000,0.525000,0.200000,0.200000},{0.975000,0.525000,0.400000,0.400000},{0.025000,0.575000,0.200000,0.200000},{0.025000,0.575000,0.400000,0.400000},{0.075000,0.575000,0.200000,0.200000},{0.075000,0.575000,0.400000,0.400000},{0.125000,0.575000,0.200000,0.200000},{0.125000,0.575000,0.400000,0.400000},{0.175000,0.575000,0.200000,0.200000},{0.175000,0.575000,0.400000,0.400000},{0.225000,0.575000,0.200000,0.200000},{0.225000,0.575000,0.400000,0.400000},{0.275000,0.575000,0.200000,0.200000},{0.275000,0.575000,0.400000,0.400000},{0.325000,0.575000,0.200000,0.200000},{0.325000,0.575000,0.400000,0.400000},{0.375000,0.575000,0.200000,0.200000},{0.375000,0.575000,0.400000,0.400000},{0.425000,0.575000,0.200000,0.200000},{0.425000,0.575000,0.400000,0.400000},{0.475000,0.575000,0.200000,0.200000},{0.475000,0.575000,0.400000,0.400000},{0.525000,0.575000,0.200000,0.200000},{0.525000,0.575000,0.400000,0.400000},{0.575000,0.575000,0.200000,0.200000},{0.575000,0.575000,0.400000,0.400000},{0.625000,0.575000,0.200000,0.200000},{0.625000,0.575000,0.400000,0.400000},{0.675000,0.575000,0.200000,0.200000},{0.675000,0.575000,0.400000,0.400000},{0.725000,0.575000,0.200000,0.200000},{0.725000,0.575000,0.400000,0.400000},{0.775000,0.575000,0.200000,0.200000},{0.775000,0.575000,0.400000,0.400000},{0.825000,0.575000,0.200000,0.200000},{0.825000,0.575000,0.400000,0.400000},{0.875000,0.575000,0.200000,0.200000},{0.875000,0.575000,0.400000,0.400000},{0.925000,0.575000,0.200000,0.200000},{0.925000,0.575000,0.400000,0.400000},{0.975000,0.575000,0.200000,0.200000},{0.975000,0.575000,0.400000,0.400000},{0.025000,0.625000,0.200000,0.200000},{0.025000,0.625000,0.400000,0.400000},{0.075000,0.625000,0.200000,0.200000},{0.075000,0.625000,0.400000,0.400000},{0.125000,0.625000,0.200000,0.200000},{0.125000,0.625000,0.400000,0.400000},{0.175000,0.625000,0.200000,0.200000},{0.175000,0.625000,0.400000,0.400000},{0.225000,0.625000,0.200000,0.200000},{0.225000,0.625000,0.400000,0.400000},{0.275000,0.625000,0.200000,0.200000},{0.275000,0.625000,0.400000,0.400000},{0.325000,0.625000,0.200000,0.200000},{0.325000,0.625000,0.400000,0.400000},{0.375000,0.625000,0.200000,0.200000},{0.375000,0.625000,0.400000,0.400000},{0.425000,0.625000,0.200000,0.200000},{0.425000,0.625000,0.400000,0.400000},{0.475000,0.625000,0.200000,0.200000},{0.475000,0.625000,0.400000,0.400000},{0.525000,0.625000,0.200000,0.200000},{0.525000,0.625000,0.400000,0.400000},{0.575000,0.625000,0.200000,0.200000},{0.575000,0.625000,0.400000,0.400000},{0.625000,0.625000,0.200000,0.200000},{0.625000,0.625000,0.400000,0.400000},{0.675000,0.625000,0.200000,0.200000},{0.675000,0.625000,0.400000,0.400000},{0.725000,0.625000,0.200000,0.200000},{0.725000,0.625000,0.400000,0.400000},{0.775000,0.625000,0.200000,0.200000},{0.775000,0.625000,0.400000,0.400000},{0.825000,0.625000,0.200000,0.200000},{0.825000,0.625000,0.400000,0.400000},{0.875000,0.625000,0.200000,0.200000},{0.875000,0.625000,0.400000,0.400000},{0.925000,0.625000,0.200000,0.200000},{0.925000,0.625000,0.400000,0.400000},{0.975000,0.625000,0.200000,0.200000},{0.975000,0.625000,0.400000,0.400000},{0.025000,0.675000,0.200000,0.200000},{0.025000,0.675000,0.400000,0.400000},{0.075000,0.675000,0.200000,0.200000},{0.075000,0.675000,0.400000,0.400000},{0.125000,0.675000,0.200000,0.200000},{0.125000,0.675000,0.400000,0.400000},{0.175000,0.675000,0.200000,0.200000},{0.175000,0.675000,0.400000,0.400000},{0.225000,0.675000,0.200000,0.200000},{0.225000,0.675000,0.400000,0.400000},{0.275000,0.675000,0.200000,0.200000},{0.275000,0.675000,0.400000,0.400000},{0.325000,0.675000,0.200000,0.200000},{0.325000,0.675000,0.400000,0.400000},{0.375000,0.675000,0.200000,0.200000},{0.375000,0.675000,0.400000,0.400000},{0.425000,0.675000,0.200000,0.200000},{0.425000,0.675000,0.400000,0.400000},{0.475000,0.675000,0.200000,0.200000},{0.475000,0.675000,0.400000,0.400000},{0.525000,0.675000,0.200000,0.200000},{0.525000,0.675000,0.400000,0.400000},{0.575000,0.675000,0.200000,0.200000},{0.575000,0.675000,0.400000,0.400000},{0.625000,0.675000,0.200000,0.200000},{0.625000,0.675000,0.400000,0.400000},{0.675000,0.675000,0.200000,0.200000},{0.675000,0.675000,0.400000,0.400000},{0.725000,0.675000,0.200000,0.200000},{0.725000,0.675000,0.400000,0.400000},{0.775000,0.675000,0.200000,0.200000},{0.775000,0.675000,0.400000,0.400000},{0.825000,0.675000,0.200000,0.200000},{0.825000,0.675000,0.400000,0.400000},{0.875000,0.675000,0.200000,0.200000},{0.875000,0.675000,0.400000,0.400000},{0.925000,0.675000,0.200000,0.200000},{0.925000,0.675000,0.400000,0.400000},{0.975000,0.675000,0.200000,0.200000},{0.975000,0.675000,0.400000,0.400000},{0.025000,0.725000,0.200000,0.200000},{0.025000,0.725000,0.400000,0.400000},{0.075000,0.725000,0.200000,0.200000},{0.075000,0.725000,0.400000,0.400000},{0.125000,0.725000,0.200000,0.200000},{0.125000,0.725000,0.400000,0.400000},{0.175000,0.725000,0.200000,0.200000},{0.175000,0.725000,0.400000,0.400000},{0.225000,0.725000,0.200000,0.200000},{0.225000,0.725000,0.400000,0.400000},{0.275000,0.725000,0.200000,0.200000},{0.275000,0.725000,0.400000,0.400000},{0.325000,0.725000,0.200000,0.200000},{0.325000,0.725000,0.400000,0.400000},{0.375000,0.725000,0.200000,0.200000},{0.375000,0.725000,0.400000,0.400000},{0.425000,0.725000,0.200000,0.200000},{0.425000,0.725000,0.400000,0.400000},{0.475000,0.725000,0.200000,0.200000},{0.475000,0.725000,0.400000,0.400000},{0.525000,0.725000,0.200000,0.200000},{0.525000,0.725000,0.400000,0.400000},{0.575000,0.725000,0.200000,0.200000},{0.575000,0.725000,0.400000,0.400000},{0.625000,0.725000,0.200000,0.200000},{0.625000,0.725000,0.400000,0.400000},{0.675000,0.725000,0.200000,0.200000},{0.675000,0.725000,0.400000,0.400000},{0.725000,0.725000,0.200000,0.200000},{0.725000,0.725000,0.400000,0.400000},{0.775000,0.725000,0.200000,0.200000},{0.775000,0.725000,0.400000,0.400000},{0.825000,0.725000,0.200000,0.200000},{0.825000,0.725000,0.400000,0.400000},{0.875000,0.725000,0.200000,0.200000},{0.875000,0.725000,0.400000,0.400000},{0.925000,0.725000,0.200000,0.200000},{0.925000,0.725000,0.400000,0.400000},{0.975000,0.725000,0.200000,0.200000},{0.975000,0.725000,0.400000,0.400000},{0.025000,0.775000,0.200000,0.200000},{0.025000,0.775000,0.400000,0.400000},{0.075000,0.775000,0.200000,0.200000},{0.075000,0.775000,0.400000,0.400000},{0.125000,0.775000,0.200000,0.200000},{0.125000,0.775000,0.400000,0.400000},{0.175000,0.775000,0.200000,0.200000},{0.175000,0.775000,0.400000,0.400000},{0.225000,0.775000,0.200000,0.200000},{0.225000,0.775000,0.400000,0.400000},{0.275000,0.775000,0.200000,0.200000},{0.275000,0.775000,0.400000,0.400000},{0.325000,0.775000,0.200000,0.200000},{0.325000,0.775000,0.400000,0.400000},{0.375000,0.775000,0.200000,0.200000},{0.375000,0.775000,0.400000,0.400000},{0.425000,0.775000,0.200000,0.200000},{0.425000,0.775000,0.400000,0.400000},{0.475000,0.775000,0.200000,0.200000},{0.475000,0.775000,0.400000,0.400000},{0.525000,0.775000,0.200000,0.200000},{0.525000,0.775000,0.400000,0.400000},{0.575000,0.775000,0.200000,0.200000},{0.575000,0.775000,0.400000,0.400000},{0.625000,0.775000,0.200000,0.200000},{0.625000,0.775000,0.400000,0.400000},{0.675000,0.775000,0.200000,0.200000},{0.675000,0.775000,0.400000,0.400000},{0.725000,0.775000,0.200000,0.200000},{0.725000,0.775000,0.400000,0.400000},{0.775000,0.775000,0.200000,0.200000},{0.775000,0.775000,0.400000,0.400000},{0.825000,0.775000,0.200000,0.200000},{0.825000,0.775000,0.400000,0.400000},{0.875000,0.775000,0.200000,0.200000},{0.875000,0.775000,0.400000,0.400000},{0.925000,0.775000,0.200000,0.200000},{0.925000,0.775000,0.400000,0.400000},{0.975000,0.775000,0.200000,0.200000},{0.975000,0.775000,0.400000,0.400000},{0.025000,0.825000,0.200000,0.200000},{0.025000,0.825000,0.400000,0.400000},{0.075000,0.825000,0.200000,0.200000},{0.075000,0.825000,0.400000,0.400000},{0.125000,0.825000,0.200000,0.200000},{0.125000,0.825000,0.400000,0.400000},{0.175000,0.825000,0.200000,0.200000},{0.175000,0.825000,0.400000,0.400000},{0.225000,0.825000,0.200000,0.200000},{0.225000,0.825000,0.400000,0.400000},{0.275000,0.825000,0.200000,0.200000},{0.275000,0.825000,0.400000,0.400000},{0.325000,0.825000,0.200000,0.200000},{0.325000,0.825000,0.400000,0.400000},{0.375000,0.825000,0.200000,0.200000},{0.375000,0.825000,0.400000,0.400000},{0.425000,0.825000,0.200000,0.200000},{0.425000,0.825000,0.400000,0.400000},{0.475000,0.825000,0.200000,0.200000},{0.475000,0.825000,0.400000,0.400000},{0.525000,0.825000,0.200000,0.200000},{0.525000,0.825000,0.400000,0.400000},{0.575000,0.825000,0.200000,0.200000},{0.575000,0.825000,0.400000,0.400000},{0.625000,0.825000,0.200000,0.200000},{0.625000,0.825000,0.400000,0.400000},{0.675000,0.825000,0.200000,0.200000},{0.675000,0.825000,0.400000,0.400000},{0.725000,0.825000,0.200000,0.200000},{0.725000,0.825000,0.400000,0.400000},{0.775000,0.825000,0.200000,0.200000},{0.775000,0.825000,0.400000,0.400000},{0.825000,0.825000,0.200000,0.200000},{0.825000,0.825000,0.400000,0.400000},{0.875000,0.825000,0.200000,0.200000},{0.875000,0.825000,0.400000,0.400000},{0.925000,0.825000,0.200000,0.200000},{0.925000,0.825000,0.400000,0.400000},{0.975000,0.825000,0.200000,0.200000},{0.975000,0.825000,0.400000,0.400000},{0.025000,0.875000,0.200000,0.200000},{0.025000,0.875000,0.400000,0.400000},{0.075000,0.875000,0.200000,0.200000},{0.075000,0.875000,0.400000,0.400000},{0.125000,0.875000,0.200000,0.200000},{0.125000,0.875000,0.400000,0.400000},{0.175000,0.875000,0.200000,0.200000},{0.175000,0.875000,0.400000,0.400000},{0.225000,0.875000,0.200000,0.200000},{0.225000,0.875000,0.400000,0.400000},{0.275000,0.875000,0.200000,0.200000},{0.275000,0.875000,0.400000,0.400000},{0.325000,0.875000,0.200000,0.200000},{0.325000,0.875000,0.400000,0.400000},{0.375000,0.875000,0.200000,0.200000},{0.375000,0.875000,0.400000,0.400000},{0.425000,0.875000,0.200000,0.200000},{0.425000,0.875000,0.400000,0.400000},{0.475000,0.875000,0.200000,0.200000},{0.475000,0.875000,0.400000,0.400000},{0.525000,0.875000,0.200000,0.200000},{0.525000,0.875000,0.400000,0.400000},{0.575000,0.875000,0.200000,0.200000},{0.575000,0.875000,0.400000,0.400000},{0.625000,0.875000,0.200000,0.200000},{0.625000,0.875000,0.400000,0.400000},{0.675000,0.875000,0.200000,0.200000},{0.675000,0.875000,0.400000,0.400000},{0.725000,0.875000,0.200000,0.200000},{0.725000,0.875000,0.400000,0.400000},{0.775000,0.875000,0.200000,0.200000},{0.775000,0.875000,0.400000,0.400000},{0.825000,0.875000,0.200000,0.200000},{0.825000,0.875000,0.400000,0.400000},{0.875000,0.875000,0.200000,0.200000},{0.875000,0.875000,0.400000,0.400000},{0.925000,0.875000,0.200000,0.200000},{0.925000,0.875000,0.400000,0.400000},{0.975000,0.875000,0.200000,0.200000},{0.975000,0.875000,0.400000,0.400000},{0.025000,0.925000,0.200000,0.200000},{0.025000,0.925000,0.400000,0.400000},{0.075000,0.925000,0.200000,0.200000},{0.075000,0.925000,0.400000,0.400000},{0.125000,0.925000,0.200000,0.200000},{0.125000,0.925000,0.400000,0.400000},{0.175000,0.925000,0.200000,0.200000},{0.175000,0.925000,0.400000,0.400000},{0.225000,0.925000,0.200000,0.200000},{0.225000,0.925000,0.400000,0.400000},{0.275000,0.925000,0.200000,0.200000},{0.275000,0.925000,0.400000,0.400000},{0.325000,0.925000,0.200000,0.200000},{0.325000,0.925000,0.400000,0.400000},{0.375000,0.925000,0.200000,0.200000},{0.375000,0.925000,0.400000,0.400000},{0.425000,0.925000,0.200000,0.200000},{0.425000,0.925000,0.400000,0.400000},{0.475000,0.925000,0.200000,0.200000},{0.475000,0.925000,0.400000,0.400000},{0.525000,0.925000,0.200000,0.200000},{0.525000,0.925000,0.400000,0.400000},{0.575000,0.925000,0.200000,0.200000},{0.575000,0.925000,0.400000,0.400000},{0.625000,0.925000,0.200000,0.200000},{0.625000,0.925000,0.400000,0.400000},{0.675000,0.925000,0.200000,0.200000},{0.675000,0.925000,0.400000,0.400000},{0.725000,0.925000,0.200000,0.200000},{0.725000,0.925000,0.400000,0.400000},{0.775000,0.925000,0.200000,0.200000},{0.775000,0.925000,0.400000,0.400000},{0.825000,0.925000,0.200000,0.200000},{0.825000,0.925000,0.400000,0.400000},{0.875000,0.925000,0.200000,0.200000},{0.875000,0.925000,0.400000,0.400000},{0.925000,0.925000,0.200000,0.200000},{0.925000,0.925000,0.400000,0.400000},{0.975000,0.925000,0.200000,0.200000},{0.975000,0.925000,0.400000,0.400000},{0.025000,0.975000,0.200000,0.200000},{0.025000,0.975000,0.400000,0.400000},{0.075000,0.975000,0.200000,0.200000},{0.075000,0.975000,0.400000,0.400000},{0.125000,0.975000,0.200000,0.200000},{0.125000,0.975000,0.400000,0.400000},{0.175000,0.975000,0.200000,0.200000},{0.175000,0.975000,0.400000,0.400000},{0.225000,0.975000,0.200000,0.200000},{0.225000,0.975000,0.400000,0.400000},{0.275000,0.975000,0.200000,0.200000},{0.275000,0.975000,0.400000,0.400000},{0.325000,0.975000,0.200000,0.200000},{0.325000,0.975000,0.400000,0.400000},{0.375000,0.975000,0.200000,0.200000},{0.375000,0.975000,0.400000,0.400000},{0.425000,0.975000,0.200000,0.200000},{0.425000,0.975000,0.400000,0.400000},{0.475000,0.975000,0.200000,0.200000},{0.475000,0.975000,0.400000,0.400000},{0.525000,0.975000,0.200000,0.200000},{0.525000,0.975000,0.400000,0.400000},{0.575000,0.975000,0.200000,0.200000},{0.575000,0.975000,0.400000,0.400000},{0.625000,0.975000,0.200000,0.200000},{0.625000,0.975000,0.400000,0.400000},{0.675000,0.975000,0.200000,0.200000},{0.675000,0.975000,0.400000,0.400000},{0.725000,0.975000,0.200000,0.200000},{0.725000,0.975000,0.400000,0.400000},{0.775000,0.975000,0.200000,0.200000},{0.775000,0.975000,0.400000,0.400000},{0.825000,0.975000,0.200000,0.200000},{0.825000,0.975000,0.400000,0.400000},{0.875000,0.975000,0.200000,0.200000},{0.875000,0.975000,0.400000,0.400000},{0.925000,0.975000,0.200000,0.200000},{0.925000,0.975000,0.400000,0.400000},{0.975000,0.975000,0.200000,0.200000},{0.975000,0.975000,0.400000,0.400000},{0.050000,0.050000,0.800000,0.800000},{0.050000,0.050000,1.600000,1.600000},{0.150000,0.050000,0.800000,0.800000},{0.150000,0.050000,1.600000,1.600000},{0.250000,0.050000,0.800000,0.800000},{0.250000,0.050000,1.600000,1.600000},{0.350000,0.050000,0.800000,0.800000},{0.350000,0.050000,1.600000,1.600000},{0.450000,0.050000,0.800000,0.800000},{0.450000,0.050000,1.600000,1.600000},{0.550000,0.050000,0.800000,0.800000},{0.550000,0.050000,1.600000,1.600000},{0.650000,0.050000,0.800000,0.800000},{0.650000,0.050000,1.600000,1.600000},{0.750000,0.050000,0.800000,0.800000},{0.750000,0.050000,1.600000,1.600000},{0.850000,0.050000,0.800000,0.800000},{0.850000,0.050000,1.600000,1.600000},{0.950000,0.050000,0.800000,0.800000},{0.950000,0.050000,1.600000,1.600000},{0.050000,0.150000,0.800000,0.800000},{0.050000,0.150000,1.600000,1.600000},{0.150000,0.150000,0.800000,0.800000},{0.150000,0.150000,1.600000,1.600000},{0.250000,0.150000,0.800000,0.800000},{0.250000,0.150000,1.600000,1.600000},{0.350000,0.150000,0.800000,0.800000},{0.350000,0.150000,1.600000,1.600000},{0.450000,0.150000,0.800000,0.800000},{0.450000,0.150000,1.600000,1.600000},{0.550000,0.150000,0.800000,0.800000},{0.550000,0.150000,1.600000,1.600000},{0.650000,0.150000,0.800000,0.800000},{0.650000,0.150000,1.600000,1.600000},{0.750000,0.150000,0.800000,0.800000},{0.750000,0.150000,1.600000,1.600000},{0.850000,0.150000,0.800000,0.800000},{0.850000,0.150000,1.600000,1.600000},{0.950000,0.150000,0.800000,0.800000},{0.950000,0.150000,1.600000,1.600000},{0.050000,0.250000,0.800000,0.800000},{0.050000,0.250000,1.600000,1.600000},{0.150000,0.250000,0.800000,0.800000},{0.150000,0.250000,1.600000,1.600000},{0.250000,0.250000,0.800000,0.800000},{0.250000,0.250000,1.600000,1.600000},{0.350000,0.250000,0.800000,0.800000},{0.350000,0.250000,1.600000,1.600000},{0.450000,0.250000,0.800000,0.800000},{0.450000,0.250000,1.600000,1.600000},{0.550000,0.250000,0.800000,0.800000},{0.550000,0.250000,1.600000,1.600000},{0.650000,0.250000,0.800000,0.800000},{0.650000,0.250000,1.600000,1.600000},{0.750000,0.250000,0.800000,0.800000},{0.750000,0.250000,1.600000,1.600000},{0.850000,0.250000,0.800000,0.800000},{0.850000,0.250000,1.600000,1.600000},{0.950000,0.250000,0.800000,0.800000},{0.950000,0.250000,1.600000,1.600000},{0.050000,0.350000,0.800000,0.800000},{0.050000,0.350000,1.600000,1.600000},{0.150000,0.350000,0.800000,0.800000},{0.150000,0.350000,1.600000,1.600000},{0.250000,0.350000,0.800000,0.800000},{0.250000,0.350000,1.600000,1.600000},{0.350000,0.350000,0.800000,0.800000},{0.350000,0.350000,1.600000,1.600000},{0.450000,0.350000,0.800000,0.800000},{0.450000,0.350000,1.600000,1.600000},{0.550000,0.350000,0.800000,0.800000},{0.550000,0.350000,1.600000,1.600000},{0.650000,0.350000,0.800000,0.800000},{0.650000,0.350000,1.600000,1.600000},{0.750000,0.350000,0.800000,0.800000},{0.750000,0.350000,1.600000,1.600000},{0.850000,0.350000,0.800000,0.800000},{0.850000,0.350000,1.600000,1.600000},{0.950000,0.350000,0.800000,0.800000},{0.950000,0.350000,1.600000,1.600000},{0.050000,0.450000,0.800000,0.800000},{0.050000,0.450000,1.600000,1.600000},{0.150000,0.450000,0.800000,0.800000},{0.150000,0.450000,1.600000,1.600000},{0.250000,0.450000,0.800000,0.800000},{0.250000,0.450000,1.600000,1.600000},{0.350000,0.450000,0.800000,0.800000},{0.350000,0.450000,1.600000,1.600000},{0.450000,0.450000,0.800000,0.800000},{0.450000,0.450000,1.600000,1.600000},{0.550000,0.450000,0.800000,0.800000},{0.550000,0.450000,1.600000,1.600000},{0.650000,0.450000,0.800000,0.800000},{0.650000,0.450000,1.600000,1.600000},{0.750000,0.450000,0.800000,0.800000},{0.750000,0.450000,1.600000,1.600000},{0.850000,0.450000,0.800000,0.800000},{0.850000,0.450000,1.600000,1.600000},{0.950000,0.450000,0.800000,0.800000},{0.950000,0.450000,1.600000,1.600000},{0.050000,0.550000,0.800000,0.800000},{0.050000,0.550000,1.600000,1.600000},{0.150000,0.550000,0.800000,0.800000},{0.150000,0.550000,1.600000,1.600000},{0.250000,0.550000,0.800000,0.800000},{0.250000,0.550000,1.600000,1.600000},{0.350000,0.550000,0.800000,0.800000},{0.350000,0.550000,1.600000,1.600000},{0.450000,0.550000,0.800000,0.800000},{0.450000,0.550000,1.600000,1.600000},{0.550000,0.550000,0.800000,0.800000},{0.550000,0.550000,1.600000,1.600000},{0.650000,0.550000,0.800000,0.800000},{0.650000,0.550000,1.600000,1.600000},{0.750000,0.550000,0.800000,0.800000},{0.750000,0.550000,1.600000,1.600000},{0.850000,0.550000,0.800000,0.800000},{0.850000,0.550000,1.600000,1.600000},{0.950000,0.550000,0.800000,0.800000},{0.950000,0.550000,1.600000,1.600000},{0.050000,0.650000,0.800000,0.800000},{0.050000,0.650000,1.600000,1.600000},{0.150000,0.650000,0.800000,0.800000},{0.150000,0.650000,1.600000,1.600000},{0.250000,0.650000,0.800000,0.800000},{0.250000,0.650000,1.600000,1.600000},{0.350000,0.650000,0.800000,0.800000},{0.350000,0.650000,1.600000,1.600000},{0.450000,0.650000,0.800000,0.800000},{0.450000,0.650000,1.600000,1.600000},{0.550000,0.650000,0.800000,0.800000},{0.550000,0.650000,1.600000,1.600000},{0.650000,0.650000,0.800000,0.800000},{0.650000,0.650000,1.600000,1.600000},{0.750000,0.650000,0.800000,0.800000},{0.750000,0.650000,1.600000,1.600000},{0.850000,0.650000,0.800000,0.800000},{0.850000,0.650000,1.600000,1.600000},{0.950000,0.650000,0.800000,0.800000},{0.950000,0.650000,1.600000,1.600000},{0.050000,0.750000,0.800000,0.800000},{0.050000,0.750000,1.600000,1.600000},{0.150000,0.750000,0.800000,0.800000},{0.150000,0.750000,1.600000,1.600000},{0.250000,0.750000,0.800000,0.800000},{0.250000,0.750000,1.600000,1.600000},{0.350000,0.750000,0.800000,0.800000},{0.350000,0.750000,1.600000,1.600000},{0.450000,0.750000,0.800000,0.800000},{0.450000,0.750000,1.600000,1.600000},{0.550000,0.750000,0.800000,0.800000},{0.550000,0.750000,1.600000,1.600000},{0.650000,0.750000,0.800000,0.800000},{0.650000,0.750000,1.600000,1.600000},{0.750000,0.750000,0.800000,0.800000},{0.750000,0.750000,1.600000,1.600000},{0.850000,0.750000,0.800000,0.800000},{0.850000,0.750000,1.600000,1.600000},{0.950000,0.750000,0.800000,0.800000},{0.950000,0.750000,1.600000,1.600000},{0.050000,0.850000,0.800000,0.800000},{0.050000,0.850000,1.600000,1.600000},{0.150000,0.850000,0.800000,0.800000},{0.150000,0.850000,1.600000,1.600000},{0.250000,0.850000,0.800000,0.800000},{0.250000,0.850000,1.600000,1.600000},{0.350000,0.850000,0.800000,0.800000},{0.350000,0.850000,1.600000,1.600000},{0.450000,0.850000,0.800000,0.800000},{0.450000,0.850000,1.600000,1.600000},{0.550000,0.850000,0.800000,0.800000},{0.550000,0.850000,1.600000,1.600000},{0.650000,0.850000,0.800000,0.800000},{0.650000,0.850000,1.600000,1.600000},{0.750000,0.850000,0.800000,0.800000},{0.750000,0.850000,1.600000,1.600000},{0.850000,0.850000,0.800000,0.800000},{0.850000,0.850000,1.600000,1.600000},{0.950000,0.850000,0.800000,0.800000},{0.950000,0.850000,1.600000,1.600000},{0.050000,0.950000,0.800000,0.800000},{0.050000,0.950000,1.600000,1.600000},{0.150000,0.950000,0.800000,0.800000},{0.150000,0.950000,1.600000,1.600000},{0.250000,0.950000,0.800000,0.800000},{0.250000,0.950000,1.600000,1.600000},{0.350000,0.950000,0.800000,0.800000},{0.350000,0.950000,1.600000,1.600000},{0.450000,0.950000,0.800000,0.800000},{0.450000,0.950000,1.600000,1.600000},{0.550000,0.950000,0.800000,0.800000},{0.550000,0.950000,1.600000,1.600000},{0.650000,0.950000,0.800000,0.800000},{0.650000,0.950000,1.600000,1.600000},{0.750000,0.950000,0.800000,0.800000},{0.750000,0.950000,1.600000,1.600000},{0.850000,0.950000,0.800000,0.800000},{0.850000,0.950000,1.600000,1.600000},{0.950000,0.950000,0.800000,0.800000},{0.950000,0.950000,1.600000,1.600000}}; \ No newline at end of file diff --git a/src/reference/ai_poc/face_mesh/anchors_640.cc b/src/reference/ai_poc/face_mesh/anchors_640.cc new file mode 100644 index 000000000..9a8d3fb0f --- /dev/null +++ b/src/reference/ai_poc/face_mesh/anchors_640.cc @@ -0,0 +1,25 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +float kAnchors640[16800][4] = {{0.006250,0.006250,0.025000,0.025000},{0.006250,0.006250,0.050000,0.050000},{0.018750,0.006250,0.025000,0.025000},{0.018750,0.006250,0.050000,0.050000},{0.031250,0.006250,0.025000,0.025000},{0.031250,0.006250,0.050000,0.050000},{0.043750,0.006250,0.025000,0.025000},{0.043750,0.006250,0.050000,0.050000},{0.056250,0.006250,0.025000,0.025000},{0.056250,0.006250,0.050000,0.050000},{0.068750,0.006250,0.025000,0.025000},{0.068750,0.006250,0.050000,0.050000},{0.081250,0.006250,0.025000,0.025000},{0.081250,0.006250,0.050000,0.050000},{0.093750,0.006250,0.025000,0.025000},{0.093750,0.006250,0.050000,0.050000},{0.106250,0.006250,0.025000,0.025000},{0.106250,0.006250,0.050000,0.050000},{0.118750,0.006250,0.025000,0.025000},{0.118750,0.006250,0.050000,0.050000},{0.131250,0.006250,0.025000,0.025000},{0.131250,0.006250,0.050000,0.050000},{0.143750,0.006250,0.025000,0.025000},{0.143750,0.006250,0.050000,0.050000},{0.156250,0.006250,0.025000,0.025000},{0.156250,0.006250,0.050000,0.050000},{0.168750,0.006250,0.025000,0.025000},{0.168750,0.006250,0.050000,0.050000},{0.181250,0.006250,0.025000,0.025000},{0.181250,0.006250,0.050000,0.050000},{0.193750,0.006250,0.025000,0.025000},{0.193750,0.006250,0.050000,0.050000},{0.206250,0.006250,0.025000,0.025000},{0.206250,0.006250,0.050000,0.050000},{0.218750,0.006250,0.025000,0.025000},{0.218750,0.006250,0.050000,0.050000},{0.231250,0.006250,0.025000,0.025000},{0.231250,0.006250,0.050000,0.050000},{0.243750,0.006250,0.025000,0.025000},{0.243750,0.006250,0.050000,0.050000},{0.256250,0.006250,0.025000,0.025000},{0.256250,0.006250,0.050000,0.050000},{0.268750,0.006250,0.025000,0.025000},{0.268750,0.006250,0.050000,0.050000},{0.281250,0.006250,0.025000,0.025000},{0.281250,0.006250,0.050000,0.050000},{0.293750,0.006250,0.025000,0.025000},{0.293750,0.006250,0.050000,0.050000},{0.306250,0.006250,0.025000,0.025000},{0.306250,0.006250,0.050000,0.050000},{0.318750,0.006250,0.025000,0.025000},{0.318750,0.006250,0.050000,0.050000},{0.331250,0.006250,0.025000,0.025000},{0.331250,0.006250,0.050000,0.050000},{0.343750,0.006250,0.025000,0.025000},{0.343750,0.006250,0.050000,0.050000},{0.356250,0.006250,0.025000,0.025000},{0.356250,0.006250,0.050000,0.050000},{0.368750,0.006250,0.025000,0.025000},{0.368750,0.006250,0.050000,0.050000},{0.381250,0.006250,0.025000,0.025000},{0.381250,0.006250,0.050000,0.050000},{0.393750,0.006250,0.025000,0.025000},{0.393750,0.006250,0.050000,0.050000},{0.406250,0.006250,0.025000,0.025000},{0.406250,0.006250,0.050000,0.050000},{0.418750,0.006250,0.025000,0.025000},{0.418750,0.006250,0.050000,0.050000},{0.431250,0.006250,0.025000,0.025000},{0.431250,0.006250,0.050000,0.050000},{0.443750,0.006250,0.025000,0.025000},{0.443750,0.006250,0.050000,0.050000},{0.456250,0.006250,0.025000,0.025000},{0.456250,0.006250,0.050000,0.050000},{0.468750,0.006250,0.025000,0.025000},{0.468750,0.006250,0.050000,0.050000},{0.481250,0.006250,0.025000,0.025000},{0.481250,0.006250,0.050000,0.050000},{0.493750,0.006250,0.025000,0.025000},{0.493750,0.006250,0.050000,0.050000},{0.506250,0.006250,0.025000,0.025000},{0.506250,0.006250,0.050000,0.050000},{0.518750,0.006250,0.025000,0.025000},{0.518750,0.006250,0.050000,0.050000},{0.531250,0.006250,0.025000,0.025000},{0.531250,0.006250,0.050000,0.050000},{0.543750,0.006250,0.025000,0.025000},{0.543750,0.006250,0.050000,0.050000},{0.556250,0.006250,0.025000,0.025000},{0.556250,0.006250,0.050000,0.050000},{0.568750,0.006250,0.025000,0.025000},{0.568750,0.006250,0.050000,0.050000},{0.581250,0.006250,0.025000,0.025000},{0.581250,0.006250,0.050000,0.050000},{0.593750,0.006250,0.025000,0.025000},{0.593750,0.006250,0.050000,0.050000},{0.606250,0.006250,0.025000,0.025000},{0.606250,0.006250,0.050000,0.050000},{0.618750,0.006250,0.025000,0.025000},{0.618750,0.006250,0.050000,0.050000},{0.631250,0.006250,0.025000,0.025000},{0.631250,0.006250,0.050000,0.050000},{0.643750,0.006250,0.025000,0.025000},{0.643750,0.006250,0.050000,0.050000},{0.656250,0.006250,0.025000,0.025000},{0.656250,0.006250,0.050000,0.050000},{0.668750,0.006250,0.025000,0.025000},{0.668750,0.006250,0.050000,0.050000},{0.681250,0.006250,0.025000,0.025000},{0.681250,0.006250,0.050000,0.050000},{0.693750,0.006250,0.025000,0.025000},{0.693750,0.006250,0.050000,0.050000},{0.706250,0.006250,0.025000,0.025000},{0.706250,0.006250,0.050000,0.050000},{0.718750,0.006250,0.025000,0.025000},{0.718750,0.006250,0.050000,0.050000},{0.731250,0.006250,0.025000,0.025000},{0.731250,0.006250,0.050000,0.050000},{0.743750,0.006250,0.025000,0.025000},{0.743750,0.006250,0.050000,0.050000},{0.756250,0.006250,0.025000,0.025000},{0.756250,0.006250,0.050000,0.050000},{0.768750,0.006250,0.025000,0.025000},{0.768750,0.006250,0.050000,0.050000},{0.781250,0.006250,0.025000,0.025000},{0.781250,0.006250,0.050000,0.050000},{0.793750,0.006250,0.025000,0.025000},{0.793750,0.006250,0.050000,0.050000},{0.806250,0.006250,0.025000,0.025000},{0.806250,0.006250,0.050000,0.050000},{0.818750,0.006250,0.025000,0.025000},{0.818750,0.006250,0.050000,0.050000},{0.831250,0.006250,0.025000,0.025000},{0.831250,0.006250,0.050000,0.050000},{0.843750,0.006250,0.025000,0.025000},{0.843750,0.006250,0.050000,0.050000},{0.856250,0.006250,0.025000,0.025000},{0.856250,0.006250,0.050000,0.050000},{0.868750,0.006250,0.025000,0.025000},{0.868750,0.006250,0.050000,0.050000},{0.881250,0.006250,0.025000,0.025000},{0.881250,0.006250,0.050000,0.050000},{0.893750,0.006250,0.025000,0.025000},{0.893750,0.006250,0.050000,0.050000},{0.906250,0.006250,0.025000,0.025000},{0.906250,0.006250,0.050000,0.050000},{0.918750,0.006250,0.025000,0.025000},{0.918750,0.006250,0.050000,0.050000},{0.931250,0.006250,0.025000,0.025000},{0.931250,0.006250,0.050000,0.050000},{0.943750,0.006250,0.025000,0.025000},{0.943750,0.006250,0.050000,0.050000},{0.956250,0.006250,0.025000,0.025000},{0.956250,0.006250,0.050000,0.050000},{0.968750,0.006250,0.025000,0.025000},{0.968750,0.006250,0.050000,0.050000},{0.981250,0.006250,0.025000,0.025000},{0.981250,0.006250,0.050000,0.050000},{0.993750,0.006250,0.025000,0.025000},{0.993750,0.006250,0.050000,0.050000},{0.006250,0.018750,0.025000,0.025000},{0.006250,0.018750,0.050000,0.050000},{0.018750,0.018750,0.025000,0.025000},{0.018750,0.018750,0.050000,0.050000},{0.031250,0.018750,0.025000,0.025000},{0.031250,0.018750,0.050000,0.050000},{0.043750,0.018750,0.025000,0.025000},{0.043750,0.018750,0.050000,0.050000},{0.056250,0.018750,0.025000,0.025000},{0.056250,0.018750,0.050000,0.050000},{0.068750,0.018750,0.025000,0.025000},{0.068750,0.018750,0.050000,0.050000},{0.081250,0.018750,0.025000,0.025000},{0.081250,0.018750,0.050000,0.050000},{0.093750,0.018750,0.025000,0.025000},{0.093750,0.018750,0.050000,0.050000},{0.106250,0.018750,0.025000,0.025000},{0.106250,0.018750,0.050000,0.050000},{0.118750,0.018750,0.025000,0.025000},{0.118750,0.018750,0.050000,0.050000},{0.131250,0.018750,0.025000,0.025000},{0.131250,0.018750,0.050000,0.050000},{0.143750,0.018750,0.025000,0.025000},{0.143750,0.018750,0.050000,0.050000},{0.156250,0.018750,0.025000,0.025000},{0.156250,0.018750,0.050000,0.050000},{0.168750,0.018750,0.025000,0.025000},{0.168750,0.018750,0.050000,0.050000},{0.181250,0.018750,0.025000,0.025000},{0.181250,0.018750,0.050000,0.050000},{0.193750,0.018750,0.025000,0.025000},{0.193750,0.018750,0.050000,0.050000},{0.206250,0.018750,0.025000,0.025000},{0.206250,0.018750,0.050000,0.050000},{0.218750,0.018750,0.025000,0.025000},{0.218750,0.018750,0.050000,0.050000},{0.231250,0.018750,0.025000,0.025000},{0.231250,0.018750,0.050000,0.050000},{0.243750,0.018750,0.025000,0.025000},{0.243750,0.018750,0.050000,0.050000},{0.256250,0.018750,0.025000,0.025000},{0.256250,0.018750,0.050000,0.050000},{0.268750,0.018750,0.025000,0.025000},{0.268750,0.018750,0.050000,0.050000},{0.281250,0.018750,0.025000,0.025000},{0.281250,0.018750,0.050000,0.050000},{0.293750,0.018750,0.025000,0.025000},{0.293750,0.018750,0.050000,0.050000},{0.306250,0.018750,0.025000,0.025000},{0.306250,0.018750,0.050000,0.050000},{0.318750,0.018750,0.025000,0.025000},{0.318750,0.018750,0.050000,0.050000},{0.331250,0.018750,0.025000,0.025000},{0.331250,0.018750,0.050000,0.050000},{0.343750,0.018750,0.025000,0.025000},{0.343750,0.018750,0.050000,0.050000},{0.356250,0.018750,0.025000,0.025000},{0.356250,0.018750,0.050000,0.050000},{0.368750,0.018750,0.025000,0.025000},{0.368750,0.018750,0.050000,0.050000},{0.381250,0.018750,0.025000,0.025000},{0.381250,0.018750,0.050000,0.050000},{0.393750,0.018750,0.025000,0.025000},{0.393750,0.018750,0.050000,0.050000},{0.406250,0.018750,0.025000,0.025000},{0.406250,0.018750,0.050000,0.050000},{0.418750,0.018750,0.025000,0.025000},{0.418750,0.018750,0.050000,0.050000},{0.431250,0.018750,0.025000,0.025000},{0.431250,0.018750,0.050000,0.050000},{0.443750,0.018750,0.025000,0.025000},{0.443750,0.018750,0.050000,0.050000},{0.456250,0.018750,0.025000,0.025000},{0.456250,0.018750,0.050000,0.050000},{0.468750,0.018750,0.025000,0.025000},{0.468750,0.018750,0.050000,0.050000},{0.481250,0.018750,0.025000,0.025000},{0.481250,0.018750,0.050000,0.050000},{0.493750,0.018750,0.025000,0.025000},{0.493750,0.018750,0.050000,0.050000},{0.506250,0.018750,0.025000,0.025000},{0.506250,0.018750,0.050000,0.050000},{0.518750,0.018750,0.025000,0.025000},{0.518750,0.018750,0.050000,0.050000},{0.531250,0.018750,0.025000,0.025000},{0.531250,0.018750,0.050000,0.050000},{0.543750,0.018750,0.025000,0.025000},{0.543750,0.018750,0.050000,0.050000},{0.556250,0.018750,0.025000,0.025000},{0.556250,0.018750,0.050000,0.050000},{0.568750,0.018750,0.025000,0.025000},{0.568750,0.018750,0.050000,0.050000},{0.581250,0.018750,0.025000,0.025000},{0.581250,0.018750,0.050000,0.050000},{0.593750,0.018750,0.025000,0.025000},{0.593750,0.018750,0.050000,0.050000},{0.606250,0.018750,0.025000,0.025000},{0.606250,0.018750,0.050000,0.050000},{0.618750,0.018750,0.025000,0.025000},{0.618750,0.018750,0.050000,0.050000},{0.631250,0.018750,0.025000,0.025000},{0.631250,0.018750,0.050000,0.050000},{0.643750,0.018750,0.025000,0.025000},{0.643750,0.018750,0.050000,0.050000},{0.656250,0.018750,0.025000,0.025000},{0.656250,0.018750,0.050000,0.050000},{0.668750,0.018750,0.025000,0.025000},{0.668750,0.018750,0.050000,0.050000},{0.681250,0.018750,0.025000,0.025000},{0.681250,0.018750,0.050000,0.050000},{0.693750,0.018750,0.025000,0.025000},{0.693750,0.018750,0.050000,0.050000},{0.706250,0.018750,0.025000,0.025000},{0.706250,0.018750,0.050000,0.050000},{0.718750,0.018750,0.025000,0.025000},{0.718750,0.018750,0.050000,0.050000},{0.731250,0.018750,0.025000,0.025000},{0.731250,0.018750,0.050000,0.050000},{0.743750,0.018750,0.025000,0.025000},{0.743750,0.018750,0.050000,0.050000},{0.756250,0.018750,0.025000,0.025000},{0.756250,0.018750,0.050000,0.050000},{0.768750,0.018750,0.025000,0.025000},{0.768750,0.018750,0.050000,0.050000},{0.781250,0.018750,0.025000,0.025000},{0.781250,0.018750,0.050000,0.050000},{0.793750,0.018750,0.025000,0.025000},{0.793750,0.018750,0.050000,0.050000},{0.806250,0.018750,0.025000,0.025000},{0.806250,0.018750,0.050000,0.050000},{0.818750,0.018750,0.025000,0.025000},{0.818750,0.018750,0.050000,0.050000},{0.831250,0.018750,0.025000,0.025000},{0.831250,0.018750,0.050000,0.050000},{0.843750,0.018750,0.025000,0.025000},{0.843750,0.018750,0.050000,0.050000},{0.856250,0.018750,0.025000,0.025000},{0.856250,0.018750,0.050000,0.050000},{0.868750,0.018750,0.025000,0.025000},{0.868750,0.018750,0.050000,0.050000},{0.881250,0.018750,0.025000,0.025000},{0.881250,0.018750,0.050000,0.050000},{0.893750,0.018750,0.025000,0.025000},{0.893750,0.018750,0.050000,0.050000},{0.906250,0.018750,0.025000,0.025000},{0.906250,0.018750,0.050000,0.050000},{0.918750,0.018750,0.025000,0.025000},{0.918750,0.018750,0.050000,0.050000},{0.931250,0.018750,0.025000,0.025000},{0.931250,0.018750,0.050000,0.050000},{0.943750,0.018750,0.025000,0.025000},{0.943750,0.018750,0.050000,0.050000},{0.956250,0.018750,0.025000,0.025000},{0.956250,0.018750,0.050000,0.050000},{0.968750,0.018750,0.025000,0.025000},{0.968750,0.018750,0.050000,0.050000},{0.981250,0.018750,0.025000,0.025000},{0.981250,0.018750,0.050000,0.050000},{0.993750,0.018750,0.025000,0.025000},{0.993750,0.018750,0.050000,0.050000},{0.006250,0.031250,0.025000,0.025000},{0.006250,0.031250,0.050000,0.050000},{0.018750,0.031250,0.025000,0.025000},{0.018750,0.031250,0.050000,0.050000},{0.031250,0.031250,0.025000,0.025000},{0.031250,0.031250,0.050000,0.050000},{0.043750,0.031250,0.025000,0.025000},{0.043750,0.031250,0.050000,0.050000},{0.056250,0.031250,0.025000,0.025000},{0.056250,0.031250,0.050000,0.050000},{0.068750,0.031250,0.025000,0.025000},{0.068750,0.031250,0.050000,0.050000},{0.081250,0.031250,0.025000,0.025000},{0.081250,0.031250,0.050000,0.050000},{0.093750,0.031250,0.025000,0.025000},{0.093750,0.031250,0.050000,0.050000},{0.106250,0.031250,0.025000,0.025000},{0.106250,0.031250,0.050000,0.050000},{0.118750,0.031250,0.025000,0.025000},{0.118750,0.031250,0.050000,0.050000},{0.131250,0.031250,0.025000,0.025000},{0.131250,0.031250,0.050000,0.050000},{0.143750,0.031250,0.025000,0.025000},{0.143750,0.031250,0.050000,0.050000},{0.156250,0.031250,0.025000,0.025000},{0.156250,0.031250,0.050000,0.050000},{0.168750,0.031250,0.025000,0.025000},{0.168750,0.031250,0.050000,0.050000},{0.181250,0.031250,0.025000,0.025000},{0.181250,0.031250,0.050000,0.050000},{0.193750,0.031250,0.025000,0.025000},{0.193750,0.031250,0.050000,0.050000},{0.206250,0.031250,0.025000,0.025000},{0.206250,0.031250,0.050000,0.050000},{0.218750,0.031250,0.025000,0.025000},{0.218750,0.031250,0.050000,0.050000},{0.231250,0.031250,0.025000,0.025000},{0.231250,0.031250,0.050000,0.050000},{0.243750,0.031250,0.025000,0.025000},{0.243750,0.031250,0.050000,0.050000},{0.256250,0.031250,0.025000,0.025000},{0.256250,0.031250,0.050000,0.050000},{0.268750,0.031250,0.025000,0.025000},{0.268750,0.031250,0.050000,0.050000},{0.281250,0.031250,0.025000,0.025000},{0.281250,0.031250,0.050000,0.050000},{0.293750,0.031250,0.025000,0.025000},{0.293750,0.031250,0.050000,0.050000},{0.306250,0.031250,0.025000,0.025000},{0.306250,0.031250,0.050000,0.050000},{0.318750,0.031250,0.025000,0.025000},{0.318750,0.031250,0.050000,0.050000},{0.331250,0.031250,0.025000,0.025000},{0.331250,0.031250,0.050000,0.050000},{0.343750,0.031250,0.025000,0.025000},{0.343750,0.031250,0.050000,0.050000},{0.356250,0.031250,0.025000,0.025000},{0.356250,0.031250,0.050000,0.050000},{0.368750,0.031250,0.025000,0.025000},{0.368750,0.031250,0.050000,0.050000},{0.381250,0.031250,0.025000,0.025000},{0.381250,0.031250,0.050000,0.050000},{0.393750,0.031250,0.025000,0.025000},{0.393750,0.031250,0.050000,0.050000},{0.406250,0.031250,0.025000,0.025000},{0.406250,0.031250,0.050000,0.050000},{0.418750,0.031250,0.025000,0.025000},{0.418750,0.031250,0.050000,0.050000},{0.431250,0.031250,0.025000,0.025000},{0.431250,0.031250,0.050000,0.050000},{0.443750,0.031250,0.025000,0.025000},{0.443750,0.031250,0.050000,0.050000},{0.456250,0.031250,0.025000,0.025000},{0.456250,0.031250,0.050000,0.050000},{0.468750,0.031250,0.025000,0.025000},{0.468750,0.031250,0.050000,0.050000},{0.481250,0.031250,0.025000,0.025000},{0.481250,0.031250,0.050000,0.050000},{0.493750,0.031250,0.025000,0.025000},{0.493750,0.031250,0.050000,0.050000},{0.506250,0.031250,0.025000,0.025000},{0.506250,0.031250,0.050000,0.050000},{0.518750,0.031250,0.025000,0.025000},{0.518750,0.031250,0.050000,0.050000},{0.531250,0.031250,0.025000,0.025000},{0.531250,0.031250,0.050000,0.050000},{0.543750,0.031250,0.025000,0.025000},{0.543750,0.031250,0.050000,0.050000},{0.556250,0.031250,0.025000,0.025000},{0.556250,0.031250,0.050000,0.050000},{0.568750,0.031250,0.025000,0.025000},{0.568750,0.031250,0.050000,0.050000},{0.581250,0.031250,0.025000,0.025000},{0.581250,0.031250,0.050000,0.050000},{0.593750,0.031250,0.025000,0.025000},{0.593750,0.031250,0.050000,0.050000},{0.606250,0.031250,0.025000,0.025000},{0.606250,0.031250,0.050000,0.050000},{0.618750,0.031250,0.025000,0.025000},{0.618750,0.031250,0.050000,0.050000},{0.631250,0.031250,0.025000,0.025000},{0.631250,0.031250,0.050000,0.050000},{0.643750,0.031250,0.025000,0.025000},{0.643750,0.031250,0.050000,0.050000},{0.656250,0.031250,0.025000,0.025000},{0.656250,0.031250,0.050000,0.050000},{0.668750,0.031250,0.025000,0.025000},{0.668750,0.031250,0.050000,0.050000},{0.681250,0.031250,0.025000,0.025000},{0.681250,0.031250,0.050000,0.050000},{0.693750,0.031250,0.025000,0.025000},{0.693750,0.031250,0.050000,0.050000},{0.706250,0.031250,0.025000,0.025000},{0.706250,0.031250,0.050000,0.050000},{0.718750,0.031250,0.025000,0.025000},{0.718750,0.031250,0.050000,0.050000},{0.731250,0.031250,0.025000,0.025000},{0.731250,0.031250,0.050000,0.050000},{0.743750,0.031250,0.025000,0.025000},{0.743750,0.031250,0.050000,0.050000},{0.756250,0.031250,0.025000,0.025000},{0.756250,0.031250,0.050000,0.050000},{0.768750,0.031250,0.025000,0.025000},{0.768750,0.031250,0.050000,0.050000},{0.781250,0.031250,0.025000,0.025000},{0.781250,0.031250,0.050000,0.050000},{0.793750,0.031250,0.025000,0.025000},{0.793750,0.031250,0.050000,0.050000},{0.806250,0.031250,0.025000,0.025000},{0.806250,0.031250,0.050000,0.050000},{0.818750,0.031250,0.025000,0.025000},{0.818750,0.031250,0.050000,0.050000},{0.831250,0.031250,0.025000,0.025000},{0.831250,0.031250,0.050000,0.050000},{0.843750,0.031250,0.025000,0.025000},{0.843750,0.031250,0.050000,0.050000},{0.856250,0.031250,0.025000,0.025000},{0.856250,0.031250,0.050000,0.050000},{0.868750,0.031250,0.025000,0.025000},{0.868750,0.031250,0.050000,0.050000},{0.881250,0.031250,0.025000,0.025000},{0.881250,0.031250,0.050000,0.050000},{0.893750,0.031250,0.025000,0.025000},{0.893750,0.031250,0.050000,0.050000},{0.906250,0.031250,0.025000,0.025000},{0.906250,0.031250,0.050000,0.050000},{0.918750,0.031250,0.025000,0.025000},{0.918750,0.031250,0.050000,0.050000},{0.931250,0.031250,0.025000,0.025000},{0.931250,0.031250,0.050000,0.050000},{0.943750,0.031250,0.025000,0.025000},{0.943750,0.031250,0.050000,0.050000},{0.956250,0.031250,0.025000,0.025000},{0.956250,0.031250,0.050000,0.050000},{0.968750,0.031250,0.025000,0.025000},{0.968750,0.031250,0.050000,0.050000},{0.981250,0.031250,0.025000,0.025000},{0.981250,0.031250,0.050000,0.050000},{0.993750,0.031250,0.025000,0.025000},{0.993750,0.031250,0.050000,0.050000},{0.006250,0.043750,0.025000,0.025000},{0.006250,0.043750,0.050000,0.050000},{0.018750,0.043750,0.025000,0.025000},{0.018750,0.043750,0.050000,0.050000},{0.031250,0.043750,0.025000,0.025000},{0.031250,0.043750,0.050000,0.050000},{0.043750,0.043750,0.025000,0.025000},{0.043750,0.043750,0.050000,0.050000},{0.056250,0.043750,0.025000,0.025000},{0.056250,0.043750,0.050000,0.050000},{0.068750,0.043750,0.025000,0.025000},{0.068750,0.043750,0.050000,0.050000},{0.081250,0.043750,0.025000,0.025000},{0.081250,0.043750,0.050000,0.050000},{0.093750,0.043750,0.025000,0.025000},{0.093750,0.043750,0.050000,0.050000},{0.106250,0.043750,0.025000,0.025000},{0.106250,0.043750,0.050000,0.050000},{0.118750,0.043750,0.025000,0.025000},{0.118750,0.043750,0.050000,0.050000},{0.131250,0.043750,0.025000,0.025000},{0.131250,0.043750,0.050000,0.050000},{0.143750,0.043750,0.025000,0.025000},{0.143750,0.043750,0.050000,0.050000},{0.156250,0.043750,0.025000,0.025000},{0.156250,0.043750,0.050000,0.050000},{0.168750,0.043750,0.025000,0.025000},{0.168750,0.043750,0.050000,0.050000},{0.181250,0.043750,0.025000,0.025000},{0.181250,0.043750,0.050000,0.050000},{0.193750,0.043750,0.025000,0.025000},{0.193750,0.043750,0.050000,0.050000},{0.206250,0.043750,0.025000,0.025000},{0.206250,0.043750,0.050000,0.050000},{0.218750,0.043750,0.025000,0.025000},{0.218750,0.043750,0.050000,0.050000},{0.231250,0.043750,0.025000,0.025000},{0.231250,0.043750,0.050000,0.050000},{0.243750,0.043750,0.025000,0.025000},{0.243750,0.043750,0.050000,0.050000},{0.256250,0.043750,0.025000,0.025000},{0.256250,0.043750,0.050000,0.050000},{0.268750,0.043750,0.025000,0.025000},{0.268750,0.043750,0.050000,0.050000},{0.281250,0.043750,0.025000,0.025000},{0.281250,0.043750,0.050000,0.050000},{0.293750,0.043750,0.025000,0.025000},{0.293750,0.043750,0.050000,0.050000},{0.306250,0.043750,0.025000,0.025000},{0.306250,0.043750,0.050000,0.050000},{0.318750,0.043750,0.025000,0.025000},{0.318750,0.043750,0.050000,0.050000},{0.331250,0.043750,0.025000,0.025000},{0.331250,0.043750,0.050000,0.050000},{0.343750,0.043750,0.025000,0.025000},{0.343750,0.043750,0.050000,0.050000},{0.356250,0.043750,0.025000,0.025000},{0.356250,0.043750,0.050000,0.050000},{0.368750,0.043750,0.025000,0.025000},{0.368750,0.043750,0.050000,0.050000},{0.381250,0.043750,0.025000,0.025000},{0.381250,0.043750,0.050000,0.050000},{0.393750,0.043750,0.025000,0.025000},{0.393750,0.043750,0.050000,0.050000},{0.406250,0.043750,0.025000,0.025000},{0.406250,0.043750,0.050000,0.050000},{0.418750,0.043750,0.025000,0.025000},{0.418750,0.043750,0.050000,0.050000},{0.431250,0.043750,0.025000,0.025000},{0.431250,0.043750,0.050000,0.050000},{0.443750,0.043750,0.025000,0.025000},{0.443750,0.043750,0.050000,0.050000},{0.456250,0.043750,0.025000,0.025000},{0.456250,0.043750,0.050000,0.050000},{0.468750,0.043750,0.025000,0.025000},{0.468750,0.043750,0.050000,0.050000},{0.481250,0.043750,0.025000,0.025000},{0.481250,0.043750,0.050000,0.050000},{0.493750,0.043750,0.025000,0.025000},{0.493750,0.043750,0.050000,0.050000},{0.506250,0.043750,0.025000,0.025000},{0.506250,0.043750,0.050000,0.050000},{0.518750,0.043750,0.025000,0.025000},{0.518750,0.043750,0.050000,0.050000},{0.531250,0.043750,0.025000,0.025000},{0.531250,0.043750,0.050000,0.050000},{0.543750,0.043750,0.025000,0.025000},{0.543750,0.043750,0.050000,0.050000},{0.556250,0.043750,0.025000,0.025000},{0.556250,0.043750,0.050000,0.050000},{0.568750,0.043750,0.025000,0.025000},{0.568750,0.043750,0.050000,0.050000},{0.581250,0.043750,0.025000,0.025000},{0.581250,0.043750,0.050000,0.050000},{0.593750,0.043750,0.025000,0.025000},{0.593750,0.043750,0.050000,0.050000},{0.606250,0.043750,0.025000,0.025000},{0.606250,0.043750,0.050000,0.050000},{0.618750,0.043750,0.025000,0.025000},{0.618750,0.043750,0.050000,0.050000},{0.631250,0.043750,0.025000,0.025000},{0.631250,0.043750,0.050000,0.050000},{0.643750,0.043750,0.025000,0.025000},{0.643750,0.043750,0.050000,0.050000},{0.656250,0.043750,0.025000,0.025000},{0.656250,0.043750,0.050000,0.050000},{0.668750,0.043750,0.025000,0.025000},{0.668750,0.043750,0.050000,0.050000},{0.681250,0.043750,0.025000,0.025000},{0.681250,0.043750,0.050000,0.050000},{0.693750,0.043750,0.025000,0.025000},{0.693750,0.043750,0.050000,0.050000},{0.706250,0.043750,0.025000,0.025000},{0.706250,0.043750,0.050000,0.050000},{0.718750,0.043750,0.025000,0.025000},{0.718750,0.043750,0.050000,0.050000},{0.731250,0.043750,0.025000,0.025000},{0.731250,0.043750,0.050000,0.050000},{0.743750,0.043750,0.025000,0.025000},{0.743750,0.043750,0.050000,0.050000},{0.756250,0.043750,0.025000,0.025000},{0.756250,0.043750,0.050000,0.050000},{0.768750,0.043750,0.025000,0.025000},{0.768750,0.043750,0.050000,0.050000},{0.781250,0.043750,0.025000,0.025000},{0.781250,0.043750,0.050000,0.050000},{0.793750,0.043750,0.025000,0.025000},{0.793750,0.043750,0.050000,0.050000},{0.806250,0.043750,0.025000,0.025000},{0.806250,0.043750,0.050000,0.050000},{0.818750,0.043750,0.025000,0.025000},{0.818750,0.043750,0.050000,0.050000},{0.831250,0.043750,0.025000,0.025000},{0.831250,0.043750,0.050000,0.050000},{0.843750,0.043750,0.025000,0.025000},{0.843750,0.043750,0.050000,0.050000},{0.856250,0.043750,0.025000,0.025000},{0.856250,0.043750,0.050000,0.050000},{0.868750,0.043750,0.025000,0.025000},{0.868750,0.043750,0.050000,0.050000},{0.881250,0.043750,0.025000,0.025000},{0.881250,0.043750,0.050000,0.050000},{0.893750,0.043750,0.025000,0.025000},{0.893750,0.043750,0.050000,0.050000},{0.906250,0.043750,0.025000,0.025000},{0.906250,0.043750,0.050000,0.050000},{0.918750,0.043750,0.025000,0.025000},{0.918750,0.043750,0.050000,0.050000},{0.931250,0.043750,0.025000,0.025000},{0.931250,0.043750,0.050000,0.050000},{0.943750,0.043750,0.025000,0.025000},{0.943750,0.043750,0.050000,0.050000},{0.956250,0.043750,0.025000,0.025000},{0.956250,0.043750,0.050000,0.050000},{0.968750,0.043750,0.025000,0.025000},{0.968750,0.043750,0.050000,0.050000},{0.981250,0.043750,0.025000,0.025000},{0.981250,0.043750,0.050000,0.050000},{0.993750,0.043750,0.025000,0.025000},{0.993750,0.043750,0.050000,0.050000},{0.006250,0.056250,0.025000,0.025000},{0.006250,0.056250,0.050000,0.050000},{0.018750,0.056250,0.025000,0.025000},{0.018750,0.056250,0.050000,0.050000},{0.031250,0.056250,0.025000,0.025000},{0.031250,0.056250,0.050000,0.050000},{0.043750,0.056250,0.025000,0.025000},{0.043750,0.056250,0.050000,0.050000},{0.056250,0.056250,0.025000,0.025000},{0.056250,0.056250,0.050000,0.050000},{0.068750,0.056250,0.025000,0.025000},{0.068750,0.056250,0.050000,0.050000},{0.081250,0.056250,0.025000,0.025000},{0.081250,0.056250,0.050000,0.050000},{0.093750,0.056250,0.025000,0.025000},{0.093750,0.056250,0.050000,0.050000},{0.106250,0.056250,0.025000,0.025000},{0.106250,0.056250,0.050000,0.050000},{0.118750,0.056250,0.025000,0.025000},{0.118750,0.056250,0.050000,0.050000},{0.131250,0.056250,0.025000,0.025000},{0.131250,0.056250,0.050000,0.050000},{0.143750,0.056250,0.025000,0.025000},{0.143750,0.056250,0.050000,0.050000},{0.156250,0.056250,0.025000,0.025000},{0.156250,0.056250,0.050000,0.050000},{0.168750,0.056250,0.025000,0.025000},{0.168750,0.056250,0.050000,0.050000},{0.181250,0.056250,0.025000,0.025000},{0.181250,0.056250,0.050000,0.050000},{0.193750,0.056250,0.025000,0.025000},{0.193750,0.056250,0.050000,0.050000},{0.206250,0.056250,0.025000,0.025000},{0.206250,0.056250,0.050000,0.050000},{0.218750,0.056250,0.025000,0.025000},{0.218750,0.056250,0.050000,0.050000},{0.231250,0.056250,0.025000,0.025000},{0.231250,0.056250,0.050000,0.050000},{0.243750,0.056250,0.025000,0.025000},{0.243750,0.056250,0.050000,0.050000},{0.256250,0.056250,0.025000,0.025000},{0.256250,0.056250,0.050000,0.050000},{0.268750,0.056250,0.025000,0.025000},{0.268750,0.056250,0.050000,0.050000},{0.281250,0.056250,0.025000,0.025000},{0.281250,0.056250,0.050000,0.050000},{0.293750,0.056250,0.025000,0.025000},{0.293750,0.056250,0.050000,0.050000},{0.306250,0.056250,0.025000,0.025000},{0.306250,0.056250,0.050000,0.050000},{0.318750,0.056250,0.025000,0.025000},{0.318750,0.056250,0.050000,0.050000},{0.331250,0.056250,0.025000,0.025000},{0.331250,0.056250,0.050000,0.050000},{0.343750,0.056250,0.025000,0.025000},{0.343750,0.056250,0.050000,0.050000},{0.356250,0.056250,0.025000,0.025000},{0.356250,0.056250,0.050000,0.050000},{0.368750,0.056250,0.025000,0.025000},{0.368750,0.056250,0.050000,0.050000},{0.381250,0.056250,0.025000,0.025000},{0.381250,0.056250,0.050000,0.050000},{0.393750,0.056250,0.025000,0.025000},{0.393750,0.056250,0.050000,0.050000},{0.406250,0.056250,0.025000,0.025000},{0.406250,0.056250,0.050000,0.050000},{0.418750,0.056250,0.025000,0.025000},{0.418750,0.056250,0.050000,0.050000},{0.431250,0.056250,0.025000,0.025000},{0.431250,0.056250,0.050000,0.050000},{0.443750,0.056250,0.025000,0.025000},{0.443750,0.056250,0.050000,0.050000},{0.456250,0.056250,0.025000,0.025000},{0.456250,0.056250,0.050000,0.050000},{0.468750,0.056250,0.025000,0.025000},{0.468750,0.056250,0.050000,0.050000},{0.481250,0.056250,0.025000,0.025000},{0.481250,0.056250,0.050000,0.050000},{0.493750,0.056250,0.025000,0.025000},{0.493750,0.056250,0.050000,0.050000},{0.506250,0.056250,0.025000,0.025000},{0.506250,0.056250,0.050000,0.050000},{0.518750,0.056250,0.025000,0.025000},{0.518750,0.056250,0.050000,0.050000},{0.531250,0.056250,0.025000,0.025000},{0.531250,0.056250,0.050000,0.050000},{0.543750,0.056250,0.025000,0.025000},{0.543750,0.056250,0.050000,0.050000},{0.556250,0.056250,0.025000,0.025000},{0.556250,0.056250,0.050000,0.050000},{0.568750,0.056250,0.025000,0.025000},{0.568750,0.056250,0.050000,0.050000},{0.581250,0.056250,0.025000,0.025000},{0.581250,0.056250,0.050000,0.050000},{0.593750,0.056250,0.025000,0.025000},{0.593750,0.056250,0.050000,0.050000},{0.606250,0.056250,0.025000,0.025000},{0.606250,0.056250,0.050000,0.050000},{0.618750,0.056250,0.025000,0.025000},{0.618750,0.056250,0.050000,0.050000},{0.631250,0.056250,0.025000,0.025000},{0.631250,0.056250,0.050000,0.050000},{0.643750,0.056250,0.025000,0.025000},{0.643750,0.056250,0.050000,0.050000},{0.656250,0.056250,0.025000,0.025000},{0.656250,0.056250,0.050000,0.050000},{0.668750,0.056250,0.025000,0.025000},{0.668750,0.056250,0.050000,0.050000},{0.681250,0.056250,0.025000,0.025000},{0.681250,0.056250,0.050000,0.050000},{0.693750,0.056250,0.025000,0.025000},{0.693750,0.056250,0.050000,0.050000},{0.706250,0.056250,0.025000,0.025000},{0.706250,0.056250,0.050000,0.050000},{0.718750,0.056250,0.025000,0.025000},{0.718750,0.056250,0.050000,0.050000},{0.731250,0.056250,0.025000,0.025000},{0.731250,0.056250,0.050000,0.050000},{0.743750,0.056250,0.025000,0.025000},{0.743750,0.056250,0.050000,0.050000},{0.756250,0.056250,0.025000,0.025000},{0.756250,0.056250,0.050000,0.050000},{0.768750,0.056250,0.025000,0.025000},{0.768750,0.056250,0.050000,0.050000},{0.781250,0.056250,0.025000,0.025000},{0.781250,0.056250,0.050000,0.050000},{0.793750,0.056250,0.025000,0.025000},{0.793750,0.056250,0.050000,0.050000},{0.806250,0.056250,0.025000,0.025000},{0.806250,0.056250,0.050000,0.050000},{0.818750,0.056250,0.025000,0.025000},{0.818750,0.056250,0.050000,0.050000},{0.831250,0.056250,0.025000,0.025000},{0.831250,0.056250,0.050000,0.050000},{0.843750,0.056250,0.025000,0.025000},{0.843750,0.056250,0.050000,0.050000},{0.856250,0.056250,0.025000,0.025000},{0.856250,0.056250,0.050000,0.050000},{0.868750,0.056250,0.025000,0.025000},{0.868750,0.056250,0.050000,0.050000},{0.881250,0.056250,0.025000,0.025000},{0.881250,0.056250,0.050000,0.050000},{0.893750,0.056250,0.025000,0.025000},{0.893750,0.056250,0.050000,0.050000},{0.906250,0.056250,0.025000,0.025000},{0.906250,0.056250,0.050000,0.050000},{0.918750,0.056250,0.025000,0.025000},{0.918750,0.056250,0.050000,0.050000},{0.931250,0.056250,0.025000,0.025000},{0.931250,0.056250,0.050000,0.050000},{0.943750,0.056250,0.025000,0.025000},{0.943750,0.056250,0.050000,0.050000},{0.956250,0.056250,0.025000,0.025000},{0.956250,0.056250,0.050000,0.050000},{0.968750,0.056250,0.025000,0.025000},{0.968750,0.056250,0.050000,0.050000},{0.981250,0.056250,0.025000,0.025000},{0.981250,0.056250,0.050000,0.050000},{0.993750,0.056250,0.025000,0.025000},{0.993750,0.056250,0.050000,0.050000},{0.006250,0.068750,0.025000,0.025000},{0.006250,0.068750,0.050000,0.050000},{0.018750,0.068750,0.025000,0.025000},{0.018750,0.068750,0.050000,0.050000},{0.031250,0.068750,0.025000,0.025000},{0.031250,0.068750,0.050000,0.050000},{0.043750,0.068750,0.025000,0.025000},{0.043750,0.068750,0.050000,0.050000},{0.056250,0.068750,0.025000,0.025000},{0.056250,0.068750,0.050000,0.050000},{0.068750,0.068750,0.025000,0.025000},{0.068750,0.068750,0.050000,0.050000},{0.081250,0.068750,0.025000,0.025000},{0.081250,0.068750,0.050000,0.050000},{0.093750,0.068750,0.025000,0.025000},{0.093750,0.068750,0.050000,0.050000},{0.106250,0.068750,0.025000,0.025000},{0.106250,0.068750,0.050000,0.050000},{0.118750,0.068750,0.025000,0.025000},{0.118750,0.068750,0.050000,0.050000},{0.131250,0.068750,0.025000,0.025000},{0.131250,0.068750,0.050000,0.050000},{0.143750,0.068750,0.025000,0.025000},{0.143750,0.068750,0.050000,0.050000},{0.156250,0.068750,0.025000,0.025000},{0.156250,0.068750,0.050000,0.050000},{0.168750,0.068750,0.025000,0.025000},{0.168750,0.068750,0.050000,0.050000},{0.181250,0.068750,0.025000,0.025000},{0.181250,0.068750,0.050000,0.050000},{0.193750,0.068750,0.025000,0.025000},{0.193750,0.068750,0.050000,0.050000},{0.206250,0.068750,0.025000,0.025000},{0.206250,0.068750,0.050000,0.050000},{0.218750,0.068750,0.025000,0.025000},{0.218750,0.068750,0.050000,0.050000},{0.231250,0.068750,0.025000,0.025000},{0.231250,0.068750,0.050000,0.050000},{0.243750,0.068750,0.025000,0.025000},{0.243750,0.068750,0.050000,0.050000},{0.256250,0.068750,0.025000,0.025000},{0.256250,0.068750,0.050000,0.050000},{0.268750,0.068750,0.025000,0.025000},{0.268750,0.068750,0.050000,0.050000},{0.281250,0.068750,0.025000,0.025000},{0.281250,0.068750,0.050000,0.050000},{0.293750,0.068750,0.025000,0.025000},{0.293750,0.068750,0.050000,0.050000},{0.306250,0.068750,0.025000,0.025000},{0.306250,0.068750,0.050000,0.050000},{0.318750,0.068750,0.025000,0.025000},{0.318750,0.068750,0.050000,0.050000},{0.331250,0.068750,0.025000,0.025000},{0.331250,0.068750,0.050000,0.050000},{0.343750,0.068750,0.025000,0.025000},{0.343750,0.068750,0.050000,0.050000},{0.356250,0.068750,0.025000,0.025000},{0.356250,0.068750,0.050000,0.050000},{0.368750,0.068750,0.025000,0.025000},{0.368750,0.068750,0.050000,0.050000},{0.381250,0.068750,0.025000,0.025000},{0.381250,0.068750,0.050000,0.050000},{0.393750,0.068750,0.025000,0.025000},{0.393750,0.068750,0.050000,0.050000},{0.406250,0.068750,0.025000,0.025000},{0.406250,0.068750,0.050000,0.050000},{0.418750,0.068750,0.025000,0.025000},{0.418750,0.068750,0.050000,0.050000},{0.431250,0.068750,0.025000,0.025000},{0.431250,0.068750,0.050000,0.050000},{0.443750,0.068750,0.025000,0.025000},{0.443750,0.068750,0.050000,0.050000},{0.456250,0.068750,0.025000,0.025000},{0.456250,0.068750,0.050000,0.050000},{0.468750,0.068750,0.025000,0.025000},{0.468750,0.068750,0.050000,0.050000},{0.481250,0.068750,0.025000,0.025000},{0.481250,0.068750,0.050000,0.050000},{0.493750,0.068750,0.025000,0.025000},{0.493750,0.068750,0.050000,0.050000},{0.506250,0.068750,0.025000,0.025000},{0.506250,0.068750,0.050000,0.050000},{0.518750,0.068750,0.025000,0.025000},{0.518750,0.068750,0.050000,0.050000},{0.531250,0.068750,0.025000,0.025000},{0.531250,0.068750,0.050000,0.050000},{0.543750,0.068750,0.025000,0.025000},{0.543750,0.068750,0.050000,0.050000},{0.556250,0.068750,0.025000,0.025000},{0.556250,0.068750,0.050000,0.050000},{0.568750,0.068750,0.025000,0.025000},{0.568750,0.068750,0.050000,0.050000},{0.581250,0.068750,0.025000,0.025000},{0.581250,0.068750,0.050000,0.050000},{0.593750,0.068750,0.025000,0.025000},{0.593750,0.068750,0.050000,0.050000},{0.606250,0.068750,0.025000,0.025000},{0.606250,0.068750,0.050000,0.050000},{0.618750,0.068750,0.025000,0.025000},{0.618750,0.068750,0.050000,0.050000},{0.631250,0.068750,0.025000,0.025000},{0.631250,0.068750,0.050000,0.050000},{0.643750,0.068750,0.025000,0.025000},{0.643750,0.068750,0.050000,0.050000},{0.656250,0.068750,0.025000,0.025000},{0.656250,0.068750,0.050000,0.050000},{0.668750,0.068750,0.025000,0.025000},{0.668750,0.068750,0.050000,0.050000},{0.681250,0.068750,0.025000,0.025000},{0.681250,0.068750,0.050000,0.050000},{0.693750,0.068750,0.025000,0.025000},{0.693750,0.068750,0.050000,0.050000},{0.706250,0.068750,0.025000,0.025000},{0.706250,0.068750,0.050000,0.050000},{0.718750,0.068750,0.025000,0.025000},{0.718750,0.068750,0.050000,0.050000},{0.731250,0.068750,0.025000,0.025000},{0.731250,0.068750,0.050000,0.050000},{0.743750,0.068750,0.025000,0.025000},{0.743750,0.068750,0.050000,0.050000},{0.756250,0.068750,0.025000,0.025000},{0.756250,0.068750,0.050000,0.050000},{0.768750,0.068750,0.025000,0.025000},{0.768750,0.068750,0.050000,0.050000},{0.781250,0.068750,0.025000,0.025000},{0.781250,0.068750,0.050000,0.050000},{0.793750,0.068750,0.025000,0.025000},{0.793750,0.068750,0.050000,0.050000},{0.806250,0.068750,0.025000,0.025000},{0.806250,0.068750,0.050000,0.050000},{0.818750,0.068750,0.025000,0.025000},{0.818750,0.068750,0.050000,0.050000},{0.831250,0.068750,0.025000,0.025000},{0.831250,0.068750,0.050000,0.050000},{0.843750,0.068750,0.025000,0.025000},{0.843750,0.068750,0.050000,0.050000},{0.856250,0.068750,0.025000,0.025000},{0.856250,0.068750,0.050000,0.050000},{0.868750,0.068750,0.025000,0.025000},{0.868750,0.068750,0.050000,0.050000},{0.881250,0.068750,0.025000,0.025000},{0.881250,0.068750,0.050000,0.050000},{0.893750,0.068750,0.025000,0.025000},{0.893750,0.068750,0.050000,0.050000},{0.906250,0.068750,0.025000,0.025000},{0.906250,0.068750,0.050000,0.050000},{0.918750,0.068750,0.025000,0.025000},{0.918750,0.068750,0.050000,0.050000},{0.931250,0.068750,0.025000,0.025000},{0.931250,0.068750,0.050000,0.050000},{0.943750,0.068750,0.025000,0.025000},{0.943750,0.068750,0.050000,0.050000},{0.956250,0.068750,0.025000,0.025000},{0.956250,0.068750,0.050000,0.050000},{0.968750,0.068750,0.025000,0.025000},{0.968750,0.068750,0.050000,0.050000},{0.981250,0.068750,0.025000,0.025000},{0.981250,0.068750,0.050000,0.050000},{0.993750,0.068750,0.025000,0.025000},{0.993750,0.068750,0.050000,0.050000},{0.006250,0.081250,0.025000,0.025000},{0.006250,0.081250,0.050000,0.050000},{0.018750,0.081250,0.025000,0.025000},{0.018750,0.081250,0.050000,0.050000},{0.031250,0.081250,0.025000,0.025000},{0.031250,0.081250,0.050000,0.050000},{0.043750,0.081250,0.025000,0.025000},{0.043750,0.081250,0.050000,0.050000},{0.056250,0.081250,0.025000,0.025000},{0.056250,0.081250,0.050000,0.050000},{0.068750,0.081250,0.025000,0.025000},{0.068750,0.081250,0.050000,0.050000},{0.081250,0.081250,0.025000,0.025000},{0.081250,0.081250,0.050000,0.050000},{0.093750,0.081250,0.025000,0.025000},{0.093750,0.081250,0.050000,0.050000},{0.106250,0.081250,0.025000,0.025000},{0.106250,0.081250,0.050000,0.050000},{0.118750,0.081250,0.025000,0.025000},{0.118750,0.081250,0.050000,0.050000},{0.131250,0.081250,0.025000,0.025000},{0.131250,0.081250,0.050000,0.050000},{0.143750,0.081250,0.025000,0.025000},{0.143750,0.081250,0.050000,0.050000},{0.156250,0.081250,0.025000,0.025000},{0.156250,0.081250,0.050000,0.050000},{0.168750,0.081250,0.025000,0.025000},{0.168750,0.081250,0.050000,0.050000},{0.181250,0.081250,0.025000,0.025000},{0.181250,0.081250,0.050000,0.050000},{0.193750,0.081250,0.025000,0.025000},{0.193750,0.081250,0.050000,0.050000},{0.206250,0.081250,0.025000,0.025000},{0.206250,0.081250,0.050000,0.050000},{0.218750,0.081250,0.025000,0.025000},{0.218750,0.081250,0.050000,0.050000},{0.231250,0.081250,0.025000,0.025000},{0.231250,0.081250,0.050000,0.050000},{0.243750,0.081250,0.025000,0.025000},{0.243750,0.081250,0.050000,0.050000},{0.256250,0.081250,0.025000,0.025000},{0.256250,0.081250,0.050000,0.050000},{0.268750,0.081250,0.025000,0.025000},{0.268750,0.081250,0.050000,0.050000},{0.281250,0.081250,0.025000,0.025000},{0.281250,0.081250,0.050000,0.050000},{0.293750,0.081250,0.025000,0.025000},{0.293750,0.081250,0.050000,0.050000},{0.306250,0.081250,0.025000,0.025000},{0.306250,0.081250,0.050000,0.050000},{0.318750,0.081250,0.025000,0.025000},{0.318750,0.081250,0.050000,0.050000},{0.331250,0.081250,0.025000,0.025000},{0.331250,0.081250,0.050000,0.050000},{0.343750,0.081250,0.025000,0.025000},{0.343750,0.081250,0.050000,0.050000},{0.356250,0.081250,0.025000,0.025000},{0.356250,0.081250,0.050000,0.050000},{0.368750,0.081250,0.025000,0.025000},{0.368750,0.081250,0.050000,0.050000},{0.381250,0.081250,0.025000,0.025000},{0.381250,0.081250,0.050000,0.050000},{0.393750,0.081250,0.025000,0.025000},{0.393750,0.081250,0.050000,0.050000},{0.406250,0.081250,0.025000,0.025000},{0.406250,0.081250,0.050000,0.050000},{0.418750,0.081250,0.025000,0.025000},{0.418750,0.081250,0.050000,0.050000},{0.431250,0.081250,0.025000,0.025000},{0.431250,0.081250,0.050000,0.050000},{0.443750,0.081250,0.025000,0.025000},{0.443750,0.081250,0.050000,0.050000},{0.456250,0.081250,0.025000,0.025000},{0.456250,0.081250,0.050000,0.050000},{0.468750,0.081250,0.025000,0.025000},{0.468750,0.081250,0.050000,0.050000},{0.481250,0.081250,0.025000,0.025000},{0.481250,0.081250,0.050000,0.050000},{0.493750,0.081250,0.025000,0.025000},{0.493750,0.081250,0.050000,0.050000},{0.506250,0.081250,0.025000,0.025000},{0.506250,0.081250,0.050000,0.050000},{0.518750,0.081250,0.025000,0.025000},{0.518750,0.081250,0.050000,0.050000},{0.531250,0.081250,0.025000,0.025000},{0.531250,0.081250,0.050000,0.050000},{0.543750,0.081250,0.025000,0.025000},{0.543750,0.081250,0.050000,0.050000},{0.556250,0.081250,0.025000,0.025000},{0.556250,0.081250,0.050000,0.050000},{0.568750,0.081250,0.025000,0.025000},{0.568750,0.081250,0.050000,0.050000},{0.581250,0.081250,0.025000,0.025000},{0.581250,0.081250,0.050000,0.050000},{0.593750,0.081250,0.025000,0.025000},{0.593750,0.081250,0.050000,0.050000},{0.606250,0.081250,0.025000,0.025000},{0.606250,0.081250,0.050000,0.050000},{0.618750,0.081250,0.025000,0.025000},{0.618750,0.081250,0.050000,0.050000},{0.631250,0.081250,0.025000,0.025000},{0.631250,0.081250,0.050000,0.050000},{0.643750,0.081250,0.025000,0.025000},{0.643750,0.081250,0.050000,0.050000},{0.656250,0.081250,0.025000,0.025000},{0.656250,0.081250,0.050000,0.050000},{0.668750,0.081250,0.025000,0.025000},{0.668750,0.081250,0.050000,0.050000},{0.681250,0.081250,0.025000,0.025000},{0.681250,0.081250,0.050000,0.050000},{0.693750,0.081250,0.025000,0.025000},{0.693750,0.081250,0.050000,0.050000},{0.706250,0.081250,0.025000,0.025000},{0.706250,0.081250,0.050000,0.050000},{0.718750,0.081250,0.025000,0.025000},{0.718750,0.081250,0.050000,0.050000},{0.731250,0.081250,0.025000,0.025000},{0.731250,0.081250,0.050000,0.050000},{0.743750,0.081250,0.025000,0.025000},{0.743750,0.081250,0.050000,0.050000},{0.756250,0.081250,0.025000,0.025000},{0.756250,0.081250,0.050000,0.050000},{0.768750,0.081250,0.025000,0.025000},{0.768750,0.081250,0.050000,0.050000},{0.781250,0.081250,0.025000,0.025000},{0.781250,0.081250,0.050000,0.050000},{0.793750,0.081250,0.025000,0.025000},{0.793750,0.081250,0.050000,0.050000},{0.806250,0.081250,0.025000,0.025000},{0.806250,0.081250,0.050000,0.050000},{0.818750,0.081250,0.025000,0.025000},{0.818750,0.081250,0.050000,0.050000},{0.831250,0.081250,0.025000,0.025000},{0.831250,0.081250,0.050000,0.050000},{0.843750,0.081250,0.025000,0.025000},{0.843750,0.081250,0.050000,0.050000},{0.856250,0.081250,0.025000,0.025000},{0.856250,0.081250,0.050000,0.050000},{0.868750,0.081250,0.025000,0.025000},{0.868750,0.081250,0.050000,0.050000},{0.881250,0.081250,0.025000,0.025000},{0.881250,0.081250,0.050000,0.050000},{0.893750,0.081250,0.025000,0.025000},{0.893750,0.081250,0.050000,0.050000},{0.906250,0.081250,0.025000,0.025000},{0.906250,0.081250,0.050000,0.050000},{0.918750,0.081250,0.025000,0.025000},{0.918750,0.081250,0.050000,0.050000},{0.931250,0.081250,0.025000,0.025000},{0.931250,0.081250,0.050000,0.050000},{0.943750,0.081250,0.025000,0.025000},{0.943750,0.081250,0.050000,0.050000},{0.956250,0.081250,0.025000,0.025000},{0.956250,0.081250,0.050000,0.050000},{0.968750,0.081250,0.025000,0.025000},{0.968750,0.081250,0.050000,0.050000},{0.981250,0.081250,0.025000,0.025000},{0.981250,0.081250,0.050000,0.050000},{0.993750,0.081250,0.025000,0.025000},{0.993750,0.081250,0.050000,0.050000},{0.006250,0.093750,0.025000,0.025000},{0.006250,0.093750,0.050000,0.050000},{0.018750,0.093750,0.025000,0.025000},{0.018750,0.093750,0.050000,0.050000},{0.031250,0.093750,0.025000,0.025000},{0.031250,0.093750,0.050000,0.050000},{0.043750,0.093750,0.025000,0.025000},{0.043750,0.093750,0.050000,0.050000},{0.056250,0.093750,0.025000,0.025000},{0.056250,0.093750,0.050000,0.050000},{0.068750,0.093750,0.025000,0.025000},{0.068750,0.093750,0.050000,0.050000},{0.081250,0.093750,0.025000,0.025000},{0.081250,0.093750,0.050000,0.050000},{0.093750,0.093750,0.025000,0.025000},{0.093750,0.093750,0.050000,0.050000},{0.106250,0.093750,0.025000,0.025000},{0.106250,0.093750,0.050000,0.050000},{0.118750,0.093750,0.025000,0.025000},{0.118750,0.093750,0.050000,0.050000},{0.131250,0.093750,0.025000,0.025000},{0.131250,0.093750,0.050000,0.050000},{0.143750,0.093750,0.025000,0.025000},{0.143750,0.093750,0.050000,0.050000},{0.156250,0.093750,0.025000,0.025000},{0.156250,0.093750,0.050000,0.050000},{0.168750,0.093750,0.025000,0.025000},{0.168750,0.093750,0.050000,0.050000},{0.181250,0.093750,0.025000,0.025000},{0.181250,0.093750,0.050000,0.050000},{0.193750,0.093750,0.025000,0.025000},{0.193750,0.093750,0.050000,0.050000},{0.206250,0.093750,0.025000,0.025000},{0.206250,0.093750,0.050000,0.050000},{0.218750,0.093750,0.025000,0.025000},{0.218750,0.093750,0.050000,0.050000},{0.231250,0.093750,0.025000,0.025000},{0.231250,0.093750,0.050000,0.050000},{0.243750,0.093750,0.025000,0.025000},{0.243750,0.093750,0.050000,0.050000},{0.256250,0.093750,0.025000,0.025000},{0.256250,0.093750,0.050000,0.050000},{0.268750,0.093750,0.025000,0.025000},{0.268750,0.093750,0.050000,0.050000},{0.281250,0.093750,0.025000,0.025000},{0.281250,0.093750,0.050000,0.050000},{0.293750,0.093750,0.025000,0.025000},{0.293750,0.093750,0.050000,0.050000},{0.306250,0.093750,0.025000,0.025000},{0.306250,0.093750,0.050000,0.050000},{0.318750,0.093750,0.025000,0.025000},{0.318750,0.093750,0.050000,0.050000},{0.331250,0.093750,0.025000,0.025000},{0.331250,0.093750,0.050000,0.050000},{0.343750,0.093750,0.025000,0.025000},{0.343750,0.093750,0.050000,0.050000},{0.356250,0.093750,0.025000,0.025000},{0.356250,0.093750,0.050000,0.050000},{0.368750,0.093750,0.025000,0.025000},{0.368750,0.093750,0.050000,0.050000},{0.381250,0.093750,0.025000,0.025000},{0.381250,0.093750,0.050000,0.050000},{0.393750,0.093750,0.025000,0.025000},{0.393750,0.093750,0.050000,0.050000},{0.406250,0.093750,0.025000,0.025000},{0.406250,0.093750,0.050000,0.050000},{0.418750,0.093750,0.025000,0.025000},{0.418750,0.093750,0.050000,0.050000},{0.431250,0.093750,0.025000,0.025000},{0.431250,0.093750,0.050000,0.050000},{0.443750,0.093750,0.025000,0.025000},{0.443750,0.093750,0.050000,0.050000},{0.456250,0.093750,0.025000,0.025000},{0.456250,0.093750,0.050000,0.050000},{0.468750,0.093750,0.025000,0.025000},{0.468750,0.093750,0.050000,0.050000},{0.481250,0.093750,0.025000,0.025000},{0.481250,0.093750,0.050000,0.050000},{0.493750,0.093750,0.025000,0.025000},{0.493750,0.093750,0.050000,0.050000},{0.506250,0.093750,0.025000,0.025000},{0.506250,0.093750,0.050000,0.050000},{0.518750,0.093750,0.025000,0.025000},{0.518750,0.093750,0.050000,0.050000},{0.531250,0.093750,0.025000,0.025000},{0.531250,0.093750,0.050000,0.050000},{0.543750,0.093750,0.025000,0.025000},{0.543750,0.093750,0.050000,0.050000},{0.556250,0.093750,0.025000,0.025000},{0.556250,0.093750,0.050000,0.050000},{0.568750,0.093750,0.025000,0.025000},{0.568750,0.093750,0.050000,0.050000},{0.581250,0.093750,0.025000,0.025000},{0.581250,0.093750,0.050000,0.050000},{0.593750,0.093750,0.025000,0.025000},{0.593750,0.093750,0.050000,0.050000},{0.606250,0.093750,0.025000,0.025000},{0.606250,0.093750,0.050000,0.050000},{0.618750,0.093750,0.025000,0.025000},{0.618750,0.093750,0.050000,0.050000},{0.631250,0.093750,0.025000,0.025000},{0.631250,0.093750,0.050000,0.050000},{0.643750,0.093750,0.025000,0.025000},{0.643750,0.093750,0.050000,0.050000},{0.656250,0.093750,0.025000,0.025000},{0.656250,0.093750,0.050000,0.050000},{0.668750,0.093750,0.025000,0.025000},{0.668750,0.093750,0.050000,0.050000},{0.681250,0.093750,0.025000,0.025000},{0.681250,0.093750,0.050000,0.050000},{0.693750,0.093750,0.025000,0.025000},{0.693750,0.093750,0.050000,0.050000},{0.706250,0.093750,0.025000,0.025000},{0.706250,0.093750,0.050000,0.050000},{0.718750,0.093750,0.025000,0.025000},{0.718750,0.093750,0.050000,0.050000},{0.731250,0.093750,0.025000,0.025000},{0.731250,0.093750,0.050000,0.050000},{0.743750,0.093750,0.025000,0.025000},{0.743750,0.093750,0.050000,0.050000},{0.756250,0.093750,0.025000,0.025000},{0.756250,0.093750,0.050000,0.050000},{0.768750,0.093750,0.025000,0.025000},{0.768750,0.093750,0.050000,0.050000},{0.781250,0.093750,0.025000,0.025000},{0.781250,0.093750,0.050000,0.050000},{0.793750,0.093750,0.025000,0.025000},{0.793750,0.093750,0.050000,0.050000},{0.806250,0.093750,0.025000,0.025000},{0.806250,0.093750,0.050000,0.050000},{0.818750,0.093750,0.025000,0.025000},{0.818750,0.093750,0.050000,0.050000},{0.831250,0.093750,0.025000,0.025000},{0.831250,0.093750,0.050000,0.050000},{0.843750,0.093750,0.025000,0.025000},{0.843750,0.093750,0.050000,0.050000},{0.856250,0.093750,0.025000,0.025000},{0.856250,0.093750,0.050000,0.050000},{0.868750,0.093750,0.025000,0.025000},{0.868750,0.093750,0.050000,0.050000},{0.881250,0.093750,0.025000,0.025000},{0.881250,0.093750,0.050000,0.050000},{0.893750,0.093750,0.025000,0.025000},{0.893750,0.093750,0.050000,0.050000},{0.906250,0.093750,0.025000,0.025000},{0.906250,0.093750,0.050000,0.050000},{0.918750,0.093750,0.025000,0.025000},{0.918750,0.093750,0.050000,0.050000},{0.931250,0.093750,0.025000,0.025000},{0.931250,0.093750,0.050000,0.050000},{0.943750,0.093750,0.025000,0.025000},{0.943750,0.093750,0.050000,0.050000},{0.956250,0.093750,0.025000,0.025000},{0.956250,0.093750,0.050000,0.050000},{0.968750,0.093750,0.025000,0.025000},{0.968750,0.093750,0.050000,0.050000},{0.981250,0.093750,0.025000,0.025000},{0.981250,0.093750,0.050000,0.050000},{0.993750,0.093750,0.025000,0.025000},{0.993750,0.093750,0.050000,0.050000},{0.006250,0.106250,0.025000,0.025000},{0.006250,0.106250,0.050000,0.050000},{0.018750,0.106250,0.025000,0.025000},{0.018750,0.106250,0.050000,0.050000},{0.031250,0.106250,0.025000,0.025000},{0.031250,0.106250,0.050000,0.050000},{0.043750,0.106250,0.025000,0.025000},{0.043750,0.106250,0.050000,0.050000},{0.056250,0.106250,0.025000,0.025000},{0.056250,0.106250,0.050000,0.050000},{0.068750,0.106250,0.025000,0.025000},{0.068750,0.106250,0.050000,0.050000},{0.081250,0.106250,0.025000,0.025000},{0.081250,0.106250,0.050000,0.050000},{0.093750,0.106250,0.025000,0.025000},{0.093750,0.106250,0.050000,0.050000},{0.106250,0.106250,0.025000,0.025000},{0.106250,0.106250,0.050000,0.050000},{0.118750,0.106250,0.025000,0.025000},{0.118750,0.106250,0.050000,0.050000},{0.131250,0.106250,0.025000,0.025000},{0.131250,0.106250,0.050000,0.050000},{0.143750,0.106250,0.025000,0.025000},{0.143750,0.106250,0.050000,0.050000},{0.156250,0.106250,0.025000,0.025000},{0.156250,0.106250,0.050000,0.050000},{0.168750,0.106250,0.025000,0.025000},{0.168750,0.106250,0.050000,0.050000},{0.181250,0.106250,0.025000,0.025000},{0.181250,0.106250,0.050000,0.050000},{0.193750,0.106250,0.025000,0.025000},{0.193750,0.106250,0.050000,0.050000},{0.206250,0.106250,0.025000,0.025000},{0.206250,0.106250,0.050000,0.050000},{0.218750,0.106250,0.025000,0.025000},{0.218750,0.106250,0.050000,0.050000},{0.231250,0.106250,0.025000,0.025000},{0.231250,0.106250,0.050000,0.050000},{0.243750,0.106250,0.025000,0.025000},{0.243750,0.106250,0.050000,0.050000},{0.256250,0.106250,0.025000,0.025000},{0.256250,0.106250,0.050000,0.050000},{0.268750,0.106250,0.025000,0.025000},{0.268750,0.106250,0.050000,0.050000},{0.281250,0.106250,0.025000,0.025000},{0.281250,0.106250,0.050000,0.050000},{0.293750,0.106250,0.025000,0.025000},{0.293750,0.106250,0.050000,0.050000},{0.306250,0.106250,0.025000,0.025000},{0.306250,0.106250,0.050000,0.050000},{0.318750,0.106250,0.025000,0.025000},{0.318750,0.106250,0.050000,0.050000},{0.331250,0.106250,0.025000,0.025000},{0.331250,0.106250,0.050000,0.050000},{0.343750,0.106250,0.025000,0.025000},{0.343750,0.106250,0.050000,0.050000},{0.356250,0.106250,0.025000,0.025000},{0.356250,0.106250,0.050000,0.050000},{0.368750,0.106250,0.025000,0.025000},{0.368750,0.106250,0.050000,0.050000},{0.381250,0.106250,0.025000,0.025000},{0.381250,0.106250,0.050000,0.050000},{0.393750,0.106250,0.025000,0.025000},{0.393750,0.106250,0.050000,0.050000},{0.406250,0.106250,0.025000,0.025000},{0.406250,0.106250,0.050000,0.050000},{0.418750,0.106250,0.025000,0.025000},{0.418750,0.106250,0.050000,0.050000},{0.431250,0.106250,0.025000,0.025000},{0.431250,0.106250,0.050000,0.050000},{0.443750,0.106250,0.025000,0.025000},{0.443750,0.106250,0.050000,0.050000},{0.456250,0.106250,0.025000,0.025000},{0.456250,0.106250,0.050000,0.050000},{0.468750,0.106250,0.025000,0.025000},{0.468750,0.106250,0.050000,0.050000},{0.481250,0.106250,0.025000,0.025000},{0.481250,0.106250,0.050000,0.050000},{0.493750,0.106250,0.025000,0.025000},{0.493750,0.106250,0.050000,0.050000},{0.506250,0.106250,0.025000,0.025000},{0.506250,0.106250,0.050000,0.050000},{0.518750,0.106250,0.025000,0.025000},{0.518750,0.106250,0.050000,0.050000},{0.531250,0.106250,0.025000,0.025000},{0.531250,0.106250,0.050000,0.050000},{0.543750,0.106250,0.025000,0.025000},{0.543750,0.106250,0.050000,0.050000},{0.556250,0.106250,0.025000,0.025000},{0.556250,0.106250,0.050000,0.050000},{0.568750,0.106250,0.025000,0.025000},{0.568750,0.106250,0.050000,0.050000},{0.581250,0.106250,0.025000,0.025000},{0.581250,0.106250,0.050000,0.050000},{0.593750,0.106250,0.025000,0.025000},{0.593750,0.106250,0.050000,0.050000},{0.606250,0.106250,0.025000,0.025000},{0.606250,0.106250,0.050000,0.050000},{0.618750,0.106250,0.025000,0.025000},{0.618750,0.106250,0.050000,0.050000},{0.631250,0.106250,0.025000,0.025000},{0.631250,0.106250,0.050000,0.050000},{0.643750,0.106250,0.025000,0.025000},{0.643750,0.106250,0.050000,0.050000},{0.656250,0.106250,0.025000,0.025000},{0.656250,0.106250,0.050000,0.050000},{0.668750,0.106250,0.025000,0.025000},{0.668750,0.106250,0.050000,0.050000},{0.681250,0.106250,0.025000,0.025000},{0.681250,0.106250,0.050000,0.050000},{0.693750,0.106250,0.025000,0.025000},{0.693750,0.106250,0.050000,0.050000},{0.706250,0.106250,0.025000,0.025000},{0.706250,0.106250,0.050000,0.050000},{0.718750,0.106250,0.025000,0.025000},{0.718750,0.106250,0.050000,0.050000},{0.731250,0.106250,0.025000,0.025000},{0.731250,0.106250,0.050000,0.050000},{0.743750,0.106250,0.025000,0.025000},{0.743750,0.106250,0.050000,0.050000},{0.756250,0.106250,0.025000,0.025000},{0.756250,0.106250,0.050000,0.050000},{0.768750,0.106250,0.025000,0.025000},{0.768750,0.106250,0.050000,0.050000},{0.781250,0.106250,0.025000,0.025000},{0.781250,0.106250,0.050000,0.050000},{0.793750,0.106250,0.025000,0.025000},{0.793750,0.106250,0.050000,0.050000},{0.806250,0.106250,0.025000,0.025000},{0.806250,0.106250,0.050000,0.050000},{0.818750,0.106250,0.025000,0.025000},{0.818750,0.106250,0.050000,0.050000},{0.831250,0.106250,0.025000,0.025000},{0.831250,0.106250,0.050000,0.050000},{0.843750,0.106250,0.025000,0.025000},{0.843750,0.106250,0.050000,0.050000},{0.856250,0.106250,0.025000,0.025000},{0.856250,0.106250,0.050000,0.050000},{0.868750,0.106250,0.025000,0.025000},{0.868750,0.106250,0.050000,0.050000},{0.881250,0.106250,0.025000,0.025000},{0.881250,0.106250,0.050000,0.050000},{0.893750,0.106250,0.025000,0.025000},{0.893750,0.106250,0.050000,0.050000},{0.906250,0.106250,0.025000,0.025000},{0.906250,0.106250,0.050000,0.050000},{0.918750,0.106250,0.025000,0.025000},{0.918750,0.106250,0.050000,0.050000},{0.931250,0.106250,0.025000,0.025000},{0.931250,0.106250,0.050000,0.050000},{0.943750,0.106250,0.025000,0.025000},{0.943750,0.106250,0.050000,0.050000},{0.956250,0.106250,0.025000,0.025000},{0.956250,0.106250,0.050000,0.050000},{0.968750,0.106250,0.025000,0.025000},{0.968750,0.106250,0.050000,0.050000},{0.981250,0.106250,0.025000,0.025000},{0.981250,0.106250,0.050000,0.050000},{0.993750,0.106250,0.025000,0.025000},{0.993750,0.106250,0.050000,0.050000},{0.006250,0.118750,0.025000,0.025000},{0.006250,0.118750,0.050000,0.050000},{0.018750,0.118750,0.025000,0.025000},{0.018750,0.118750,0.050000,0.050000},{0.031250,0.118750,0.025000,0.025000},{0.031250,0.118750,0.050000,0.050000},{0.043750,0.118750,0.025000,0.025000},{0.043750,0.118750,0.050000,0.050000},{0.056250,0.118750,0.025000,0.025000},{0.056250,0.118750,0.050000,0.050000},{0.068750,0.118750,0.025000,0.025000},{0.068750,0.118750,0.050000,0.050000},{0.081250,0.118750,0.025000,0.025000},{0.081250,0.118750,0.050000,0.050000},{0.093750,0.118750,0.025000,0.025000},{0.093750,0.118750,0.050000,0.050000},{0.106250,0.118750,0.025000,0.025000},{0.106250,0.118750,0.050000,0.050000},{0.118750,0.118750,0.025000,0.025000},{0.118750,0.118750,0.050000,0.050000},{0.131250,0.118750,0.025000,0.025000},{0.131250,0.118750,0.050000,0.050000},{0.143750,0.118750,0.025000,0.025000},{0.143750,0.118750,0.050000,0.050000},{0.156250,0.118750,0.025000,0.025000},{0.156250,0.118750,0.050000,0.050000},{0.168750,0.118750,0.025000,0.025000},{0.168750,0.118750,0.050000,0.050000},{0.181250,0.118750,0.025000,0.025000},{0.181250,0.118750,0.050000,0.050000},{0.193750,0.118750,0.025000,0.025000},{0.193750,0.118750,0.050000,0.050000},{0.206250,0.118750,0.025000,0.025000},{0.206250,0.118750,0.050000,0.050000},{0.218750,0.118750,0.025000,0.025000},{0.218750,0.118750,0.050000,0.050000},{0.231250,0.118750,0.025000,0.025000},{0.231250,0.118750,0.050000,0.050000},{0.243750,0.118750,0.025000,0.025000},{0.243750,0.118750,0.050000,0.050000},{0.256250,0.118750,0.025000,0.025000},{0.256250,0.118750,0.050000,0.050000},{0.268750,0.118750,0.025000,0.025000},{0.268750,0.118750,0.050000,0.050000},{0.281250,0.118750,0.025000,0.025000},{0.281250,0.118750,0.050000,0.050000},{0.293750,0.118750,0.025000,0.025000},{0.293750,0.118750,0.050000,0.050000},{0.306250,0.118750,0.025000,0.025000},{0.306250,0.118750,0.050000,0.050000},{0.318750,0.118750,0.025000,0.025000},{0.318750,0.118750,0.050000,0.050000},{0.331250,0.118750,0.025000,0.025000},{0.331250,0.118750,0.050000,0.050000},{0.343750,0.118750,0.025000,0.025000},{0.343750,0.118750,0.050000,0.050000},{0.356250,0.118750,0.025000,0.025000},{0.356250,0.118750,0.050000,0.050000},{0.368750,0.118750,0.025000,0.025000},{0.368750,0.118750,0.050000,0.050000},{0.381250,0.118750,0.025000,0.025000},{0.381250,0.118750,0.050000,0.050000},{0.393750,0.118750,0.025000,0.025000},{0.393750,0.118750,0.050000,0.050000},{0.406250,0.118750,0.025000,0.025000},{0.406250,0.118750,0.050000,0.050000},{0.418750,0.118750,0.025000,0.025000},{0.418750,0.118750,0.050000,0.050000},{0.431250,0.118750,0.025000,0.025000},{0.431250,0.118750,0.050000,0.050000},{0.443750,0.118750,0.025000,0.025000},{0.443750,0.118750,0.050000,0.050000},{0.456250,0.118750,0.025000,0.025000},{0.456250,0.118750,0.050000,0.050000},{0.468750,0.118750,0.025000,0.025000},{0.468750,0.118750,0.050000,0.050000},{0.481250,0.118750,0.025000,0.025000},{0.481250,0.118750,0.050000,0.050000},{0.493750,0.118750,0.025000,0.025000},{0.493750,0.118750,0.050000,0.050000},{0.506250,0.118750,0.025000,0.025000},{0.506250,0.118750,0.050000,0.050000},{0.518750,0.118750,0.025000,0.025000},{0.518750,0.118750,0.050000,0.050000},{0.531250,0.118750,0.025000,0.025000},{0.531250,0.118750,0.050000,0.050000},{0.543750,0.118750,0.025000,0.025000},{0.543750,0.118750,0.050000,0.050000},{0.556250,0.118750,0.025000,0.025000},{0.556250,0.118750,0.050000,0.050000},{0.568750,0.118750,0.025000,0.025000},{0.568750,0.118750,0.050000,0.050000},{0.581250,0.118750,0.025000,0.025000},{0.581250,0.118750,0.050000,0.050000},{0.593750,0.118750,0.025000,0.025000},{0.593750,0.118750,0.050000,0.050000},{0.606250,0.118750,0.025000,0.025000},{0.606250,0.118750,0.050000,0.050000},{0.618750,0.118750,0.025000,0.025000},{0.618750,0.118750,0.050000,0.050000},{0.631250,0.118750,0.025000,0.025000},{0.631250,0.118750,0.050000,0.050000},{0.643750,0.118750,0.025000,0.025000},{0.643750,0.118750,0.050000,0.050000},{0.656250,0.118750,0.025000,0.025000},{0.656250,0.118750,0.050000,0.050000},{0.668750,0.118750,0.025000,0.025000},{0.668750,0.118750,0.050000,0.050000},{0.681250,0.118750,0.025000,0.025000},{0.681250,0.118750,0.050000,0.050000},{0.693750,0.118750,0.025000,0.025000},{0.693750,0.118750,0.050000,0.050000},{0.706250,0.118750,0.025000,0.025000},{0.706250,0.118750,0.050000,0.050000},{0.718750,0.118750,0.025000,0.025000},{0.718750,0.118750,0.050000,0.050000},{0.731250,0.118750,0.025000,0.025000},{0.731250,0.118750,0.050000,0.050000},{0.743750,0.118750,0.025000,0.025000},{0.743750,0.118750,0.050000,0.050000},{0.756250,0.118750,0.025000,0.025000},{0.756250,0.118750,0.050000,0.050000},{0.768750,0.118750,0.025000,0.025000},{0.768750,0.118750,0.050000,0.050000},{0.781250,0.118750,0.025000,0.025000},{0.781250,0.118750,0.050000,0.050000},{0.793750,0.118750,0.025000,0.025000},{0.793750,0.118750,0.050000,0.050000},{0.806250,0.118750,0.025000,0.025000},{0.806250,0.118750,0.050000,0.050000},{0.818750,0.118750,0.025000,0.025000},{0.818750,0.118750,0.050000,0.050000},{0.831250,0.118750,0.025000,0.025000},{0.831250,0.118750,0.050000,0.050000},{0.843750,0.118750,0.025000,0.025000},{0.843750,0.118750,0.050000,0.050000},{0.856250,0.118750,0.025000,0.025000},{0.856250,0.118750,0.050000,0.050000},{0.868750,0.118750,0.025000,0.025000},{0.868750,0.118750,0.050000,0.050000},{0.881250,0.118750,0.025000,0.025000},{0.881250,0.118750,0.050000,0.050000},{0.893750,0.118750,0.025000,0.025000},{0.893750,0.118750,0.050000,0.050000},{0.906250,0.118750,0.025000,0.025000},{0.906250,0.118750,0.050000,0.050000},{0.918750,0.118750,0.025000,0.025000},{0.918750,0.118750,0.050000,0.050000},{0.931250,0.118750,0.025000,0.025000},{0.931250,0.118750,0.050000,0.050000},{0.943750,0.118750,0.025000,0.025000},{0.943750,0.118750,0.050000,0.050000},{0.956250,0.118750,0.025000,0.025000},{0.956250,0.118750,0.050000,0.050000},{0.968750,0.118750,0.025000,0.025000},{0.968750,0.118750,0.050000,0.050000},{0.981250,0.118750,0.025000,0.025000},{0.981250,0.118750,0.050000,0.050000},{0.993750,0.118750,0.025000,0.025000},{0.993750,0.118750,0.050000,0.050000},{0.006250,0.131250,0.025000,0.025000},{0.006250,0.131250,0.050000,0.050000},{0.018750,0.131250,0.025000,0.025000},{0.018750,0.131250,0.050000,0.050000},{0.031250,0.131250,0.025000,0.025000},{0.031250,0.131250,0.050000,0.050000},{0.043750,0.131250,0.025000,0.025000},{0.043750,0.131250,0.050000,0.050000},{0.056250,0.131250,0.025000,0.025000},{0.056250,0.131250,0.050000,0.050000},{0.068750,0.131250,0.025000,0.025000},{0.068750,0.131250,0.050000,0.050000},{0.081250,0.131250,0.025000,0.025000},{0.081250,0.131250,0.050000,0.050000},{0.093750,0.131250,0.025000,0.025000},{0.093750,0.131250,0.050000,0.050000},{0.106250,0.131250,0.025000,0.025000},{0.106250,0.131250,0.050000,0.050000},{0.118750,0.131250,0.025000,0.025000},{0.118750,0.131250,0.050000,0.050000},{0.131250,0.131250,0.025000,0.025000},{0.131250,0.131250,0.050000,0.050000},{0.143750,0.131250,0.025000,0.025000},{0.143750,0.131250,0.050000,0.050000},{0.156250,0.131250,0.025000,0.025000},{0.156250,0.131250,0.050000,0.050000},{0.168750,0.131250,0.025000,0.025000},{0.168750,0.131250,0.050000,0.050000},{0.181250,0.131250,0.025000,0.025000},{0.181250,0.131250,0.050000,0.050000},{0.193750,0.131250,0.025000,0.025000},{0.193750,0.131250,0.050000,0.050000},{0.206250,0.131250,0.025000,0.025000},{0.206250,0.131250,0.050000,0.050000},{0.218750,0.131250,0.025000,0.025000},{0.218750,0.131250,0.050000,0.050000},{0.231250,0.131250,0.025000,0.025000},{0.231250,0.131250,0.050000,0.050000},{0.243750,0.131250,0.025000,0.025000},{0.243750,0.131250,0.050000,0.050000},{0.256250,0.131250,0.025000,0.025000},{0.256250,0.131250,0.050000,0.050000},{0.268750,0.131250,0.025000,0.025000},{0.268750,0.131250,0.050000,0.050000},{0.281250,0.131250,0.025000,0.025000},{0.281250,0.131250,0.050000,0.050000},{0.293750,0.131250,0.025000,0.025000},{0.293750,0.131250,0.050000,0.050000},{0.306250,0.131250,0.025000,0.025000},{0.306250,0.131250,0.050000,0.050000},{0.318750,0.131250,0.025000,0.025000},{0.318750,0.131250,0.050000,0.050000},{0.331250,0.131250,0.025000,0.025000},{0.331250,0.131250,0.050000,0.050000},{0.343750,0.131250,0.025000,0.025000},{0.343750,0.131250,0.050000,0.050000},{0.356250,0.131250,0.025000,0.025000},{0.356250,0.131250,0.050000,0.050000},{0.368750,0.131250,0.025000,0.025000},{0.368750,0.131250,0.050000,0.050000},{0.381250,0.131250,0.025000,0.025000},{0.381250,0.131250,0.050000,0.050000},{0.393750,0.131250,0.025000,0.025000},{0.393750,0.131250,0.050000,0.050000},{0.406250,0.131250,0.025000,0.025000},{0.406250,0.131250,0.050000,0.050000},{0.418750,0.131250,0.025000,0.025000},{0.418750,0.131250,0.050000,0.050000},{0.431250,0.131250,0.025000,0.025000},{0.431250,0.131250,0.050000,0.050000},{0.443750,0.131250,0.025000,0.025000},{0.443750,0.131250,0.050000,0.050000},{0.456250,0.131250,0.025000,0.025000},{0.456250,0.131250,0.050000,0.050000},{0.468750,0.131250,0.025000,0.025000},{0.468750,0.131250,0.050000,0.050000},{0.481250,0.131250,0.025000,0.025000},{0.481250,0.131250,0.050000,0.050000},{0.493750,0.131250,0.025000,0.025000},{0.493750,0.131250,0.050000,0.050000},{0.506250,0.131250,0.025000,0.025000},{0.506250,0.131250,0.050000,0.050000},{0.518750,0.131250,0.025000,0.025000},{0.518750,0.131250,0.050000,0.050000},{0.531250,0.131250,0.025000,0.025000},{0.531250,0.131250,0.050000,0.050000},{0.543750,0.131250,0.025000,0.025000},{0.543750,0.131250,0.050000,0.050000},{0.556250,0.131250,0.025000,0.025000},{0.556250,0.131250,0.050000,0.050000},{0.568750,0.131250,0.025000,0.025000},{0.568750,0.131250,0.050000,0.050000},{0.581250,0.131250,0.025000,0.025000},{0.581250,0.131250,0.050000,0.050000},{0.593750,0.131250,0.025000,0.025000},{0.593750,0.131250,0.050000,0.050000},{0.606250,0.131250,0.025000,0.025000},{0.606250,0.131250,0.050000,0.050000},{0.618750,0.131250,0.025000,0.025000},{0.618750,0.131250,0.050000,0.050000},{0.631250,0.131250,0.025000,0.025000},{0.631250,0.131250,0.050000,0.050000},{0.643750,0.131250,0.025000,0.025000},{0.643750,0.131250,0.050000,0.050000},{0.656250,0.131250,0.025000,0.025000},{0.656250,0.131250,0.050000,0.050000},{0.668750,0.131250,0.025000,0.025000},{0.668750,0.131250,0.050000,0.050000},{0.681250,0.131250,0.025000,0.025000},{0.681250,0.131250,0.050000,0.050000},{0.693750,0.131250,0.025000,0.025000},{0.693750,0.131250,0.050000,0.050000},{0.706250,0.131250,0.025000,0.025000},{0.706250,0.131250,0.050000,0.050000},{0.718750,0.131250,0.025000,0.025000},{0.718750,0.131250,0.050000,0.050000},{0.731250,0.131250,0.025000,0.025000},{0.731250,0.131250,0.050000,0.050000},{0.743750,0.131250,0.025000,0.025000},{0.743750,0.131250,0.050000,0.050000},{0.756250,0.131250,0.025000,0.025000},{0.756250,0.131250,0.050000,0.050000},{0.768750,0.131250,0.025000,0.025000},{0.768750,0.131250,0.050000,0.050000},{0.781250,0.131250,0.025000,0.025000},{0.781250,0.131250,0.050000,0.050000},{0.793750,0.131250,0.025000,0.025000},{0.793750,0.131250,0.050000,0.050000},{0.806250,0.131250,0.025000,0.025000},{0.806250,0.131250,0.050000,0.050000},{0.818750,0.131250,0.025000,0.025000},{0.818750,0.131250,0.050000,0.050000},{0.831250,0.131250,0.025000,0.025000},{0.831250,0.131250,0.050000,0.050000},{0.843750,0.131250,0.025000,0.025000},{0.843750,0.131250,0.050000,0.050000},{0.856250,0.131250,0.025000,0.025000},{0.856250,0.131250,0.050000,0.050000},{0.868750,0.131250,0.025000,0.025000},{0.868750,0.131250,0.050000,0.050000},{0.881250,0.131250,0.025000,0.025000},{0.881250,0.131250,0.050000,0.050000},{0.893750,0.131250,0.025000,0.025000},{0.893750,0.131250,0.050000,0.050000},{0.906250,0.131250,0.025000,0.025000},{0.906250,0.131250,0.050000,0.050000},{0.918750,0.131250,0.025000,0.025000},{0.918750,0.131250,0.050000,0.050000},{0.931250,0.131250,0.025000,0.025000},{0.931250,0.131250,0.050000,0.050000},{0.943750,0.131250,0.025000,0.025000},{0.943750,0.131250,0.050000,0.050000},{0.956250,0.131250,0.025000,0.025000},{0.956250,0.131250,0.050000,0.050000},{0.968750,0.131250,0.025000,0.025000},{0.968750,0.131250,0.050000,0.050000},{0.981250,0.131250,0.025000,0.025000},{0.981250,0.131250,0.050000,0.050000},{0.993750,0.131250,0.025000,0.025000},{0.993750,0.131250,0.050000,0.050000},{0.006250,0.143750,0.025000,0.025000},{0.006250,0.143750,0.050000,0.050000},{0.018750,0.143750,0.025000,0.025000},{0.018750,0.143750,0.050000,0.050000},{0.031250,0.143750,0.025000,0.025000},{0.031250,0.143750,0.050000,0.050000},{0.043750,0.143750,0.025000,0.025000},{0.043750,0.143750,0.050000,0.050000},{0.056250,0.143750,0.025000,0.025000},{0.056250,0.143750,0.050000,0.050000},{0.068750,0.143750,0.025000,0.025000},{0.068750,0.143750,0.050000,0.050000},{0.081250,0.143750,0.025000,0.025000},{0.081250,0.143750,0.050000,0.050000},{0.093750,0.143750,0.025000,0.025000},{0.093750,0.143750,0.050000,0.050000},{0.106250,0.143750,0.025000,0.025000},{0.106250,0.143750,0.050000,0.050000},{0.118750,0.143750,0.025000,0.025000},{0.118750,0.143750,0.050000,0.050000},{0.131250,0.143750,0.025000,0.025000},{0.131250,0.143750,0.050000,0.050000},{0.143750,0.143750,0.025000,0.025000},{0.143750,0.143750,0.050000,0.050000},{0.156250,0.143750,0.025000,0.025000},{0.156250,0.143750,0.050000,0.050000},{0.168750,0.143750,0.025000,0.025000},{0.168750,0.143750,0.050000,0.050000},{0.181250,0.143750,0.025000,0.025000},{0.181250,0.143750,0.050000,0.050000},{0.193750,0.143750,0.025000,0.025000},{0.193750,0.143750,0.050000,0.050000},{0.206250,0.143750,0.025000,0.025000},{0.206250,0.143750,0.050000,0.050000},{0.218750,0.143750,0.025000,0.025000},{0.218750,0.143750,0.050000,0.050000},{0.231250,0.143750,0.025000,0.025000},{0.231250,0.143750,0.050000,0.050000},{0.243750,0.143750,0.025000,0.025000},{0.243750,0.143750,0.050000,0.050000},{0.256250,0.143750,0.025000,0.025000},{0.256250,0.143750,0.050000,0.050000},{0.268750,0.143750,0.025000,0.025000},{0.268750,0.143750,0.050000,0.050000},{0.281250,0.143750,0.025000,0.025000},{0.281250,0.143750,0.050000,0.050000},{0.293750,0.143750,0.025000,0.025000},{0.293750,0.143750,0.050000,0.050000},{0.306250,0.143750,0.025000,0.025000},{0.306250,0.143750,0.050000,0.050000},{0.318750,0.143750,0.025000,0.025000},{0.318750,0.143750,0.050000,0.050000},{0.331250,0.143750,0.025000,0.025000},{0.331250,0.143750,0.050000,0.050000},{0.343750,0.143750,0.025000,0.025000},{0.343750,0.143750,0.050000,0.050000},{0.356250,0.143750,0.025000,0.025000},{0.356250,0.143750,0.050000,0.050000},{0.368750,0.143750,0.025000,0.025000},{0.368750,0.143750,0.050000,0.050000},{0.381250,0.143750,0.025000,0.025000},{0.381250,0.143750,0.050000,0.050000},{0.393750,0.143750,0.025000,0.025000},{0.393750,0.143750,0.050000,0.050000},{0.406250,0.143750,0.025000,0.025000},{0.406250,0.143750,0.050000,0.050000},{0.418750,0.143750,0.025000,0.025000},{0.418750,0.143750,0.050000,0.050000},{0.431250,0.143750,0.025000,0.025000},{0.431250,0.143750,0.050000,0.050000},{0.443750,0.143750,0.025000,0.025000},{0.443750,0.143750,0.050000,0.050000},{0.456250,0.143750,0.025000,0.025000},{0.456250,0.143750,0.050000,0.050000},{0.468750,0.143750,0.025000,0.025000},{0.468750,0.143750,0.050000,0.050000},{0.481250,0.143750,0.025000,0.025000},{0.481250,0.143750,0.050000,0.050000},{0.493750,0.143750,0.025000,0.025000},{0.493750,0.143750,0.050000,0.050000},{0.506250,0.143750,0.025000,0.025000},{0.506250,0.143750,0.050000,0.050000},{0.518750,0.143750,0.025000,0.025000},{0.518750,0.143750,0.050000,0.050000},{0.531250,0.143750,0.025000,0.025000},{0.531250,0.143750,0.050000,0.050000},{0.543750,0.143750,0.025000,0.025000},{0.543750,0.143750,0.050000,0.050000},{0.556250,0.143750,0.025000,0.025000},{0.556250,0.143750,0.050000,0.050000},{0.568750,0.143750,0.025000,0.025000},{0.568750,0.143750,0.050000,0.050000},{0.581250,0.143750,0.025000,0.025000},{0.581250,0.143750,0.050000,0.050000},{0.593750,0.143750,0.025000,0.025000},{0.593750,0.143750,0.050000,0.050000},{0.606250,0.143750,0.025000,0.025000},{0.606250,0.143750,0.050000,0.050000},{0.618750,0.143750,0.025000,0.025000},{0.618750,0.143750,0.050000,0.050000},{0.631250,0.143750,0.025000,0.025000},{0.631250,0.143750,0.050000,0.050000},{0.643750,0.143750,0.025000,0.025000},{0.643750,0.143750,0.050000,0.050000},{0.656250,0.143750,0.025000,0.025000},{0.656250,0.143750,0.050000,0.050000},{0.668750,0.143750,0.025000,0.025000},{0.668750,0.143750,0.050000,0.050000},{0.681250,0.143750,0.025000,0.025000},{0.681250,0.143750,0.050000,0.050000},{0.693750,0.143750,0.025000,0.025000},{0.693750,0.143750,0.050000,0.050000},{0.706250,0.143750,0.025000,0.025000},{0.706250,0.143750,0.050000,0.050000},{0.718750,0.143750,0.025000,0.025000},{0.718750,0.143750,0.050000,0.050000},{0.731250,0.143750,0.025000,0.025000},{0.731250,0.143750,0.050000,0.050000},{0.743750,0.143750,0.025000,0.025000},{0.743750,0.143750,0.050000,0.050000},{0.756250,0.143750,0.025000,0.025000},{0.756250,0.143750,0.050000,0.050000},{0.768750,0.143750,0.025000,0.025000},{0.768750,0.143750,0.050000,0.050000},{0.781250,0.143750,0.025000,0.025000},{0.781250,0.143750,0.050000,0.050000},{0.793750,0.143750,0.025000,0.025000},{0.793750,0.143750,0.050000,0.050000},{0.806250,0.143750,0.025000,0.025000},{0.806250,0.143750,0.050000,0.050000},{0.818750,0.143750,0.025000,0.025000},{0.818750,0.143750,0.050000,0.050000},{0.831250,0.143750,0.025000,0.025000},{0.831250,0.143750,0.050000,0.050000},{0.843750,0.143750,0.025000,0.025000},{0.843750,0.143750,0.050000,0.050000},{0.856250,0.143750,0.025000,0.025000},{0.856250,0.143750,0.050000,0.050000},{0.868750,0.143750,0.025000,0.025000},{0.868750,0.143750,0.050000,0.050000},{0.881250,0.143750,0.025000,0.025000},{0.881250,0.143750,0.050000,0.050000},{0.893750,0.143750,0.025000,0.025000},{0.893750,0.143750,0.050000,0.050000},{0.906250,0.143750,0.025000,0.025000},{0.906250,0.143750,0.050000,0.050000},{0.918750,0.143750,0.025000,0.025000},{0.918750,0.143750,0.050000,0.050000},{0.931250,0.143750,0.025000,0.025000},{0.931250,0.143750,0.050000,0.050000},{0.943750,0.143750,0.025000,0.025000},{0.943750,0.143750,0.050000,0.050000},{0.956250,0.143750,0.025000,0.025000},{0.956250,0.143750,0.050000,0.050000},{0.968750,0.143750,0.025000,0.025000},{0.968750,0.143750,0.050000,0.050000},{0.981250,0.143750,0.025000,0.025000},{0.981250,0.143750,0.050000,0.050000},{0.993750,0.143750,0.025000,0.025000},{0.993750,0.143750,0.050000,0.050000},{0.006250,0.156250,0.025000,0.025000},{0.006250,0.156250,0.050000,0.050000},{0.018750,0.156250,0.025000,0.025000},{0.018750,0.156250,0.050000,0.050000},{0.031250,0.156250,0.025000,0.025000},{0.031250,0.156250,0.050000,0.050000},{0.043750,0.156250,0.025000,0.025000},{0.043750,0.156250,0.050000,0.050000},{0.056250,0.156250,0.025000,0.025000},{0.056250,0.156250,0.050000,0.050000},{0.068750,0.156250,0.025000,0.025000},{0.068750,0.156250,0.050000,0.050000},{0.081250,0.156250,0.025000,0.025000},{0.081250,0.156250,0.050000,0.050000},{0.093750,0.156250,0.025000,0.025000},{0.093750,0.156250,0.050000,0.050000},{0.106250,0.156250,0.025000,0.025000},{0.106250,0.156250,0.050000,0.050000},{0.118750,0.156250,0.025000,0.025000},{0.118750,0.156250,0.050000,0.050000},{0.131250,0.156250,0.025000,0.025000},{0.131250,0.156250,0.050000,0.050000},{0.143750,0.156250,0.025000,0.025000},{0.143750,0.156250,0.050000,0.050000},{0.156250,0.156250,0.025000,0.025000},{0.156250,0.156250,0.050000,0.050000},{0.168750,0.156250,0.025000,0.025000},{0.168750,0.156250,0.050000,0.050000},{0.181250,0.156250,0.025000,0.025000},{0.181250,0.156250,0.050000,0.050000},{0.193750,0.156250,0.025000,0.025000},{0.193750,0.156250,0.050000,0.050000},{0.206250,0.156250,0.025000,0.025000},{0.206250,0.156250,0.050000,0.050000},{0.218750,0.156250,0.025000,0.025000},{0.218750,0.156250,0.050000,0.050000},{0.231250,0.156250,0.025000,0.025000},{0.231250,0.156250,0.050000,0.050000},{0.243750,0.156250,0.025000,0.025000},{0.243750,0.156250,0.050000,0.050000},{0.256250,0.156250,0.025000,0.025000},{0.256250,0.156250,0.050000,0.050000},{0.268750,0.156250,0.025000,0.025000},{0.268750,0.156250,0.050000,0.050000},{0.281250,0.156250,0.025000,0.025000},{0.281250,0.156250,0.050000,0.050000},{0.293750,0.156250,0.025000,0.025000},{0.293750,0.156250,0.050000,0.050000},{0.306250,0.156250,0.025000,0.025000},{0.306250,0.156250,0.050000,0.050000},{0.318750,0.156250,0.025000,0.025000},{0.318750,0.156250,0.050000,0.050000},{0.331250,0.156250,0.025000,0.025000},{0.331250,0.156250,0.050000,0.050000},{0.343750,0.156250,0.025000,0.025000},{0.343750,0.156250,0.050000,0.050000},{0.356250,0.156250,0.025000,0.025000},{0.356250,0.156250,0.050000,0.050000},{0.368750,0.156250,0.025000,0.025000},{0.368750,0.156250,0.050000,0.050000},{0.381250,0.156250,0.025000,0.025000},{0.381250,0.156250,0.050000,0.050000},{0.393750,0.156250,0.025000,0.025000},{0.393750,0.156250,0.050000,0.050000},{0.406250,0.156250,0.025000,0.025000},{0.406250,0.156250,0.050000,0.050000},{0.418750,0.156250,0.025000,0.025000},{0.418750,0.156250,0.050000,0.050000},{0.431250,0.156250,0.025000,0.025000},{0.431250,0.156250,0.050000,0.050000},{0.443750,0.156250,0.025000,0.025000},{0.443750,0.156250,0.050000,0.050000},{0.456250,0.156250,0.025000,0.025000},{0.456250,0.156250,0.050000,0.050000},{0.468750,0.156250,0.025000,0.025000},{0.468750,0.156250,0.050000,0.050000},{0.481250,0.156250,0.025000,0.025000},{0.481250,0.156250,0.050000,0.050000},{0.493750,0.156250,0.025000,0.025000},{0.493750,0.156250,0.050000,0.050000},{0.506250,0.156250,0.025000,0.025000},{0.506250,0.156250,0.050000,0.050000},{0.518750,0.156250,0.025000,0.025000},{0.518750,0.156250,0.050000,0.050000},{0.531250,0.156250,0.025000,0.025000},{0.531250,0.156250,0.050000,0.050000},{0.543750,0.156250,0.025000,0.025000},{0.543750,0.156250,0.050000,0.050000},{0.556250,0.156250,0.025000,0.025000},{0.556250,0.156250,0.050000,0.050000},{0.568750,0.156250,0.025000,0.025000},{0.568750,0.156250,0.050000,0.050000},{0.581250,0.156250,0.025000,0.025000},{0.581250,0.156250,0.050000,0.050000},{0.593750,0.156250,0.025000,0.025000},{0.593750,0.156250,0.050000,0.050000},{0.606250,0.156250,0.025000,0.025000},{0.606250,0.156250,0.050000,0.050000},{0.618750,0.156250,0.025000,0.025000},{0.618750,0.156250,0.050000,0.050000},{0.631250,0.156250,0.025000,0.025000},{0.631250,0.156250,0.050000,0.050000},{0.643750,0.156250,0.025000,0.025000},{0.643750,0.156250,0.050000,0.050000},{0.656250,0.156250,0.025000,0.025000},{0.656250,0.156250,0.050000,0.050000},{0.668750,0.156250,0.025000,0.025000},{0.668750,0.156250,0.050000,0.050000},{0.681250,0.156250,0.025000,0.025000},{0.681250,0.156250,0.050000,0.050000},{0.693750,0.156250,0.025000,0.025000},{0.693750,0.156250,0.050000,0.050000},{0.706250,0.156250,0.025000,0.025000},{0.706250,0.156250,0.050000,0.050000},{0.718750,0.156250,0.025000,0.025000},{0.718750,0.156250,0.050000,0.050000},{0.731250,0.156250,0.025000,0.025000},{0.731250,0.156250,0.050000,0.050000},{0.743750,0.156250,0.025000,0.025000},{0.743750,0.156250,0.050000,0.050000},{0.756250,0.156250,0.025000,0.025000},{0.756250,0.156250,0.050000,0.050000},{0.768750,0.156250,0.025000,0.025000},{0.768750,0.156250,0.050000,0.050000},{0.781250,0.156250,0.025000,0.025000},{0.781250,0.156250,0.050000,0.050000},{0.793750,0.156250,0.025000,0.025000},{0.793750,0.156250,0.050000,0.050000},{0.806250,0.156250,0.025000,0.025000},{0.806250,0.156250,0.050000,0.050000},{0.818750,0.156250,0.025000,0.025000},{0.818750,0.156250,0.050000,0.050000},{0.831250,0.156250,0.025000,0.025000},{0.831250,0.156250,0.050000,0.050000},{0.843750,0.156250,0.025000,0.025000},{0.843750,0.156250,0.050000,0.050000},{0.856250,0.156250,0.025000,0.025000},{0.856250,0.156250,0.050000,0.050000},{0.868750,0.156250,0.025000,0.025000},{0.868750,0.156250,0.050000,0.050000},{0.881250,0.156250,0.025000,0.025000},{0.881250,0.156250,0.050000,0.050000},{0.893750,0.156250,0.025000,0.025000},{0.893750,0.156250,0.050000,0.050000},{0.906250,0.156250,0.025000,0.025000},{0.906250,0.156250,0.050000,0.050000},{0.918750,0.156250,0.025000,0.025000},{0.918750,0.156250,0.050000,0.050000},{0.931250,0.156250,0.025000,0.025000},{0.931250,0.156250,0.050000,0.050000},{0.943750,0.156250,0.025000,0.025000},{0.943750,0.156250,0.050000,0.050000},{0.956250,0.156250,0.025000,0.025000},{0.956250,0.156250,0.050000,0.050000},{0.968750,0.156250,0.025000,0.025000},{0.968750,0.156250,0.050000,0.050000},{0.981250,0.156250,0.025000,0.025000},{0.981250,0.156250,0.050000,0.050000},{0.993750,0.156250,0.025000,0.025000},{0.993750,0.156250,0.050000,0.050000},{0.006250,0.168750,0.025000,0.025000},{0.006250,0.168750,0.050000,0.050000},{0.018750,0.168750,0.025000,0.025000},{0.018750,0.168750,0.050000,0.050000},{0.031250,0.168750,0.025000,0.025000},{0.031250,0.168750,0.050000,0.050000},{0.043750,0.168750,0.025000,0.025000},{0.043750,0.168750,0.050000,0.050000},{0.056250,0.168750,0.025000,0.025000},{0.056250,0.168750,0.050000,0.050000},{0.068750,0.168750,0.025000,0.025000},{0.068750,0.168750,0.050000,0.050000},{0.081250,0.168750,0.025000,0.025000},{0.081250,0.168750,0.050000,0.050000},{0.093750,0.168750,0.025000,0.025000},{0.093750,0.168750,0.050000,0.050000},{0.106250,0.168750,0.025000,0.025000},{0.106250,0.168750,0.050000,0.050000},{0.118750,0.168750,0.025000,0.025000},{0.118750,0.168750,0.050000,0.050000},{0.131250,0.168750,0.025000,0.025000},{0.131250,0.168750,0.050000,0.050000},{0.143750,0.168750,0.025000,0.025000},{0.143750,0.168750,0.050000,0.050000},{0.156250,0.168750,0.025000,0.025000},{0.156250,0.168750,0.050000,0.050000},{0.168750,0.168750,0.025000,0.025000},{0.168750,0.168750,0.050000,0.050000},{0.181250,0.168750,0.025000,0.025000},{0.181250,0.168750,0.050000,0.050000},{0.193750,0.168750,0.025000,0.025000},{0.193750,0.168750,0.050000,0.050000},{0.206250,0.168750,0.025000,0.025000},{0.206250,0.168750,0.050000,0.050000},{0.218750,0.168750,0.025000,0.025000},{0.218750,0.168750,0.050000,0.050000},{0.231250,0.168750,0.025000,0.025000},{0.231250,0.168750,0.050000,0.050000},{0.243750,0.168750,0.025000,0.025000},{0.243750,0.168750,0.050000,0.050000},{0.256250,0.168750,0.025000,0.025000},{0.256250,0.168750,0.050000,0.050000},{0.268750,0.168750,0.025000,0.025000},{0.268750,0.168750,0.050000,0.050000},{0.281250,0.168750,0.025000,0.025000},{0.281250,0.168750,0.050000,0.050000},{0.293750,0.168750,0.025000,0.025000},{0.293750,0.168750,0.050000,0.050000},{0.306250,0.168750,0.025000,0.025000},{0.306250,0.168750,0.050000,0.050000},{0.318750,0.168750,0.025000,0.025000},{0.318750,0.168750,0.050000,0.050000},{0.331250,0.168750,0.025000,0.025000},{0.331250,0.168750,0.050000,0.050000},{0.343750,0.168750,0.025000,0.025000},{0.343750,0.168750,0.050000,0.050000},{0.356250,0.168750,0.025000,0.025000},{0.356250,0.168750,0.050000,0.050000},{0.368750,0.168750,0.025000,0.025000},{0.368750,0.168750,0.050000,0.050000},{0.381250,0.168750,0.025000,0.025000},{0.381250,0.168750,0.050000,0.050000},{0.393750,0.168750,0.025000,0.025000},{0.393750,0.168750,0.050000,0.050000},{0.406250,0.168750,0.025000,0.025000},{0.406250,0.168750,0.050000,0.050000},{0.418750,0.168750,0.025000,0.025000},{0.418750,0.168750,0.050000,0.050000},{0.431250,0.168750,0.025000,0.025000},{0.431250,0.168750,0.050000,0.050000},{0.443750,0.168750,0.025000,0.025000},{0.443750,0.168750,0.050000,0.050000},{0.456250,0.168750,0.025000,0.025000},{0.456250,0.168750,0.050000,0.050000},{0.468750,0.168750,0.025000,0.025000},{0.468750,0.168750,0.050000,0.050000},{0.481250,0.168750,0.025000,0.025000},{0.481250,0.168750,0.050000,0.050000},{0.493750,0.168750,0.025000,0.025000},{0.493750,0.168750,0.050000,0.050000},{0.506250,0.168750,0.025000,0.025000},{0.506250,0.168750,0.050000,0.050000},{0.518750,0.168750,0.025000,0.025000},{0.518750,0.168750,0.050000,0.050000},{0.531250,0.168750,0.025000,0.025000},{0.531250,0.168750,0.050000,0.050000},{0.543750,0.168750,0.025000,0.025000},{0.543750,0.168750,0.050000,0.050000},{0.556250,0.168750,0.025000,0.025000},{0.556250,0.168750,0.050000,0.050000},{0.568750,0.168750,0.025000,0.025000},{0.568750,0.168750,0.050000,0.050000},{0.581250,0.168750,0.025000,0.025000},{0.581250,0.168750,0.050000,0.050000},{0.593750,0.168750,0.025000,0.025000},{0.593750,0.168750,0.050000,0.050000},{0.606250,0.168750,0.025000,0.025000},{0.606250,0.168750,0.050000,0.050000},{0.618750,0.168750,0.025000,0.025000},{0.618750,0.168750,0.050000,0.050000},{0.631250,0.168750,0.025000,0.025000},{0.631250,0.168750,0.050000,0.050000},{0.643750,0.168750,0.025000,0.025000},{0.643750,0.168750,0.050000,0.050000},{0.656250,0.168750,0.025000,0.025000},{0.656250,0.168750,0.050000,0.050000},{0.668750,0.168750,0.025000,0.025000},{0.668750,0.168750,0.050000,0.050000},{0.681250,0.168750,0.025000,0.025000},{0.681250,0.168750,0.050000,0.050000},{0.693750,0.168750,0.025000,0.025000},{0.693750,0.168750,0.050000,0.050000},{0.706250,0.168750,0.025000,0.025000},{0.706250,0.168750,0.050000,0.050000},{0.718750,0.168750,0.025000,0.025000},{0.718750,0.168750,0.050000,0.050000},{0.731250,0.168750,0.025000,0.025000},{0.731250,0.168750,0.050000,0.050000},{0.743750,0.168750,0.025000,0.025000},{0.743750,0.168750,0.050000,0.050000},{0.756250,0.168750,0.025000,0.025000},{0.756250,0.168750,0.050000,0.050000},{0.768750,0.168750,0.025000,0.025000},{0.768750,0.168750,0.050000,0.050000},{0.781250,0.168750,0.025000,0.025000},{0.781250,0.168750,0.050000,0.050000},{0.793750,0.168750,0.025000,0.025000},{0.793750,0.168750,0.050000,0.050000},{0.806250,0.168750,0.025000,0.025000},{0.806250,0.168750,0.050000,0.050000},{0.818750,0.168750,0.025000,0.025000},{0.818750,0.168750,0.050000,0.050000},{0.831250,0.168750,0.025000,0.025000},{0.831250,0.168750,0.050000,0.050000},{0.843750,0.168750,0.025000,0.025000},{0.843750,0.168750,0.050000,0.050000},{0.856250,0.168750,0.025000,0.025000},{0.856250,0.168750,0.050000,0.050000},{0.868750,0.168750,0.025000,0.025000},{0.868750,0.168750,0.050000,0.050000},{0.881250,0.168750,0.025000,0.025000},{0.881250,0.168750,0.050000,0.050000},{0.893750,0.168750,0.025000,0.025000},{0.893750,0.168750,0.050000,0.050000},{0.906250,0.168750,0.025000,0.025000},{0.906250,0.168750,0.050000,0.050000},{0.918750,0.168750,0.025000,0.025000},{0.918750,0.168750,0.050000,0.050000},{0.931250,0.168750,0.025000,0.025000},{0.931250,0.168750,0.050000,0.050000},{0.943750,0.168750,0.025000,0.025000},{0.943750,0.168750,0.050000,0.050000},{0.956250,0.168750,0.025000,0.025000},{0.956250,0.168750,0.050000,0.050000},{0.968750,0.168750,0.025000,0.025000},{0.968750,0.168750,0.050000,0.050000},{0.981250,0.168750,0.025000,0.025000},{0.981250,0.168750,0.050000,0.050000},{0.993750,0.168750,0.025000,0.025000},{0.993750,0.168750,0.050000,0.050000},{0.006250,0.181250,0.025000,0.025000},{0.006250,0.181250,0.050000,0.050000},{0.018750,0.181250,0.025000,0.025000},{0.018750,0.181250,0.050000,0.050000},{0.031250,0.181250,0.025000,0.025000},{0.031250,0.181250,0.050000,0.050000},{0.043750,0.181250,0.025000,0.025000},{0.043750,0.181250,0.050000,0.050000},{0.056250,0.181250,0.025000,0.025000},{0.056250,0.181250,0.050000,0.050000},{0.068750,0.181250,0.025000,0.025000},{0.068750,0.181250,0.050000,0.050000},{0.081250,0.181250,0.025000,0.025000},{0.081250,0.181250,0.050000,0.050000},{0.093750,0.181250,0.025000,0.025000},{0.093750,0.181250,0.050000,0.050000},{0.106250,0.181250,0.025000,0.025000},{0.106250,0.181250,0.050000,0.050000},{0.118750,0.181250,0.025000,0.025000},{0.118750,0.181250,0.050000,0.050000},{0.131250,0.181250,0.025000,0.025000},{0.131250,0.181250,0.050000,0.050000},{0.143750,0.181250,0.025000,0.025000},{0.143750,0.181250,0.050000,0.050000},{0.156250,0.181250,0.025000,0.025000},{0.156250,0.181250,0.050000,0.050000},{0.168750,0.181250,0.025000,0.025000},{0.168750,0.181250,0.050000,0.050000},{0.181250,0.181250,0.025000,0.025000},{0.181250,0.181250,0.050000,0.050000},{0.193750,0.181250,0.025000,0.025000},{0.193750,0.181250,0.050000,0.050000},{0.206250,0.181250,0.025000,0.025000},{0.206250,0.181250,0.050000,0.050000},{0.218750,0.181250,0.025000,0.025000},{0.218750,0.181250,0.050000,0.050000},{0.231250,0.181250,0.025000,0.025000},{0.231250,0.181250,0.050000,0.050000},{0.243750,0.181250,0.025000,0.025000},{0.243750,0.181250,0.050000,0.050000},{0.256250,0.181250,0.025000,0.025000},{0.256250,0.181250,0.050000,0.050000},{0.268750,0.181250,0.025000,0.025000},{0.268750,0.181250,0.050000,0.050000},{0.281250,0.181250,0.025000,0.025000},{0.281250,0.181250,0.050000,0.050000},{0.293750,0.181250,0.025000,0.025000},{0.293750,0.181250,0.050000,0.050000},{0.306250,0.181250,0.025000,0.025000},{0.306250,0.181250,0.050000,0.050000},{0.318750,0.181250,0.025000,0.025000},{0.318750,0.181250,0.050000,0.050000},{0.331250,0.181250,0.025000,0.025000},{0.331250,0.181250,0.050000,0.050000},{0.343750,0.181250,0.025000,0.025000},{0.343750,0.181250,0.050000,0.050000},{0.356250,0.181250,0.025000,0.025000},{0.356250,0.181250,0.050000,0.050000},{0.368750,0.181250,0.025000,0.025000},{0.368750,0.181250,0.050000,0.050000},{0.381250,0.181250,0.025000,0.025000},{0.381250,0.181250,0.050000,0.050000},{0.393750,0.181250,0.025000,0.025000},{0.393750,0.181250,0.050000,0.050000},{0.406250,0.181250,0.025000,0.025000},{0.406250,0.181250,0.050000,0.050000},{0.418750,0.181250,0.025000,0.025000},{0.418750,0.181250,0.050000,0.050000},{0.431250,0.181250,0.025000,0.025000},{0.431250,0.181250,0.050000,0.050000},{0.443750,0.181250,0.025000,0.025000},{0.443750,0.181250,0.050000,0.050000},{0.456250,0.181250,0.025000,0.025000},{0.456250,0.181250,0.050000,0.050000},{0.468750,0.181250,0.025000,0.025000},{0.468750,0.181250,0.050000,0.050000},{0.481250,0.181250,0.025000,0.025000},{0.481250,0.181250,0.050000,0.050000},{0.493750,0.181250,0.025000,0.025000},{0.493750,0.181250,0.050000,0.050000},{0.506250,0.181250,0.025000,0.025000},{0.506250,0.181250,0.050000,0.050000},{0.518750,0.181250,0.025000,0.025000},{0.518750,0.181250,0.050000,0.050000},{0.531250,0.181250,0.025000,0.025000},{0.531250,0.181250,0.050000,0.050000},{0.543750,0.181250,0.025000,0.025000},{0.543750,0.181250,0.050000,0.050000},{0.556250,0.181250,0.025000,0.025000},{0.556250,0.181250,0.050000,0.050000},{0.568750,0.181250,0.025000,0.025000},{0.568750,0.181250,0.050000,0.050000},{0.581250,0.181250,0.025000,0.025000},{0.581250,0.181250,0.050000,0.050000},{0.593750,0.181250,0.025000,0.025000},{0.593750,0.181250,0.050000,0.050000},{0.606250,0.181250,0.025000,0.025000},{0.606250,0.181250,0.050000,0.050000},{0.618750,0.181250,0.025000,0.025000},{0.618750,0.181250,0.050000,0.050000},{0.631250,0.181250,0.025000,0.025000},{0.631250,0.181250,0.050000,0.050000},{0.643750,0.181250,0.025000,0.025000},{0.643750,0.181250,0.050000,0.050000},{0.656250,0.181250,0.025000,0.025000},{0.656250,0.181250,0.050000,0.050000},{0.668750,0.181250,0.025000,0.025000},{0.668750,0.181250,0.050000,0.050000},{0.681250,0.181250,0.025000,0.025000},{0.681250,0.181250,0.050000,0.050000},{0.693750,0.181250,0.025000,0.025000},{0.693750,0.181250,0.050000,0.050000},{0.706250,0.181250,0.025000,0.025000},{0.706250,0.181250,0.050000,0.050000},{0.718750,0.181250,0.025000,0.025000},{0.718750,0.181250,0.050000,0.050000},{0.731250,0.181250,0.025000,0.025000},{0.731250,0.181250,0.050000,0.050000},{0.743750,0.181250,0.025000,0.025000},{0.743750,0.181250,0.050000,0.050000},{0.756250,0.181250,0.025000,0.025000},{0.756250,0.181250,0.050000,0.050000},{0.768750,0.181250,0.025000,0.025000},{0.768750,0.181250,0.050000,0.050000},{0.781250,0.181250,0.025000,0.025000},{0.781250,0.181250,0.050000,0.050000},{0.793750,0.181250,0.025000,0.025000},{0.793750,0.181250,0.050000,0.050000},{0.806250,0.181250,0.025000,0.025000},{0.806250,0.181250,0.050000,0.050000},{0.818750,0.181250,0.025000,0.025000},{0.818750,0.181250,0.050000,0.050000},{0.831250,0.181250,0.025000,0.025000},{0.831250,0.181250,0.050000,0.050000},{0.843750,0.181250,0.025000,0.025000},{0.843750,0.181250,0.050000,0.050000},{0.856250,0.181250,0.025000,0.025000},{0.856250,0.181250,0.050000,0.050000},{0.868750,0.181250,0.025000,0.025000},{0.868750,0.181250,0.050000,0.050000},{0.881250,0.181250,0.025000,0.025000},{0.881250,0.181250,0.050000,0.050000},{0.893750,0.181250,0.025000,0.025000},{0.893750,0.181250,0.050000,0.050000},{0.906250,0.181250,0.025000,0.025000},{0.906250,0.181250,0.050000,0.050000},{0.918750,0.181250,0.025000,0.025000},{0.918750,0.181250,0.050000,0.050000},{0.931250,0.181250,0.025000,0.025000},{0.931250,0.181250,0.050000,0.050000},{0.943750,0.181250,0.025000,0.025000},{0.943750,0.181250,0.050000,0.050000},{0.956250,0.181250,0.025000,0.025000},{0.956250,0.181250,0.050000,0.050000},{0.968750,0.181250,0.025000,0.025000},{0.968750,0.181250,0.050000,0.050000},{0.981250,0.181250,0.025000,0.025000},{0.981250,0.181250,0.050000,0.050000},{0.993750,0.181250,0.025000,0.025000},{0.993750,0.181250,0.050000,0.050000},{0.006250,0.193750,0.025000,0.025000},{0.006250,0.193750,0.050000,0.050000},{0.018750,0.193750,0.025000,0.025000},{0.018750,0.193750,0.050000,0.050000},{0.031250,0.193750,0.025000,0.025000},{0.031250,0.193750,0.050000,0.050000},{0.043750,0.193750,0.025000,0.025000},{0.043750,0.193750,0.050000,0.050000},{0.056250,0.193750,0.025000,0.025000},{0.056250,0.193750,0.050000,0.050000},{0.068750,0.193750,0.025000,0.025000},{0.068750,0.193750,0.050000,0.050000},{0.081250,0.193750,0.025000,0.025000},{0.081250,0.193750,0.050000,0.050000},{0.093750,0.193750,0.025000,0.025000},{0.093750,0.193750,0.050000,0.050000},{0.106250,0.193750,0.025000,0.025000},{0.106250,0.193750,0.050000,0.050000},{0.118750,0.193750,0.025000,0.025000},{0.118750,0.193750,0.050000,0.050000},{0.131250,0.193750,0.025000,0.025000},{0.131250,0.193750,0.050000,0.050000},{0.143750,0.193750,0.025000,0.025000},{0.143750,0.193750,0.050000,0.050000},{0.156250,0.193750,0.025000,0.025000},{0.156250,0.193750,0.050000,0.050000},{0.168750,0.193750,0.025000,0.025000},{0.168750,0.193750,0.050000,0.050000},{0.181250,0.193750,0.025000,0.025000},{0.181250,0.193750,0.050000,0.050000},{0.193750,0.193750,0.025000,0.025000},{0.193750,0.193750,0.050000,0.050000},{0.206250,0.193750,0.025000,0.025000},{0.206250,0.193750,0.050000,0.050000},{0.218750,0.193750,0.025000,0.025000},{0.218750,0.193750,0.050000,0.050000},{0.231250,0.193750,0.025000,0.025000},{0.231250,0.193750,0.050000,0.050000},{0.243750,0.193750,0.025000,0.025000},{0.243750,0.193750,0.050000,0.050000},{0.256250,0.193750,0.025000,0.025000},{0.256250,0.193750,0.050000,0.050000},{0.268750,0.193750,0.025000,0.025000},{0.268750,0.193750,0.050000,0.050000},{0.281250,0.193750,0.025000,0.025000},{0.281250,0.193750,0.050000,0.050000},{0.293750,0.193750,0.025000,0.025000},{0.293750,0.193750,0.050000,0.050000},{0.306250,0.193750,0.025000,0.025000},{0.306250,0.193750,0.050000,0.050000},{0.318750,0.193750,0.025000,0.025000},{0.318750,0.193750,0.050000,0.050000},{0.331250,0.193750,0.025000,0.025000},{0.331250,0.193750,0.050000,0.050000},{0.343750,0.193750,0.025000,0.025000},{0.343750,0.193750,0.050000,0.050000},{0.356250,0.193750,0.025000,0.025000},{0.356250,0.193750,0.050000,0.050000},{0.368750,0.193750,0.025000,0.025000},{0.368750,0.193750,0.050000,0.050000},{0.381250,0.193750,0.025000,0.025000},{0.381250,0.193750,0.050000,0.050000},{0.393750,0.193750,0.025000,0.025000},{0.393750,0.193750,0.050000,0.050000},{0.406250,0.193750,0.025000,0.025000},{0.406250,0.193750,0.050000,0.050000},{0.418750,0.193750,0.025000,0.025000},{0.418750,0.193750,0.050000,0.050000},{0.431250,0.193750,0.025000,0.025000},{0.431250,0.193750,0.050000,0.050000},{0.443750,0.193750,0.025000,0.025000},{0.443750,0.193750,0.050000,0.050000},{0.456250,0.193750,0.025000,0.025000},{0.456250,0.193750,0.050000,0.050000},{0.468750,0.193750,0.025000,0.025000},{0.468750,0.193750,0.050000,0.050000},{0.481250,0.193750,0.025000,0.025000},{0.481250,0.193750,0.050000,0.050000},{0.493750,0.193750,0.025000,0.025000},{0.493750,0.193750,0.050000,0.050000},{0.506250,0.193750,0.025000,0.025000},{0.506250,0.193750,0.050000,0.050000},{0.518750,0.193750,0.025000,0.025000},{0.518750,0.193750,0.050000,0.050000},{0.531250,0.193750,0.025000,0.025000},{0.531250,0.193750,0.050000,0.050000},{0.543750,0.193750,0.025000,0.025000},{0.543750,0.193750,0.050000,0.050000},{0.556250,0.193750,0.025000,0.025000},{0.556250,0.193750,0.050000,0.050000},{0.568750,0.193750,0.025000,0.025000},{0.568750,0.193750,0.050000,0.050000},{0.581250,0.193750,0.025000,0.025000},{0.581250,0.193750,0.050000,0.050000},{0.593750,0.193750,0.025000,0.025000},{0.593750,0.193750,0.050000,0.050000},{0.606250,0.193750,0.025000,0.025000},{0.606250,0.193750,0.050000,0.050000},{0.618750,0.193750,0.025000,0.025000},{0.618750,0.193750,0.050000,0.050000},{0.631250,0.193750,0.025000,0.025000},{0.631250,0.193750,0.050000,0.050000},{0.643750,0.193750,0.025000,0.025000},{0.643750,0.193750,0.050000,0.050000},{0.656250,0.193750,0.025000,0.025000},{0.656250,0.193750,0.050000,0.050000},{0.668750,0.193750,0.025000,0.025000},{0.668750,0.193750,0.050000,0.050000},{0.681250,0.193750,0.025000,0.025000},{0.681250,0.193750,0.050000,0.050000},{0.693750,0.193750,0.025000,0.025000},{0.693750,0.193750,0.050000,0.050000},{0.706250,0.193750,0.025000,0.025000},{0.706250,0.193750,0.050000,0.050000},{0.718750,0.193750,0.025000,0.025000},{0.718750,0.193750,0.050000,0.050000},{0.731250,0.193750,0.025000,0.025000},{0.731250,0.193750,0.050000,0.050000},{0.743750,0.193750,0.025000,0.025000},{0.743750,0.193750,0.050000,0.050000},{0.756250,0.193750,0.025000,0.025000},{0.756250,0.193750,0.050000,0.050000},{0.768750,0.193750,0.025000,0.025000},{0.768750,0.193750,0.050000,0.050000},{0.781250,0.193750,0.025000,0.025000},{0.781250,0.193750,0.050000,0.050000},{0.793750,0.193750,0.025000,0.025000},{0.793750,0.193750,0.050000,0.050000},{0.806250,0.193750,0.025000,0.025000},{0.806250,0.193750,0.050000,0.050000},{0.818750,0.193750,0.025000,0.025000},{0.818750,0.193750,0.050000,0.050000},{0.831250,0.193750,0.025000,0.025000},{0.831250,0.193750,0.050000,0.050000},{0.843750,0.193750,0.025000,0.025000},{0.843750,0.193750,0.050000,0.050000},{0.856250,0.193750,0.025000,0.025000},{0.856250,0.193750,0.050000,0.050000},{0.868750,0.193750,0.025000,0.025000},{0.868750,0.193750,0.050000,0.050000},{0.881250,0.193750,0.025000,0.025000},{0.881250,0.193750,0.050000,0.050000},{0.893750,0.193750,0.025000,0.025000},{0.893750,0.193750,0.050000,0.050000},{0.906250,0.193750,0.025000,0.025000},{0.906250,0.193750,0.050000,0.050000},{0.918750,0.193750,0.025000,0.025000},{0.918750,0.193750,0.050000,0.050000},{0.931250,0.193750,0.025000,0.025000},{0.931250,0.193750,0.050000,0.050000},{0.943750,0.193750,0.025000,0.025000},{0.943750,0.193750,0.050000,0.050000},{0.956250,0.193750,0.025000,0.025000},{0.956250,0.193750,0.050000,0.050000},{0.968750,0.193750,0.025000,0.025000},{0.968750,0.193750,0.050000,0.050000},{0.981250,0.193750,0.025000,0.025000},{0.981250,0.193750,0.050000,0.050000},{0.993750,0.193750,0.025000,0.025000},{0.993750,0.193750,0.050000,0.050000},{0.006250,0.206250,0.025000,0.025000},{0.006250,0.206250,0.050000,0.050000},{0.018750,0.206250,0.025000,0.025000},{0.018750,0.206250,0.050000,0.050000},{0.031250,0.206250,0.025000,0.025000},{0.031250,0.206250,0.050000,0.050000},{0.043750,0.206250,0.025000,0.025000},{0.043750,0.206250,0.050000,0.050000},{0.056250,0.206250,0.025000,0.025000},{0.056250,0.206250,0.050000,0.050000},{0.068750,0.206250,0.025000,0.025000},{0.068750,0.206250,0.050000,0.050000},{0.081250,0.206250,0.025000,0.025000},{0.081250,0.206250,0.050000,0.050000},{0.093750,0.206250,0.025000,0.025000},{0.093750,0.206250,0.050000,0.050000},{0.106250,0.206250,0.025000,0.025000},{0.106250,0.206250,0.050000,0.050000},{0.118750,0.206250,0.025000,0.025000},{0.118750,0.206250,0.050000,0.050000},{0.131250,0.206250,0.025000,0.025000},{0.131250,0.206250,0.050000,0.050000},{0.143750,0.206250,0.025000,0.025000},{0.143750,0.206250,0.050000,0.050000},{0.156250,0.206250,0.025000,0.025000},{0.156250,0.206250,0.050000,0.050000},{0.168750,0.206250,0.025000,0.025000},{0.168750,0.206250,0.050000,0.050000},{0.181250,0.206250,0.025000,0.025000},{0.181250,0.206250,0.050000,0.050000},{0.193750,0.206250,0.025000,0.025000},{0.193750,0.206250,0.050000,0.050000},{0.206250,0.206250,0.025000,0.025000},{0.206250,0.206250,0.050000,0.050000},{0.218750,0.206250,0.025000,0.025000},{0.218750,0.206250,0.050000,0.050000},{0.231250,0.206250,0.025000,0.025000},{0.231250,0.206250,0.050000,0.050000},{0.243750,0.206250,0.025000,0.025000},{0.243750,0.206250,0.050000,0.050000},{0.256250,0.206250,0.025000,0.025000},{0.256250,0.206250,0.050000,0.050000},{0.268750,0.206250,0.025000,0.025000},{0.268750,0.206250,0.050000,0.050000},{0.281250,0.206250,0.025000,0.025000},{0.281250,0.206250,0.050000,0.050000},{0.293750,0.206250,0.025000,0.025000},{0.293750,0.206250,0.050000,0.050000},{0.306250,0.206250,0.025000,0.025000},{0.306250,0.206250,0.050000,0.050000},{0.318750,0.206250,0.025000,0.025000},{0.318750,0.206250,0.050000,0.050000},{0.331250,0.206250,0.025000,0.025000},{0.331250,0.206250,0.050000,0.050000},{0.343750,0.206250,0.025000,0.025000},{0.343750,0.206250,0.050000,0.050000},{0.356250,0.206250,0.025000,0.025000},{0.356250,0.206250,0.050000,0.050000},{0.368750,0.206250,0.025000,0.025000},{0.368750,0.206250,0.050000,0.050000},{0.381250,0.206250,0.025000,0.025000},{0.381250,0.206250,0.050000,0.050000},{0.393750,0.206250,0.025000,0.025000},{0.393750,0.206250,0.050000,0.050000},{0.406250,0.206250,0.025000,0.025000},{0.406250,0.206250,0.050000,0.050000},{0.418750,0.206250,0.025000,0.025000},{0.418750,0.206250,0.050000,0.050000},{0.431250,0.206250,0.025000,0.025000},{0.431250,0.206250,0.050000,0.050000},{0.443750,0.206250,0.025000,0.025000},{0.443750,0.206250,0.050000,0.050000},{0.456250,0.206250,0.025000,0.025000},{0.456250,0.206250,0.050000,0.050000},{0.468750,0.206250,0.025000,0.025000},{0.468750,0.206250,0.050000,0.050000},{0.481250,0.206250,0.025000,0.025000},{0.481250,0.206250,0.050000,0.050000},{0.493750,0.206250,0.025000,0.025000},{0.493750,0.206250,0.050000,0.050000},{0.506250,0.206250,0.025000,0.025000},{0.506250,0.206250,0.050000,0.050000},{0.518750,0.206250,0.025000,0.025000},{0.518750,0.206250,0.050000,0.050000},{0.531250,0.206250,0.025000,0.025000},{0.531250,0.206250,0.050000,0.050000},{0.543750,0.206250,0.025000,0.025000},{0.543750,0.206250,0.050000,0.050000},{0.556250,0.206250,0.025000,0.025000},{0.556250,0.206250,0.050000,0.050000},{0.568750,0.206250,0.025000,0.025000},{0.568750,0.206250,0.050000,0.050000},{0.581250,0.206250,0.025000,0.025000},{0.581250,0.206250,0.050000,0.050000},{0.593750,0.206250,0.025000,0.025000},{0.593750,0.206250,0.050000,0.050000},{0.606250,0.206250,0.025000,0.025000},{0.606250,0.206250,0.050000,0.050000},{0.618750,0.206250,0.025000,0.025000},{0.618750,0.206250,0.050000,0.050000},{0.631250,0.206250,0.025000,0.025000},{0.631250,0.206250,0.050000,0.050000},{0.643750,0.206250,0.025000,0.025000},{0.643750,0.206250,0.050000,0.050000},{0.656250,0.206250,0.025000,0.025000},{0.656250,0.206250,0.050000,0.050000},{0.668750,0.206250,0.025000,0.025000},{0.668750,0.206250,0.050000,0.050000},{0.681250,0.206250,0.025000,0.025000},{0.681250,0.206250,0.050000,0.050000},{0.693750,0.206250,0.025000,0.025000},{0.693750,0.206250,0.050000,0.050000},{0.706250,0.206250,0.025000,0.025000},{0.706250,0.206250,0.050000,0.050000},{0.718750,0.206250,0.025000,0.025000},{0.718750,0.206250,0.050000,0.050000},{0.731250,0.206250,0.025000,0.025000},{0.731250,0.206250,0.050000,0.050000},{0.743750,0.206250,0.025000,0.025000},{0.743750,0.206250,0.050000,0.050000},{0.756250,0.206250,0.025000,0.025000},{0.756250,0.206250,0.050000,0.050000},{0.768750,0.206250,0.025000,0.025000},{0.768750,0.206250,0.050000,0.050000},{0.781250,0.206250,0.025000,0.025000},{0.781250,0.206250,0.050000,0.050000},{0.793750,0.206250,0.025000,0.025000},{0.793750,0.206250,0.050000,0.050000},{0.806250,0.206250,0.025000,0.025000},{0.806250,0.206250,0.050000,0.050000},{0.818750,0.206250,0.025000,0.025000},{0.818750,0.206250,0.050000,0.050000},{0.831250,0.206250,0.025000,0.025000},{0.831250,0.206250,0.050000,0.050000},{0.843750,0.206250,0.025000,0.025000},{0.843750,0.206250,0.050000,0.050000},{0.856250,0.206250,0.025000,0.025000},{0.856250,0.206250,0.050000,0.050000},{0.868750,0.206250,0.025000,0.025000},{0.868750,0.206250,0.050000,0.050000},{0.881250,0.206250,0.025000,0.025000},{0.881250,0.206250,0.050000,0.050000},{0.893750,0.206250,0.025000,0.025000},{0.893750,0.206250,0.050000,0.050000},{0.906250,0.206250,0.025000,0.025000},{0.906250,0.206250,0.050000,0.050000},{0.918750,0.206250,0.025000,0.025000},{0.918750,0.206250,0.050000,0.050000},{0.931250,0.206250,0.025000,0.025000},{0.931250,0.206250,0.050000,0.050000},{0.943750,0.206250,0.025000,0.025000},{0.943750,0.206250,0.050000,0.050000},{0.956250,0.206250,0.025000,0.025000},{0.956250,0.206250,0.050000,0.050000},{0.968750,0.206250,0.025000,0.025000},{0.968750,0.206250,0.050000,0.050000},{0.981250,0.206250,0.025000,0.025000},{0.981250,0.206250,0.050000,0.050000},{0.993750,0.206250,0.025000,0.025000},{0.993750,0.206250,0.050000,0.050000},{0.006250,0.218750,0.025000,0.025000},{0.006250,0.218750,0.050000,0.050000},{0.018750,0.218750,0.025000,0.025000},{0.018750,0.218750,0.050000,0.050000},{0.031250,0.218750,0.025000,0.025000},{0.031250,0.218750,0.050000,0.050000},{0.043750,0.218750,0.025000,0.025000},{0.043750,0.218750,0.050000,0.050000},{0.056250,0.218750,0.025000,0.025000},{0.056250,0.218750,0.050000,0.050000},{0.068750,0.218750,0.025000,0.025000},{0.068750,0.218750,0.050000,0.050000},{0.081250,0.218750,0.025000,0.025000},{0.081250,0.218750,0.050000,0.050000},{0.093750,0.218750,0.025000,0.025000},{0.093750,0.218750,0.050000,0.050000},{0.106250,0.218750,0.025000,0.025000},{0.106250,0.218750,0.050000,0.050000},{0.118750,0.218750,0.025000,0.025000},{0.118750,0.218750,0.050000,0.050000},{0.131250,0.218750,0.025000,0.025000},{0.131250,0.218750,0.050000,0.050000},{0.143750,0.218750,0.025000,0.025000},{0.143750,0.218750,0.050000,0.050000},{0.156250,0.218750,0.025000,0.025000},{0.156250,0.218750,0.050000,0.050000},{0.168750,0.218750,0.025000,0.025000},{0.168750,0.218750,0.050000,0.050000},{0.181250,0.218750,0.025000,0.025000},{0.181250,0.218750,0.050000,0.050000},{0.193750,0.218750,0.025000,0.025000},{0.193750,0.218750,0.050000,0.050000},{0.206250,0.218750,0.025000,0.025000},{0.206250,0.218750,0.050000,0.050000},{0.218750,0.218750,0.025000,0.025000},{0.218750,0.218750,0.050000,0.050000},{0.231250,0.218750,0.025000,0.025000},{0.231250,0.218750,0.050000,0.050000},{0.243750,0.218750,0.025000,0.025000},{0.243750,0.218750,0.050000,0.050000},{0.256250,0.218750,0.025000,0.025000},{0.256250,0.218750,0.050000,0.050000},{0.268750,0.218750,0.025000,0.025000},{0.268750,0.218750,0.050000,0.050000},{0.281250,0.218750,0.025000,0.025000},{0.281250,0.218750,0.050000,0.050000},{0.293750,0.218750,0.025000,0.025000},{0.293750,0.218750,0.050000,0.050000},{0.306250,0.218750,0.025000,0.025000},{0.306250,0.218750,0.050000,0.050000},{0.318750,0.218750,0.025000,0.025000},{0.318750,0.218750,0.050000,0.050000},{0.331250,0.218750,0.025000,0.025000},{0.331250,0.218750,0.050000,0.050000},{0.343750,0.218750,0.025000,0.025000},{0.343750,0.218750,0.050000,0.050000},{0.356250,0.218750,0.025000,0.025000},{0.356250,0.218750,0.050000,0.050000},{0.368750,0.218750,0.025000,0.025000},{0.368750,0.218750,0.050000,0.050000},{0.381250,0.218750,0.025000,0.025000},{0.381250,0.218750,0.050000,0.050000},{0.393750,0.218750,0.025000,0.025000},{0.393750,0.218750,0.050000,0.050000},{0.406250,0.218750,0.025000,0.025000},{0.406250,0.218750,0.050000,0.050000},{0.418750,0.218750,0.025000,0.025000},{0.418750,0.218750,0.050000,0.050000},{0.431250,0.218750,0.025000,0.025000},{0.431250,0.218750,0.050000,0.050000},{0.443750,0.218750,0.025000,0.025000},{0.443750,0.218750,0.050000,0.050000},{0.456250,0.218750,0.025000,0.025000},{0.456250,0.218750,0.050000,0.050000},{0.468750,0.218750,0.025000,0.025000},{0.468750,0.218750,0.050000,0.050000},{0.481250,0.218750,0.025000,0.025000},{0.481250,0.218750,0.050000,0.050000},{0.493750,0.218750,0.025000,0.025000},{0.493750,0.218750,0.050000,0.050000},{0.506250,0.218750,0.025000,0.025000},{0.506250,0.218750,0.050000,0.050000},{0.518750,0.218750,0.025000,0.025000},{0.518750,0.218750,0.050000,0.050000},{0.531250,0.218750,0.025000,0.025000},{0.531250,0.218750,0.050000,0.050000},{0.543750,0.218750,0.025000,0.025000},{0.543750,0.218750,0.050000,0.050000},{0.556250,0.218750,0.025000,0.025000},{0.556250,0.218750,0.050000,0.050000},{0.568750,0.218750,0.025000,0.025000},{0.568750,0.218750,0.050000,0.050000},{0.581250,0.218750,0.025000,0.025000},{0.581250,0.218750,0.050000,0.050000},{0.593750,0.218750,0.025000,0.025000},{0.593750,0.218750,0.050000,0.050000},{0.606250,0.218750,0.025000,0.025000},{0.606250,0.218750,0.050000,0.050000},{0.618750,0.218750,0.025000,0.025000},{0.618750,0.218750,0.050000,0.050000},{0.631250,0.218750,0.025000,0.025000},{0.631250,0.218750,0.050000,0.050000},{0.643750,0.218750,0.025000,0.025000},{0.643750,0.218750,0.050000,0.050000},{0.656250,0.218750,0.025000,0.025000},{0.656250,0.218750,0.050000,0.050000},{0.668750,0.218750,0.025000,0.025000},{0.668750,0.218750,0.050000,0.050000},{0.681250,0.218750,0.025000,0.025000},{0.681250,0.218750,0.050000,0.050000},{0.693750,0.218750,0.025000,0.025000},{0.693750,0.218750,0.050000,0.050000},{0.706250,0.218750,0.025000,0.025000},{0.706250,0.218750,0.050000,0.050000},{0.718750,0.218750,0.025000,0.025000},{0.718750,0.218750,0.050000,0.050000},{0.731250,0.218750,0.025000,0.025000},{0.731250,0.218750,0.050000,0.050000},{0.743750,0.218750,0.025000,0.025000},{0.743750,0.218750,0.050000,0.050000},{0.756250,0.218750,0.025000,0.025000},{0.756250,0.218750,0.050000,0.050000},{0.768750,0.218750,0.025000,0.025000},{0.768750,0.218750,0.050000,0.050000},{0.781250,0.218750,0.025000,0.025000},{0.781250,0.218750,0.050000,0.050000},{0.793750,0.218750,0.025000,0.025000},{0.793750,0.218750,0.050000,0.050000},{0.806250,0.218750,0.025000,0.025000},{0.806250,0.218750,0.050000,0.050000},{0.818750,0.218750,0.025000,0.025000},{0.818750,0.218750,0.050000,0.050000},{0.831250,0.218750,0.025000,0.025000},{0.831250,0.218750,0.050000,0.050000},{0.843750,0.218750,0.025000,0.025000},{0.843750,0.218750,0.050000,0.050000},{0.856250,0.218750,0.025000,0.025000},{0.856250,0.218750,0.050000,0.050000},{0.868750,0.218750,0.025000,0.025000},{0.868750,0.218750,0.050000,0.050000},{0.881250,0.218750,0.025000,0.025000},{0.881250,0.218750,0.050000,0.050000},{0.893750,0.218750,0.025000,0.025000},{0.893750,0.218750,0.050000,0.050000},{0.906250,0.218750,0.025000,0.025000},{0.906250,0.218750,0.050000,0.050000},{0.918750,0.218750,0.025000,0.025000},{0.918750,0.218750,0.050000,0.050000},{0.931250,0.218750,0.025000,0.025000},{0.931250,0.218750,0.050000,0.050000},{0.943750,0.218750,0.025000,0.025000},{0.943750,0.218750,0.050000,0.050000},{0.956250,0.218750,0.025000,0.025000},{0.956250,0.218750,0.050000,0.050000},{0.968750,0.218750,0.025000,0.025000},{0.968750,0.218750,0.050000,0.050000},{0.981250,0.218750,0.025000,0.025000},{0.981250,0.218750,0.050000,0.050000},{0.993750,0.218750,0.025000,0.025000},{0.993750,0.218750,0.050000,0.050000},{0.006250,0.231250,0.025000,0.025000},{0.006250,0.231250,0.050000,0.050000},{0.018750,0.231250,0.025000,0.025000},{0.018750,0.231250,0.050000,0.050000},{0.031250,0.231250,0.025000,0.025000},{0.031250,0.231250,0.050000,0.050000},{0.043750,0.231250,0.025000,0.025000},{0.043750,0.231250,0.050000,0.050000},{0.056250,0.231250,0.025000,0.025000},{0.056250,0.231250,0.050000,0.050000},{0.068750,0.231250,0.025000,0.025000},{0.068750,0.231250,0.050000,0.050000},{0.081250,0.231250,0.025000,0.025000},{0.081250,0.231250,0.050000,0.050000},{0.093750,0.231250,0.025000,0.025000},{0.093750,0.231250,0.050000,0.050000},{0.106250,0.231250,0.025000,0.025000},{0.106250,0.231250,0.050000,0.050000},{0.118750,0.231250,0.025000,0.025000},{0.118750,0.231250,0.050000,0.050000},{0.131250,0.231250,0.025000,0.025000},{0.131250,0.231250,0.050000,0.050000},{0.143750,0.231250,0.025000,0.025000},{0.143750,0.231250,0.050000,0.050000},{0.156250,0.231250,0.025000,0.025000},{0.156250,0.231250,0.050000,0.050000},{0.168750,0.231250,0.025000,0.025000},{0.168750,0.231250,0.050000,0.050000},{0.181250,0.231250,0.025000,0.025000},{0.181250,0.231250,0.050000,0.050000},{0.193750,0.231250,0.025000,0.025000},{0.193750,0.231250,0.050000,0.050000},{0.206250,0.231250,0.025000,0.025000},{0.206250,0.231250,0.050000,0.050000},{0.218750,0.231250,0.025000,0.025000},{0.218750,0.231250,0.050000,0.050000},{0.231250,0.231250,0.025000,0.025000},{0.231250,0.231250,0.050000,0.050000},{0.243750,0.231250,0.025000,0.025000},{0.243750,0.231250,0.050000,0.050000},{0.256250,0.231250,0.025000,0.025000},{0.256250,0.231250,0.050000,0.050000},{0.268750,0.231250,0.025000,0.025000},{0.268750,0.231250,0.050000,0.050000},{0.281250,0.231250,0.025000,0.025000},{0.281250,0.231250,0.050000,0.050000},{0.293750,0.231250,0.025000,0.025000},{0.293750,0.231250,0.050000,0.050000},{0.306250,0.231250,0.025000,0.025000},{0.306250,0.231250,0.050000,0.050000},{0.318750,0.231250,0.025000,0.025000},{0.318750,0.231250,0.050000,0.050000},{0.331250,0.231250,0.025000,0.025000},{0.331250,0.231250,0.050000,0.050000},{0.343750,0.231250,0.025000,0.025000},{0.343750,0.231250,0.050000,0.050000},{0.356250,0.231250,0.025000,0.025000},{0.356250,0.231250,0.050000,0.050000},{0.368750,0.231250,0.025000,0.025000},{0.368750,0.231250,0.050000,0.050000},{0.381250,0.231250,0.025000,0.025000},{0.381250,0.231250,0.050000,0.050000},{0.393750,0.231250,0.025000,0.025000},{0.393750,0.231250,0.050000,0.050000},{0.406250,0.231250,0.025000,0.025000},{0.406250,0.231250,0.050000,0.050000},{0.418750,0.231250,0.025000,0.025000},{0.418750,0.231250,0.050000,0.050000},{0.431250,0.231250,0.025000,0.025000},{0.431250,0.231250,0.050000,0.050000},{0.443750,0.231250,0.025000,0.025000},{0.443750,0.231250,0.050000,0.050000},{0.456250,0.231250,0.025000,0.025000},{0.456250,0.231250,0.050000,0.050000},{0.468750,0.231250,0.025000,0.025000},{0.468750,0.231250,0.050000,0.050000},{0.481250,0.231250,0.025000,0.025000},{0.481250,0.231250,0.050000,0.050000},{0.493750,0.231250,0.025000,0.025000},{0.493750,0.231250,0.050000,0.050000},{0.506250,0.231250,0.025000,0.025000},{0.506250,0.231250,0.050000,0.050000},{0.518750,0.231250,0.025000,0.025000},{0.518750,0.231250,0.050000,0.050000},{0.531250,0.231250,0.025000,0.025000},{0.531250,0.231250,0.050000,0.050000},{0.543750,0.231250,0.025000,0.025000},{0.543750,0.231250,0.050000,0.050000},{0.556250,0.231250,0.025000,0.025000},{0.556250,0.231250,0.050000,0.050000},{0.568750,0.231250,0.025000,0.025000},{0.568750,0.231250,0.050000,0.050000},{0.581250,0.231250,0.025000,0.025000},{0.581250,0.231250,0.050000,0.050000},{0.593750,0.231250,0.025000,0.025000},{0.593750,0.231250,0.050000,0.050000},{0.606250,0.231250,0.025000,0.025000},{0.606250,0.231250,0.050000,0.050000},{0.618750,0.231250,0.025000,0.025000},{0.618750,0.231250,0.050000,0.050000},{0.631250,0.231250,0.025000,0.025000},{0.631250,0.231250,0.050000,0.050000},{0.643750,0.231250,0.025000,0.025000},{0.643750,0.231250,0.050000,0.050000},{0.656250,0.231250,0.025000,0.025000},{0.656250,0.231250,0.050000,0.050000},{0.668750,0.231250,0.025000,0.025000},{0.668750,0.231250,0.050000,0.050000},{0.681250,0.231250,0.025000,0.025000},{0.681250,0.231250,0.050000,0.050000},{0.693750,0.231250,0.025000,0.025000},{0.693750,0.231250,0.050000,0.050000},{0.706250,0.231250,0.025000,0.025000},{0.706250,0.231250,0.050000,0.050000},{0.718750,0.231250,0.025000,0.025000},{0.718750,0.231250,0.050000,0.050000},{0.731250,0.231250,0.025000,0.025000},{0.731250,0.231250,0.050000,0.050000},{0.743750,0.231250,0.025000,0.025000},{0.743750,0.231250,0.050000,0.050000},{0.756250,0.231250,0.025000,0.025000},{0.756250,0.231250,0.050000,0.050000},{0.768750,0.231250,0.025000,0.025000},{0.768750,0.231250,0.050000,0.050000},{0.781250,0.231250,0.025000,0.025000},{0.781250,0.231250,0.050000,0.050000},{0.793750,0.231250,0.025000,0.025000},{0.793750,0.231250,0.050000,0.050000},{0.806250,0.231250,0.025000,0.025000},{0.806250,0.231250,0.050000,0.050000},{0.818750,0.231250,0.025000,0.025000},{0.818750,0.231250,0.050000,0.050000},{0.831250,0.231250,0.025000,0.025000},{0.831250,0.231250,0.050000,0.050000},{0.843750,0.231250,0.025000,0.025000},{0.843750,0.231250,0.050000,0.050000},{0.856250,0.231250,0.025000,0.025000},{0.856250,0.231250,0.050000,0.050000},{0.868750,0.231250,0.025000,0.025000},{0.868750,0.231250,0.050000,0.050000},{0.881250,0.231250,0.025000,0.025000},{0.881250,0.231250,0.050000,0.050000},{0.893750,0.231250,0.025000,0.025000},{0.893750,0.231250,0.050000,0.050000},{0.906250,0.231250,0.025000,0.025000},{0.906250,0.231250,0.050000,0.050000},{0.918750,0.231250,0.025000,0.025000},{0.918750,0.231250,0.050000,0.050000},{0.931250,0.231250,0.025000,0.025000},{0.931250,0.231250,0.050000,0.050000},{0.943750,0.231250,0.025000,0.025000},{0.943750,0.231250,0.050000,0.050000},{0.956250,0.231250,0.025000,0.025000},{0.956250,0.231250,0.050000,0.050000},{0.968750,0.231250,0.025000,0.025000},{0.968750,0.231250,0.050000,0.050000},{0.981250,0.231250,0.025000,0.025000},{0.981250,0.231250,0.050000,0.050000},{0.993750,0.231250,0.025000,0.025000},{0.993750,0.231250,0.050000,0.050000},{0.006250,0.243750,0.025000,0.025000},{0.006250,0.243750,0.050000,0.050000},{0.018750,0.243750,0.025000,0.025000},{0.018750,0.243750,0.050000,0.050000},{0.031250,0.243750,0.025000,0.025000},{0.031250,0.243750,0.050000,0.050000},{0.043750,0.243750,0.025000,0.025000},{0.043750,0.243750,0.050000,0.050000},{0.056250,0.243750,0.025000,0.025000},{0.056250,0.243750,0.050000,0.050000},{0.068750,0.243750,0.025000,0.025000},{0.068750,0.243750,0.050000,0.050000},{0.081250,0.243750,0.025000,0.025000},{0.081250,0.243750,0.050000,0.050000},{0.093750,0.243750,0.025000,0.025000},{0.093750,0.243750,0.050000,0.050000},{0.106250,0.243750,0.025000,0.025000},{0.106250,0.243750,0.050000,0.050000},{0.118750,0.243750,0.025000,0.025000},{0.118750,0.243750,0.050000,0.050000},{0.131250,0.243750,0.025000,0.025000},{0.131250,0.243750,0.050000,0.050000},{0.143750,0.243750,0.025000,0.025000},{0.143750,0.243750,0.050000,0.050000},{0.156250,0.243750,0.025000,0.025000},{0.156250,0.243750,0.050000,0.050000},{0.168750,0.243750,0.025000,0.025000},{0.168750,0.243750,0.050000,0.050000},{0.181250,0.243750,0.025000,0.025000},{0.181250,0.243750,0.050000,0.050000},{0.193750,0.243750,0.025000,0.025000},{0.193750,0.243750,0.050000,0.050000},{0.206250,0.243750,0.025000,0.025000},{0.206250,0.243750,0.050000,0.050000},{0.218750,0.243750,0.025000,0.025000},{0.218750,0.243750,0.050000,0.050000},{0.231250,0.243750,0.025000,0.025000},{0.231250,0.243750,0.050000,0.050000},{0.243750,0.243750,0.025000,0.025000},{0.243750,0.243750,0.050000,0.050000},{0.256250,0.243750,0.025000,0.025000},{0.256250,0.243750,0.050000,0.050000},{0.268750,0.243750,0.025000,0.025000},{0.268750,0.243750,0.050000,0.050000},{0.281250,0.243750,0.025000,0.025000},{0.281250,0.243750,0.050000,0.050000},{0.293750,0.243750,0.025000,0.025000},{0.293750,0.243750,0.050000,0.050000},{0.306250,0.243750,0.025000,0.025000},{0.306250,0.243750,0.050000,0.050000},{0.318750,0.243750,0.025000,0.025000},{0.318750,0.243750,0.050000,0.050000},{0.331250,0.243750,0.025000,0.025000},{0.331250,0.243750,0.050000,0.050000},{0.343750,0.243750,0.025000,0.025000},{0.343750,0.243750,0.050000,0.050000},{0.356250,0.243750,0.025000,0.025000},{0.356250,0.243750,0.050000,0.050000},{0.368750,0.243750,0.025000,0.025000},{0.368750,0.243750,0.050000,0.050000},{0.381250,0.243750,0.025000,0.025000},{0.381250,0.243750,0.050000,0.050000},{0.393750,0.243750,0.025000,0.025000},{0.393750,0.243750,0.050000,0.050000},{0.406250,0.243750,0.025000,0.025000},{0.406250,0.243750,0.050000,0.050000},{0.418750,0.243750,0.025000,0.025000},{0.418750,0.243750,0.050000,0.050000},{0.431250,0.243750,0.025000,0.025000},{0.431250,0.243750,0.050000,0.050000},{0.443750,0.243750,0.025000,0.025000},{0.443750,0.243750,0.050000,0.050000},{0.456250,0.243750,0.025000,0.025000},{0.456250,0.243750,0.050000,0.050000},{0.468750,0.243750,0.025000,0.025000},{0.468750,0.243750,0.050000,0.050000},{0.481250,0.243750,0.025000,0.025000},{0.481250,0.243750,0.050000,0.050000},{0.493750,0.243750,0.025000,0.025000},{0.493750,0.243750,0.050000,0.050000},{0.506250,0.243750,0.025000,0.025000},{0.506250,0.243750,0.050000,0.050000},{0.518750,0.243750,0.025000,0.025000},{0.518750,0.243750,0.050000,0.050000},{0.531250,0.243750,0.025000,0.025000},{0.531250,0.243750,0.050000,0.050000},{0.543750,0.243750,0.025000,0.025000},{0.543750,0.243750,0.050000,0.050000},{0.556250,0.243750,0.025000,0.025000},{0.556250,0.243750,0.050000,0.050000},{0.568750,0.243750,0.025000,0.025000},{0.568750,0.243750,0.050000,0.050000},{0.581250,0.243750,0.025000,0.025000},{0.581250,0.243750,0.050000,0.050000},{0.593750,0.243750,0.025000,0.025000},{0.593750,0.243750,0.050000,0.050000},{0.606250,0.243750,0.025000,0.025000},{0.606250,0.243750,0.050000,0.050000},{0.618750,0.243750,0.025000,0.025000},{0.618750,0.243750,0.050000,0.050000},{0.631250,0.243750,0.025000,0.025000},{0.631250,0.243750,0.050000,0.050000},{0.643750,0.243750,0.025000,0.025000},{0.643750,0.243750,0.050000,0.050000},{0.656250,0.243750,0.025000,0.025000},{0.656250,0.243750,0.050000,0.050000},{0.668750,0.243750,0.025000,0.025000},{0.668750,0.243750,0.050000,0.050000},{0.681250,0.243750,0.025000,0.025000},{0.681250,0.243750,0.050000,0.050000},{0.693750,0.243750,0.025000,0.025000},{0.693750,0.243750,0.050000,0.050000},{0.706250,0.243750,0.025000,0.025000},{0.706250,0.243750,0.050000,0.050000},{0.718750,0.243750,0.025000,0.025000},{0.718750,0.243750,0.050000,0.050000},{0.731250,0.243750,0.025000,0.025000},{0.731250,0.243750,0.050000,0.050000},{0.743750,0.243750,0.025000,0.025000},{0.743750,0.243750,0.050000,0.050000},{0.756250,0.243750,0.025000,0.025000},{0.756250,0.243750,0.050000,0.050000},{0.768750,0.243750,0.025000,0.025000},{0.768750,0.243750,0.050000,0.050000},{0.781250,0.243750,0.025000,0.025000},{0.781250,0.243750,0.050000,0.050000},{0.793750,0.243750,0.025000,0.025000},{0.793750,0.243750,0.050000,0.050000},{0.806250,0.243750,0.025000,0.025000},{0.806250,0.243750,0.050000,0.050000},{0.818750,0.243750,0.025000,0.025000},{0.818750,0.243750,0.050000,0.050000},{0.831250,0.243750,0.025000,0.025000},{0.831250,0.243750,0.050000,0.050000},{0.843750,0.243750,0.025000,0.025000},{0.843750,0.243750,0.050000,0.050000},{0.856250,0.243750,0.025000,0.025000},{0.856250,0.243750,0.050000,0.050000},{0.868750,0.243750,0.025000,0.025000},{0.868750,0.243750,0.050000,0.050000},{0.881250,0.243750,0.025000,0.025000},{0.881250,0.243750,0.050000,0.050000},{0.893750,0.243750,0.025000,0.025000},{0.893750,0.243750,0.050000,0.050000},{0.906250,0.243750,0.025000,0.025000},{0.906250,0.243750,0.050000,0.050000},{0.918750,0.243750,0.025000,0.025000},{0.918750,0.243750,0.050000,0.050000},{0.931250,0.243750,0.025000,0.025000},{0.931250,0.243750,0.050000,0.050000},{0.943750,0.243750,0.025000,0.025000},{0.943750,0.243750,0.050000,0.050000},{0.956250,0.243750,0.025000,0.025000},{0.956250,0.243750,0.050000,0.050000},{0.968750,0.243750,0.025000,0.025000},{0.968750,0.243750,0.050000,0.050000},{0.981250,0.243750,0.025000,0.025000},{0.981250,0.243750,0.050000,0.050000},{0.993750,0.243750,0.025000,0.025000},{0.993750,0.243750,0.050000,0.050000},{0.006250,0.256250,0.025000,0.025000},{0.006250,0.256250,0.050000,0.050000},{0.018750,0.256250,0.025000,0.025000},{0.018750,0.256250,0.050000,0.050000},{0.031250,0.256250,0.025000,0.025000},{0.031250,0.256250,0.050000,0.050000},{0.043750,0.256250,0.025000,0.025000},{0.043750,0.256250,0.050000,0.050000},{0.056250,0.256250,0.025000,0.025000},{0.056250,0.256250,0.050000,0.050000},{0.068750,0.256250,0.025000,0.025000},{0.068750,0.256250,0.050000,0.050000},{0.081250,0.256250,0.025000,0.025000},{0.081250,0.256250,0.050000,0.050000},{0.093750,0.256250,0.025000,0.025000},{0.093750,0.256250,0.050000,0.050000},{0.106250,0.256250,0.025000,0.025000},{0.106250,0.256250,0.050000,0.050000},{0.118750,0.256250,0.025000,0.025000},{0.118750,0.256250,0.050000,0.050000},{0.131250,0.256250,0.025000,0.025000},{0.131250,0.256250,0.050000,0.050000},{0.143750,0.256250,0.025000,0.025000},{0.143750,0.256250,0.050000,0.050000},{0.156250,0.256250,0.025000,0.025000},{0.156250,0.256250,0.050000,0.050000},{0.168750,0.256250,0.025000,0.025000},{0.168750,0.256250,0.050000,0.050000},{0.181250,0.256250,0.025000,0.025000},{0.181250,0.256250,0.050000,0.050000},{0.193750,0.256250,0.025000,0.025000},{0.193750,0.256250,0.050000,0.050000},{0.206250,0.256250,0.025000,0.025000},{0.206250,0.256250,0.050000,0.050000},{0.218750,0.256250,0.025000,0.025000},{0.218750,0.256250,0.050000,0.050000},{0.231250,0.256250,0.025000,0.025000},{0.231250,0.256250,0.050000,0.050000},{0.243750,0.256250,0.025000,0.025000},{0.243750,0.256250,0.050000,0.050000},{0.256250,0.256250,0.025000,0.025000},{0.256250,0.256250,0.050000,0.050000},{0.268750,0.256250,0.025000,0.025000},{0.268750,0.256250,0.050000,0.050000},{0.281250,0.256250,0.025000,0.025000},{0.281250,0.256250,0.050000,0.050000},{0.293750,0.256250,0.025000,0.025000},{0.293750,0.256250,0.050000,0.050000},{0.306250,0.256250,0.025000,0.025000},{0.306250,0.256250,0.050000,0.050000},{0.318750,0.256250,0.025000,0.025000},{0.318750,0.256250,0.050000,0.050000},{0.331250,0.256250,0.025000,0.025000},{0.331250,0.256250,0.050000,0.050000},{0.343750,0.256250,0.025000,0.025000},{0.343750,0.256250,0.050000,0.050000},{0.356250,0.256250,0.025000,0.025000},{0.356250,0.256250,0.050000,0.050000},{0.368750,0.256250,0.025000,0.025000},{0.368750,0.256250,0.050000,0.050000},{0.381250,0.256250,0.025000,0.025000},{0.381250,0.256250,0.050000,0.050000},{0.393750,0.256250,0.025000,0.025000},{0.393750,0.256250,0.050000,0.050000},{0.406250,0.256250,0.025000,0.025000},{0.406250,0.256250,0.050000,0.050000},{0.418750,0.256250,0.025000,0.025000},{0.418750,0.256250,0.050000,0.050000},{0.431250,0.256250,0.025000,0.025000},{0.431250,0.256250,0.050000,0.050000},{0.443750,0.256250,0.025000,0.025000},{0.443750,0.256250,0.050000,0.050000},{0.456250,0.256250,0.025000,0.025000},{0.456250,0.256250,0.050000,0.050000},{0.468750,0.256250,0.025000,0.025000},{0.468750,0.256250,0.050000,0.050000},{0.481250,0.256250,0.025000,0.025000},{0.481250,0.256250,0.050000,0.050000},{0.493750,0.256250,0.025000,0.025000},{0.493750,0.256250,0.050000,0.050000},{0.506250,0.256250,0.025000,0.025000},{0.506250,0.256250,0.050000,0.050000},{0.518750,0.256250,0.025000,0.025000},{0.518750,0.256250,0.050000,0.050000},{0.531250,0.256250,0.025000,0.025000},{0.531250,0.256250,0.050000,0.050000},{0.543750,0.256250,0.025000,0.025000},{0.543750,0.256250,0.050000,0.050000},{0.556250,0.256250,0.025000,0.025000},{0.556250,0.256250,0.050000,0.050000},{0.568750,0.256250,0.025000,0.025000},{0.568750,0.256250,0.050000,0.050000},{0.581250,0.256250,0.025000,0.025000},{0.581250,0.256250,0.050000,0.050000},{0.593750,0.256250,0.025000,0.025000},{0.593750,0.256250,0.050000,0.050000},{0.606250,0.256250,0.025000,0.025000},{0.606250,0.256250,0.050000,0.050000},{0.618750,0.256250,0.025000,0.025000},{0.618750,0.256250,0.050000,0.050000},{0.631250,0.256250,0.025000,0.025000},{0.631250,0.256250,0.050000,0.050000},{0.643750,0.256250,0.025000,0.025000},{0.643750,0.256250,0.050000,0.050000},{0.656250,0.256250,0.025000,0.025000},{0.656250,0.256250,0.050000,0.050000},{0.668750,0.256250,0.025000,0.025000},{0.668750,0.256250,0.050000,0.050000},{0.681250,0.256250,0.025000,0.025000},{0.681250,0.256250,0.050000,0.050000},{0.693750,0.256250,0.025000,0.025000},{0.693750,0.256250,0.050000,0.050000},{0.706250,0.256250,0.025000,0.025000},{0.706250,0.256250,0.050000,0.050000},{0.718750,0.256250,0.025000,0.025000},{0.718750,0.256250,0.050000,0.050000},{0.731250,0.256250,0.025000,0.025000},{0.731250,0.256250,0.050000,0.050000},{0.743750,0.256250,0.025000,0.025000},{0.743750,0.256250,0.050000,0.050000},{0.756250,0.256250,0.025000,0.025000},{0.756250,0.256250,0.050000,0.050000},{0.768750,0.256250,0.025000,0.025000},{0.768750,0.256250,0.050000,0.050000},{0.781250,0.256250,0.025000,0.025000},{0.781250,0.256250,0.050000,0.050000},{0.793750,0.256250,0.025000,0.025000},{0.793750,0.256250,0.050000,0.050000},{0.806250,0.256250,0.025000,0.025000},{0.806250,0.256250,0.050000,0.050000},{0.818750,0.256250,0.025000,0.025000},{0.818750,0.256250,0.050000,0.050000},{0.831250,0.256250,0.025000,0.025000},{0.831250,0.256250,0.050000,0.050000},{0.843750,0.256250,0.025000,0.025000},{0.843750,0.256250,0.050000,0.050000},{0.856250,0.256250,0.025000,0.025000},{0.856250,0.256250,0.050000,0.050000},{0.868750,0.256250,0.025000,0.025000},{0.868750,0.256250,0.050000,0.050000},{0.881250,0.256250,0.025000,0.025000},{0.881250,0.256250,0.050000,0.050000},{0.893750,0.256250,0.025000,0.025000},{0.893750,0.256250,0.050000,0.050000},{0.906250,0.256250,0.025000,0.025000},{0.906250,0.256250,0.050000,0.050000},{0.918750,0.256250,0.025000,0.025000},{0.918750,0.256250,0.050000,0.050000},{0.931250,0.256250,0.025000,0.025000},{0.931250,0.256250,0.050000,0.050000},{0.943750,0.256250,0.025000,0.025000},{0.943750,0.256250,0.050000,0.050000},{0.956250,0.256250,0.025000,0.025000},{0.956250,0.256250,0.050000,0.050000},{0.968750,0.256250,0.025000,0.025000},{0.968750,0.256250,0.050000,0.050000},{0.981250,0.256250,0.025000,0.025000},{0.981250,0.256250,0.050000,0.050000},{0.993750,0.256250,0.025000,0.025000},{0.993750,0.256250,0.050000,0.050000},{0.006250,0.268750,0.025000,0.025000},{0.006250,0.268750,0.050000,0.050000},{0.018750,0.268750,0.025000,0.025000},{0.018750,0.268750,0.050000,0.050000},{0.031250,0.268750,0.025000,0.025000},{0.031250,0.268750,0.050000,0.050000},{0.043750,0.268750,0.025000,0.025000},{0.043750,0.268750,0.050000,0.050000},{0.056250,0.268750,0.025000,0.025000},{0.056250,0.268750,0.050000,0.050000},{0.068750,0.268750,0.025000,0.025000},{0.068750,0.268750,0.050000,0.050000},{0.081250,0.268750,0.025000,0.025000},{0.081250,0.268750,0.050000,0.050000},{0.093750,0.268750,0.025000,0.025000},{0.093750,0.268750,0.050000,0.050000},{0.106250,0.268750,0.025000,0.025000},{0.106250,0.268750,0.050000,0.050000},{0.118750,0.268750,0.025000,0.025000},{0.118750,0.268750,0.050000,0.050000},{0.131250,0.268750,0.025000,0.025000},{0.131250,0.268750,0.050000,0.050000},{0.143750,0.268750,0.025000,0.025000},{0.143750,0.268750,0.050000,0.050000},{0.156250,0.268750,0.025000,0.025000},{0.156250,0.268750,0.050000,0.050000},{0.168750,0.268750,0.025000,0.025000},{0.168750,0.268750,0.050000,0.050000},{0.181250,0.268750,0.025000,0.025000},{0.181250,0.268750,0.050000,0.050000},{0.193750,0.268750,0.025000,0.025000},{0.193750,0.268750,0.050000,0.050000},{0.206250,0.268750,0.025000,0.025000},{0.206250,0.268750,0.050000,0.050000},{0.218750,0.268750,0.025000,0.025000},{0.218750,0.268750,0.050000,0.050000},{0.231250,0.268750,0.025000,0.025000},{0.231250,0.268750,0.050000,0.050000},{0.243750,0.268750,0.025000,0.025000},{0.243750,0.268750,0.050000,0.050000},{0.256250,0.268750,0.025000,0.025000},{0.256250,0.268750,0.050000,0.050000},{0.268750,0.268750,0.025000,0.025000},{0.268750,0.268750,0.050000,0.050000},{0.281250,0.268750,0.025000,0.025000},{0.281250,0.268750,0.050000,0.050000},{0.293750,0.268750,0.025000,0.025000},{0.293750,0.268750,0.050000,0.050000},{0.306250,0.268750,0.025000,0.025000},{0.306250,0.268750,0.050000,0.050000},{0.318750,0.268750,0.025000,0.025000},{0.318750,0.268750,0.050000,0.050000},{0.331250,0.268750,0.025000,0.025000},{0.331250,0.268750,0.050000,0.050000},{0.343750,0.268750,0.025000,0.025000},{0.343750,0.268750,0.050000,0.050000},{0.356250,0.268750,0.025000,0.025000},{0.356250,0.268750,0.050000,0.050000},{0.368750,0.268750,0.025000,0.025000},{0.368750,0.268750,0.050000,0.050000},{0.381250,0.268750,0.025000,0.025000},{0.381250,0.268750,0.050000,0.050000},{0.393750,0.268750,0.025000,0.025000},{0.393750,0.268750,0.050000,0.050000},{0.406250,0.268750,0.025000,0.025000},{0.406250,0.268750,0.050000,0.050000},{0.418750,0.268750,0.025000,0.025000},{0.418750,0.268750,0.050000,0.050000},{0.431250,0.268750,0.025000,0.025000},{0.431250,0.268750,0.050000,0.050000},{0.443750,0.268750,0.025000,0.025000},{0.443750,0.268750,0.050000,0.050000},{0.456250,0.268750,0.025000,0.025000},{0.456250,0.268750,0.050000,0.050000},{0.468750,0.268750,0.025000,0.025000},{0.468750,0.268750,0.050000,0.050000},{0.481250,0.268750,0.025000,0.025000},{0.481250,0.268750,0.050000,0.050000},{0.493750,0.268750,0.025000,0.025000},{0.493750,0.268750,0.050000,0.050000},{0.506250,0.268750,0.025000,0.025000},{0.506250,0.268750,0.050000,0.050000},{0.518750,0.268750,0.025000,0.025000},{0.518750,0.268750,0.050000,0.050000},{0.531250,0.268750,0.025000,0.025000},{0.531250,0.268750,0.050000,0.050000},{0.543750,0.268750,0.025000,0.025000},{0.543750,0.268750,0.050000,0.050000},{0.556250,0.268750,0.025000,0.025000},{0.556250,0.268750,0.050000,0.050000},{0.568750,0.268750,0.025000,0.025000},{0.568750,0.268750,0.050000,0.050000},{0.581250,0.268750,0.025000,0.025000},{0.581250,0.268750,0.050000,0.050000},{0.593750,0.268750,0.025000,0.025000},{0.593750,0.268750,0.050000,0.050000},{0.606250,0.268750,0.025000,0.025000},{0.606250,0.268750,0.050000,0.050000},{0.618750,0.268750,0.025000,0.025000},{0.618750,0.268750,0.050000,0.050000},{0.631250,0.268750,0.025000,0.025000},{0.631250,0.268750,0.050000,0.050000},{0.643750,0.268750,0.025000,0.025000},{0.643750,0.268750,0.050000,0.050000},{0.656250,0.268750,0.025000,0.025000},{0.656250,0.268750,0.050000,0.050000},{0.668750,0.268750,0.025000,0.025000},{0.668750,0.268750,0.050000,0.050000},{0.681250,0.268750,0.025000,0.025000},{0.681250,0.268750,0.050000,0.050000},{0.693750,0.268750,0.025000,0.025000},{0.693750,0.268750,0.050000,0.050000},{0.706250,0.268750,0.025000,0.025000},{0.706250,0.268750,0.050000,0.050000},{0.718750,0.268750,0.025000,0.025000},{0.718750,0.268750,0.050000,0.050000},{0.731250,0.268750,0.025000,0.025000},{0.731250,0.268750,0.050000,0.050000},{0.743750,0.268750,0.025000,0.025000},{0.743750,0.268750,0.050000,0.050000},{0.756250,0.268750,0.025000,0.025000},{0.756250,0.268750,0.050000,0.050000},{0.768750,0.268750,0.025000,0.025000},{0.768750,0.268750,0.050000,0.050000},{0.781250,0.268750,0.025000,0.025000},{0.781250,0.268750,0.050000,0.050000},{0.793750,0.268750,0.025000,0.025000},{0.793750,0.268750,0.050000,0.050000},{0.806250,0.268750,0.025000,0.025000},{0.806250,0.268750,0.050000,0.050000},{0.818750,0.268750,0.025000,0.025000},{0.818750,0.268750,0.050000,0.050000},{0.831250,0.268750,0.025000,0.025000},{0.831250,0.268750,0.050000,0.050000},{0.843750,0.268750,0.025000,0.025000},{0.843750,0.268750,0.050000,0.050000},{0.856250,0.268750,0.025000,0.025000},{0.856250,0.268750,0.050000,0.050000},{0.868750,0.268750,0.025000,0.025000},{0.868750,0.268750,0.050000,0.050000},{0.881250,0.268750,0.025000,0.025000},{0.881250,0.268750,0.050000,0.050000},{0.893750,0.268750,0.025000,0.025000},{0.893750,0.268750,0.050000,0.050000},{0.906250,0.268750,0.025000,0.025000},{0.906250,0.268750,0.050000,0.050000},{0.918750,0.268750,0.025000,0.025000},{0.918750,0.268750,0.050000,0.050000},{0.931250,0.268750,0.025000,0.025000},{0.931250,0.268750,0.050000,0.050000},{0.943750,0.268750,0.025000,0.025000},{0.943750,0.268750,0.050000,0.050000},{0.956250,0.268750,0.025000,0.025000},{0.956250,0.268750,0.050000,0.050000},{0.968750,0.268750,0.025000,0.025000},{0.968750,0.268750,0.050000,0.050000},{0.981250,0.268750,0.025000,0.025000},{0.981250,0.268750,0.050000,0.050000},{0.993750,0.268750,0.025000,0.025000},{0.993750,0.268750,0.050000,0.050000},{0.006250,0.281250,0.025000,0.025000},{0.006250,0.281250,0.050000,0.050000},{0.018750,0.281250,0.025000,0.025000},{0.018750,0.281250,0.050000,0.050000},{0.031250,0.281250,0.025000,0.025000},{0.031250,0.281250,0.050000,0.050000},{0.043750,0.281250,0.025000,0.025000},{0.043750,0.281250,0.050000,0.050000},{0.056250,0.281250,0.025000,0.025000},{0.056250,0.281250,0.050000,0.050000},{0.068750,0.281250,0.025000,0.025000},{0.068750,0.281250,0.050000,0.050000},{0.081250,0.281250,0.025000,0.025000},{0.081250,0.281250,0.050000,0.050000},{0.093750,0.281250,0.025000,0.025000},{0.093750,0.281250,0.050000,0.050000},{0.106250,0.281250,0.025000,0.025000},{0.106250,0.281250,0.050000,0.050000},{0.118750,0.281250,0.025000,0.025000},{0.118750,0.281250,0.050000,0.050000},{0.131250,0.281250,0.025000,0.025000},{0.131250,0.281250,0.050000,0.050000},{0.143750,0.281250,0.025000,0.025000},{0.143750,0.281250,0.050000,0.050000},{0.156250,0.281250,0.025000,0.025000},{0.156250,0.281250,0.050000,0.050000},{0.168750,0.281250,0.025000,0.025000},{0.168750,0.281250,0.050000,0.050000},{0.181250,0.281250,0.025000,0.025000},{0.181250,0.281250,0.050000,0.050000},{0.193750,0.281250,0.025000,0.025000},{0.193750,0.281250,0.050000,0.050000},{0.206250,0.281250,0.025000,0.025000},{0.206250,0.281250,0.050000,0.050000},{0.218750,0.281250,0.025000,0.025000},{0.218750,0.281250,0.050000,0.050000},{0.231250,0.281250,0.025000,0.025000},{0.231250,0.281250,0.050000,0.050000},{0.243750,0.281250,0.025000,0.025000},{0.243750,0.281250,0.050000,0.050000},{0.256250,0.281250,0.025000,0.025000},{0.256250,0.281250,0.050000,0.050000},{0.268750,0.281250,0.025000,0.025000},{0.268750,0.281250,0.050000,0.050000},{0.281250,0.281250,0.025000,0.025000},{0.281250,0.281250,0.050000,0.050000},{0.293750,0.281250,0.025000,0.025000},{0.293750,0.281250,0.050000,0.050000},{0.306250,0.281250,0.025000,0.025000},{0.306250,0.281250,0.050000,0.050000},{0.318750,0.281250,0.025000,0.025000},{0.318750,0.281250,0.050000,0.050000},{0.331250,0.281250,0.025000,0.025000},{0.331250,0.281250,0.050000,0.050000},{0.343750,0.281250,0.025000,0.025000},{0.343750,0.281250,0.050000,0.050000},{0.356250,0.281250,0.025000,0.025000},{0.356250,0.281250,0.050000,0.050000},{0.368750,0.281250,0.025000,0.025000},{0.368750,0.281250,0.050000,0.050000},{0.381250,0.281250,0.025000,0.025000},{0.381250,0.281250,0.050000,0.050000},{0.393750,0.281250,0.025000,0.025000},{0.393750,0.281250,0.050000,0.050000},{0.406250,0.281250,0.025000,0.025000},{0.406250,0.281250,0.050000,0.050000},{0.418750,0.281250,0.025000,0.025000},{0.418750,0.281250,0.050000,0.050000},{0.431250,0.281250,0.025000,0.025000},{0.431250,0.281250,0.050000,0.050000},{0.443750,0.281250,0.025000,0.025000},{0.443750,0.281250,0.050000,0.050000},{0.456250,0.281250,0.025000,0.025000},{0.456250,0.281250,0.050000,0.050000},{0.468750,0.281250,0.025000,0.025000},{0.468750,0.281250,0.050000,0.050000},{0.481250,0.281250,0.025000,0.025000},{0.481250,0.281250,0.050000,0.050000},{0.493750,0.281250,0.025000,0.025000},{0.493750,0.281250,0.050000,0.050000},{0.506250,0.281250,0.025000,0.025000},{0.506250,0.281250,0.050000,0.050000},{0.518750,0.281250,0.025000,0.025000},{0.518750,0.281250,0.050000,0.050000},{0.531250,0.281250,0.025000,0.025000},{0.531250,0.281250,0.050000,0.050000},{0.543750,0.281250,0.025000,0.025000},{0.543750,0.281250,0.050000,0.050000},{0.556250,0.281250,0.025000,0.025000},{0.556250,0.281250,0.050000,0.050000},{0.568750,0.281250,0.025000,0.025000},{0.568750,0.281250,0.050000,0.050000},{0.581250,0.281250,0.025000,0.025000},{0.581250,0.281250,0.050000,0.050000},{0.593750,0.281250,0.025000,0.025000},{0.593750,0.281250,0.050000,0.050000},{0.606250,0.281250,0.025000,0.025000},{0.606250,0.281250,0.050000,0.050000},{0.618750,0.281250,0.025000,0.025000},{0.618750,0.281250,0.050000,0.050000},{0.631250,0.281250,0.025000,0.025000},{0.631250,0.281250,0.050000,0.050000},{0.643750,0.281250,0.025000,0.025000},{0.643750,0.281250,0.050000,0.050000},{0.656250,0.281250,0.025000,0.025000},{0.656250,0.281250,0.050000,0.050000},{0.668750,0.281250,0.025000,0.025000},{0.668750,0.281250,0.050000,0.050000},{0.681250,0.281250,0.025000,0.025000},{0.681250,0.281250,0.050000,0.050000},{0.693750,0.281250,0.025000,0.025000},{0.693750,0.281250,0.050000,0.050000},{0.706250,0.281250,0.025000,0.025000},{0.706250,0.281250,0.050000,0.050000},{0.718750,0.281250,0.025000,0.025000},{0.718750,0.281250,0.050000,0.050000},{0.731250,0.281250,0.025000,0.025000},{0.731250,0.281250,0.050000,0.050000},{0.743750,0.281250,0.025000,0.025000},{0.743750,0.281250,0.050000,0.050000},{0.756250,0.281250,0.025000,0.025000},{0.756250,0.281250,0.050000,0.050000},{0.768750,0.281250,0.025000,0.025000},{0.768750,0.281250,0.050000,0.050000},{0.781250,0.281250,0.025000,0.025000},{0.781250,0.281250,0.050000,0.050000},{0.793750,0.281250,0.025000,0.025000},{0.793750,0.281250,0.050000,0.050000},{0.806250,0.281250,0.025000,0.025000},{0.806250,0.281250,0.050000,0.050000},{0.818750,0.281250,0.025000,0.025000},{0.818750,0.281250,0.050000,0.050000},{0.831250,0.281250,0.025000,0.025000},{0.831250,0.281250,0.050000,0.050000},{0.843750,0.281250,0.025000,0.025000},{0.843750,0.281250,0.050000,0.050000},{0.856250,0.281250,0.025000,0.025000},{0.856250,0.281250,0.050000,0.050000},{0.868750,0.281250,0.025000,0.025000},{0.868750,0.281250,0.050000,0.050000},{0.881250,0.281250,0.025000,0.025000},{0.881250,0.281250,0.050000,0.050000},{0.893750,0.281250,0.025000,0.025000},{0.893750,0.281250,0.050000,0.050000},{0.906250,0.281250,0.025000,0.025000},{0.906250,0.281250,0.050000,0.050000},{0.918750,0.281250,0.025000,0.025000},{0.918750,0.281250,0.050000,0.050000},{0.931250,0.281250,0.025000,0.025000},{0.931250,0.281250,0.050000,0.050000},{0.943750,0.281250,0.025000,0.025000},{0.943750,0.281250,0.050000,0.050000},{0.956250,0.281250,0.025000,0.025000},{0.956250,0.281250,0.050000,0.050000},{0.968750,0.281250,0.025000,0.025000},{0.968750,0.281250,0.050000,0.050000},{0.981250,0.281250,0.025000,0.025000},{0.981250,0.281250,0.050000,0.050000},{0.993750,0.281250,0.025000,0.025000},{0.993750,0.281250,0.050000,0.050000},{0.006250,0.293750,0.025000,0.025000},{0.006250,0.293750,0.050000,0.050000},{0.018750,0.293750,0.025000,0.025000},{0.018750,0.293750,0.050000,0.050000},{0.031250,0.293750,0.025000,0.025000},{0.031250,0.293750,0.050000,0.050000},{0.043750,0.293750,0.025000,0.025000},{0.043750,0.293750,0.050000,0.050000},{0.056250,0.293750,0.025000,0.025000},{0.056250,0.293750,0.050000,0.050000},{0.068750,0.293750,0.025000,0.025000},{0.068750,0.293750,0.050000,0.050000},{0.081250,0.293750,0.025000,0.025000},{0.081250,0.293750,0.050000,0.050000},{0.093750,0.293750,0.025000,0.025000},{0.093750,0.293750,0.050000,0.050000},{0.106250,0.293750,0.025000,0.025000},{0.106250,0.293750,0.050000,0.050000},{0.118750,0.293750,0.025000,0.025000},{0.118750,0.293750,0.050000,0.050000},{0.131250,0.293750,0.025000,0.025000},{0.131250,0.293750,0.050000,0.050000},{0.143750,0.293750,0.025000,0.025000},{0.143750,0.293750,0.050000,0.050000},{0.156250,0.293750,0.025000,0.025000},{0.156250,0.293750,0.050000,0.050000},{0.168750,0.293750,0.025000,0.025000},{0.168750,0.293750,0.050000,0.050000},{0.181250,0.293750,0.025000,0.025000},{0.181250,0.293750,0.050000,0.050000},{0.193750,0.293750,0.025000,0.025000},{0.193750,0.293750,0.050000,0.050000},{0.206250,0.293750,0.025000,0.025000},{0.206250,0.293750,0.050000,0.050000},{0.218750,0.293750,0.025000,0.025000},{0.218750,0.293750,0.050000,0.050000},{0.231250,0.293750,0.025000,0.025000},{0.231250,0.293750,0.050000,0.050000},{0.243750,0.293750,0.025000,0.025000},{0.243750,0.293750,0.050000,0.050000},{0.256250,0.293750,0.025000,0.025000},{0.256250,0.293750,0.050000,0.050000},{0.268750,0.293750,0.025000,0.025000},{0.268750,0.293750,0.050000,0.050000},{0.281250,0.293750,0.025000,0.025000},{0.281250,0.293750,0.050000,0.050000},{0.293750,0.293750,0.025000,0.025000},{0.293750,0.293750,0.050000,0.050000},{0.306250,0.293750,0.025000,0.025000},{0.306250,0.293750,0.050000,0.050000},{0.318750,0.293750,0.025000,0.025000},{0.318750,0.293750,0.050000,0.050000},{0.331250,0.293750,0.025000,0.025000},{0.331250,0.293750,0.050000,0.050000},{0.343750,0.293750,0.025000,0.025000},{0.343750,0.293750,0.050000,0.050000},{0.356250,0.293750,0.025000,0.025000},{0.356250,0.293750,0.050000,0.050000},{0.368750,0.293750,0.025000,0.025000},{0.368750,0.293750,0.050000,0.050000},{0.381250,0.293750,0.025000,0.025000},{0.381250,0.293750,0.050000,0.050000},{0.393750,0.293750,0.025000,0.025000},{0.393750,0.293750,0.050000,0.050000},{0.406250,0.293750,0.025000,0.025000},{0.406250,0.293750,0.050000,0.050000},{0.418750,0.293750,0.025000,0.025000},{0.418750,0.293750,0.050000,0.050000},{0.431250,0.293750,0.025000,0.025000},{0.431250,0.293750,0.050000,0.050000},{0.443750,0.293750,0.025000,0.025000},{0.443750,0.293750,0.050000,0.050000},{0.456250,0.293750,0.025000,0.025000},{0.456250,0.293750,0.050000,0.050000},{0.468750,0.293750,0.025000,0.025000},{0.468750,0.293750,0.050000,0.050000},{0.481250,0.293750,0.025000,0.025000},{0.481250,0.293750,0.050000,0.050000},{0.493750,0.293750,0.025000,0.025000},{0.493750,0.293750,0.050000,0.050000},{0.506250,0.293750,0.025000,0.025000},{0.506250,0.293750,0.050000,0.050000},{0.518750,0.293750,0.025000,0.025000},{0.518750,0.293750,0.050000,0.050000},{0.531250,0.293750,0.025000,0.025000},{0.531250,0.293750,0.050000,0.050000},{0.543750,0.293750,0.025000,0.025000},{0.543750,0.293750,0.050000,0.050000},{0.556250,0.293750,0.025000,0.025000},{0.556250,0.293750,0.050000,0.050000},{0.568750,0.293750,0.025000,0.025000},{0.568750,0.293750,0.050000,0.050000},{0.581250,0.293750,0.025000,0.025000},{0.581250,0.293750,0.050000,0.050000},{0.593750,0.293750,0.025000,0.025000},{0.593750,0.293750,0.050000,0.050000},{0.606250,0.293750,0.025000,0.025000},{0.606250,0.293750,0.050000,0.050000},{0.618750,0.293750,0.025000,0.025000},{0.618750,0.293750,0.050000,0.050000},{0.631250,0.293750,0.025000,0.025000},{0.631250,0.293750,0.050000,0.050000},{0.643750,0.293750,0.025000,0.025000},{0.643750,0.293750,0.050000,0.050000},{0.656250,0.293750,0.025000,0.025000},{0.656250,0.293750,0.050000,0.050000},{0.668750,0.293750,0.025000,0.025000},{0.668750,0.293750,0.050000,0.050000},{0.681250,0.293750,0.025000,0.025000},{0.681250,0.293750,0.050000,0.050000},{0.693750,0.293750,0.025000,0.025000},{0.693750,0.293750,0.050000,0.050000},{0.706250,0.293750,0.025000,0.025000},{0.706250,0.293750,0.050000,0.050000},{0.718750,0.293750,0.025000,0.025000},{0.718750,0.293750,0.050000,0.050000},{0.731250,0.293750,0.025000,0.025000},{0.731250,0.293750,0.050000,0.050000},{0.743750,0.293750,0.025000,0.025000},{0.743750,0.293750,0.050000,0.050000},{0.756250,0.293750,0.025000,0.025000},{0.756250,0.293750,0.050000,0.050000},{0.768750,0.293750,0.025000,0.025000},{0.768750,0.293750,0.050000,0.050000},{0.781250,0.293750,0.025000,0.025000},{0.781250,0.293750,0.050000,0.050000},{0.793750,0.293750,0.025000,0.025000},{0.793750,0.293750,0.050000,0.050000},{0.806250,0.293750,0.025000,0.025000},{0.806250,0.293750,0.050000,0.050000},{0.818750,0.293750,0.025000,0.025000},{0.818750,0.293750,0.050000,0.050000},{0.831250,0.293750,0.025000,0.025000},{0.831250,0.293750,0.050000,0.050000},{0.843750,0.293750,0.025000,0.025000},{0.843750,0.293750,0.050000,0.050000},{0.856250,0.293750,0.025000,0.025000},{0.856250,0.293750,0.050000,0.050000},{0.868750,0.293750,0.025000,0.025000},{0.868750,0.293750,0.050000,0.050000},{0.881250,0.293750,0.025000,0.025000},{0.881250,0.293750,0.050000,0.050000},{0.893750,0.293750,0.025000,0.025000},{0.893750,0.293750,0.050000,0.050000},{0.906250,0.293750,0.025000,0.025000},{0.906250,0.293750,0.050000,0.050000},{0.918750,0.293750,0.025000,0.025000},{0.918750,0.293750,0.050000,0.050000},{0.931250,0.293750,0.025000,0.025000},{0.931250,0.293750,0.050000,0.050000},{0.943750,0.293750,0.025000,0.025000},{0.943750,0.293750,0.050000,0.050000},{0.956250,0.293750,0.025000,0.025000},{0.956250,0.293750,0.050000,0.050000},{0.968750,0.293750,0.025000,0.025000},{0.968750,0.293750,0.050000,0.050000},{0.981250,0.293750,0.025000,0.025000},{0.981250,0.293750,0.050000,0.050000},{0.993750,0.293750,0.025000,0.025000},{0.993750,0.293750,0.050000,0.050000},{0.006250,0.306250,0.025000,0.025000},{0.006250,0.306250,0.050000,0.050000},{0.018750,0.306250,0.025000,0.025000},{0.018750,0.306250,0.050000,0.050000},{0.031250,0.306250,0.025000,0.025000},{0.031250,0.306250,0.050000,0.050000},{0.043750,0.306250,0.025000,0.025000},{0.043750,0.306250,0.050000,0.050000},{0.056250,0.306250,0.025000,0.025000},{0.056250,0.306250,0.050000,0.050000},{0.068750,0.306250,0.025000,0.025000},{0.068750,0.306250,0.050000,0.050000},{0.081250,0.306250,0.025000,0.025000},{0.081250,0.306250,0.050000,0.050000},{0.093750,0.306250,0.025000,0.025000},{0.093750,0.306250,0.050000,0.050000},{0.106250,0.306250,0.025000,0.025000},{0.106250,0.306250,0.050000,0.050000},{0.118750,0.306250,0.025000,0.025000},{0.118750,0.306250,0.050000,0.050000},{0.131250,0.306250,0.025000,0.025000},{0.131250,0.306250,0.050000,0.050000},{0.143750,0.306250,0.025000,0.025000},{0.143750,0.306250,0.050000,0.050000},{0.156250,0.306250,0.025000,0.025000},{0.156250,0.306250,0.050000,0.050000},{0.168750,0.306250,0.025000,0.025000},{0.168750,0.306250,0.050000,0.050000},{0.181250,0.306250,0.025000,0.025000},{0.181250,0.306250,0.050000,0.050000},{0.193750,0.306250,0.025000,0.025000},{0.193750,0.306250,0.050000,0.050000},{0.206250,0.306250,0.025000,0.025000},{0.206250,0.306250,0.050000,0.050000},{0.218750,0.306250,0.025000,0.025000},{0.218750,0.306250,0.050000,0.050000},{0.231250,0.306250,0.025000,0.025000},{0.231250,0.306250,0.050000,0.050000},{0.243750,0.306250,0.025000,0.025000},{0.243750,0.306250,0.050000,0.050000},{0.256250,0.306250,0.025000,0.025000},{0.256250,0.306250,0.050000,0.050000},{0.268750,0.306250,0.025000,0.025000},{0.268750,0.306250,0.050000,0.050000},{0.281250,0.306250,0.025000,0.025000},{0.281250,0.306250,0.050000,0.050000},{0.293750,0.306250,0.025000,0.025000},{0.293750,0.306250,0.050000,0.050000},{0.306250,0.306250,0.025000,0.025000},{0.306250,0.306250,0.050000,0.050000},{0.318750,0.306250,0.025000,0.025000},{0.318750,0.306250,0.050000,0.050000},{0.331250,0.306250,0.025000,0.025000},{0.331250,0.306250,0.050000,0.050000},{0.343750,0.306250,0.025000,0.025000},{0.343750,0.306250,0.050000,0.050000},{0.356250,0.306250,0.025000,0.025000},{0.356250,0.306250,0.050000,0.050000},{0.368750,0.306250,0.025000,0.025000},{0.368750,0.306250,0.050000,0.050000},{0.381250,0.306250,0.025000,0.025000},{0.381250,0.306250,0.050000,0.050000},{0.393750,0.306250,0.025000,0.025000},{0.393750,0.306250,0.050000,0.050000},{0.406250,0.306250,0.025000,0.025000},{0.406250,0.306250,0.050000,0.050000},{0.418750,0.306250,0.025000,0.025000},{0.418750,0.306250,0.050000,0.050000},{0.431250,0.306250,0.025000,0.025000},{0.431250,0.306250,0.050000,0.050000},{0.443750,0.306250,0.025000,0.025000},{0.443750,0.306250,0.050000,0.050000},{0.456250,0.306250,0.025000,0.025000},{0.456250,0.306250,0.050000,0.050000},{0.468750,0.306250,0.025000,0.025000},{0.468750,0.306250,0.050000,0.050000},{0.481250,0.306250,0.025000,0.025000},{0.481250,0.306250,0.050000,0.050000},{0.493750,0.306250,0.025000,0.025000},{0.493750,0.306250,0.050000,0.050000},{0.506250,0.306250,0.025000,0.025000},{0.506250,0.306250,0.050000,0.050000},{0.518750,0.306250,0.025000,0.025000},{0.518750,0.306250,0.050000,0.050000},{0.531250,0.306250,0.025000,0.025000},{0.531250,0.306250,0.050000,0.050000},{0.543750,0.306250,0.025000,0.025000},{0.543750,0.306250,0.050000,0.050000},{0.556250,0.306250,0.025000,0.025000},{0.556250,0.306250,0.050000,0.050000},{0.568750,0.306250,0.025000,0.025000},{0.568750,0.306250,0.050000,0.050000},{0.581250,0.306250,0.025000,0.025000},{0.581250,0.306250,0.050000,0.050000},{0.593750,0.306250,0.025000,0.025000},{0.593750,0.306250,0.050000,0.050000},{0.606250,0.306250,0.025000,0.025000},{0.606250,0.306250,0.050000,0.050000},{0.618750,0.306250,0.025000,0.025000},{0.618750,0.306250,0.050000,0.050000},{0.631250,0.306250,0.025000,0.025000},{0.631250,0.306250,0.050000,0.050000},{0.643750,0.306250,0.025000,0.025000},{0.643750,0.306250,0.050000,0.050000},{0.656250,0.306250,0.025000,0.025000},{0.656250,0.306250,0.050000,0.050000},{0.668750,0.306250,0.025000,0.025000},{0.668750,0.306250,0.050000,0.050000},{0.681250,0.306250,0.025000,0.025000},{0.681250,0.306250,0.050000,0.050000},{0.693750,0.306250,0.025000,0.025000},{0.693750,0.306250,0.050000,0.050000},{0.706250,0.306250,0.025000,0.025000},{0.706250,0.306250,0.050000,0.050000},{0.718750,0.306250,0.025000,0.025000},{0.718750,0.306250,0.050000,0.050000},{0.731250,0.306250,0.025000,0.025000},{0.731250,0.306250,0.050000,0.050000},{0.743750,0.306250,0.025000,0.025000},{0.743750,0.306250,0.050000,0.050000},{0.756250,0.306250,0.025000,0.025000},{0.756250,0.306250,0.050000,0.050000},{0.768750,0.306250,0.025000,0.025000},{0.768750,0.306250,0.050000,0.050000},{0.781250,0.306250,0.025000,0.025000},{0.781250,0.306250,0.050000,0.050000},{0.793750,0.306250,0.025000,0.025000},{0.793750,0.306250,0.050000,0.050000},{0.806250,0.306250,0.025000,0.025000},{0.806250,0.306250,0.050000,0.050000},{0.818750,0.306250,0.025000,0.025000},{0.818750,0.306250,0.050000,0.050000},{0.831250,0.306250,0.025000,0.025000},{0.831250,0.306250,0.050000,0.050000},{0.843750,0.306250,0.025000,0.025000},{0.843750,0.306250,0.050000,0.050000},{0.856250,0.306250,0.025000,0.025000},{0.856250,0.306250,0.050000,0.050000},{0.868750,0.306250,0.025000,0.025000},{0.868750,0.306250,0.050000,0.050000},{0.881250,0.306250,0.025000,0.025000},{0.881250,0.306250,0.050000,0.050000},{0.893750,0.306250,0.025000,0.025000},{0.893750,0.306250,0.050000,0.050000},{0.906250,0.306250,0.025000,0.025000},{0.906250,0.306250,0.050000,0.050000},{0.918750,0.306250,0.025000,0.025000},{0.918750,0.306250,0.050000,0.050000},{0.931250,0.306250,0.025000,0.025000},{0.931250,0.306250,0.050000,0.050000},{0.943750,0.306250,0.025000,0.025000},{0.943750,0.306250,0.050000,0.050000},{0.956250,0.306250,0.025000,0.025000},{0.956250,0.306250,0.050000,0.050000},{0.968750,0.306250,0.025000,0.025000},{0.968750,0.306250,0.050000,0.050000},{0.981250,0.306250,0.025000,0.025000},{0.981250,0.306250,0.050000,0.050000},{0.993750,0.306250,0.025000,0.025000},{0.993750,0.306250,0.050000,0.050000},{0.006250,0.318750,0.025000,0.025000},{0.006250,0.318750,0.050000,0.050000},{0.018750,0.318750,0.025000,0.025000},{0.018750,0.318750,0.050000,0.050000},{0.031250,0.318750,0.025000,0.025000},{0.031250,0.318750,0.050000,0.050000},{0.043750,0.318750,0.025000,0.025000},{0.043750,0.318750,0.050000,0.050000},{0.056250,0.318750,0.025000,0.025000},{0.056250,0.318750,0.050000,0.050000},{0.068750,0.318750,0.025000,0.025000},{0.068750,0.318750,0.050000,0.050000},{0.081250,0.318750,0.025000,0.025000},{0.081250,0.318750,0.050000,0.050000},{0.093750,0.318750,0.025000,0.025000},{0.093750,0.318750,0.050000,0.050000},{0.106250,0.318750,0.025000,0.025000},{0.106250,0.318750,0.050000,0.050000},{0.118750,0.318750,0.025000,0.025000},{0.118750,0.318750,0.050000,0.050000},{0.131250,0.318750,0.025000,0.025000},{0.131250,0.318750,0.050000,0.050000},{0.143750,0.318750,0.025000,0.025000},{0.143750,0.318750,0.050000,0.050000},{0.156250,0.318750,0.025000,0.025000},{0.156250,0.318750,0.050000,0.050000},{0.168750,0.318750,0.025000,0.025000},{0.168750,0.318750,0.050000,0.050000},{0.181250,0.318750,0.025000,0.025000},{0.181250,0.318750,0.050000,0.050000},{0.193750,0.318750,0.025000,0.025000},{0.193750,0.318750,0.050000,0.050000},{0.206250,0.318750,0.025000,0.025000},{0.206250,0.318750,0.050000,0.050000},{0.218750,0.318750,0.025000,0.025000},{0.218750,0.318750,0.050000,0.050000},{0.231250,0.318750,0.025000,0.025000},{0.231250,0.318750,0.050000,0.050000},{0.243750,0.318750,0.025000,0.025000},{0.243750,0.318750,0.050000,0.050000},{0.256250,0.318750,0.025000,0.025000},{0.256250,0.318750,0.050000,0.050000},{0.268750,0.318750,0.025000,0.025000},{0.268750,0.318750,0.050000,0.050000},{0.281250,0.318750,0.025000,0.025000},{0.281250,0.318750,0.050000,0.050000},{0.293750,0.318750,0.025000,0.025000},{0.293750,0.318750,0.050000,0.050000},{0.306250,0.318750,0.025000,0.025000},{0.306250,0.318750,0.050000,0.050000},{0.318750,0.318750,0.025000,0.025000},{0.318750,0.318750,0.050000,0.050000},{0.331250,0.318750,0.025000,0.025000},{0.331250,0.318750,0.050000,0.050000},{0.343750,0.318750,0.025000,0.025000},{0.343750,0.318750,0.050000,0.050000},{0.356250,0.318750,0.025000,0.025000},{0.356250,0.318750,0.050000,0.050000},{0.368750,0.318750,0.025000,0.025000},{0.368750,0.318750,0.050000,0.050000},{0.381250,0.318750,0.025000,0.025000},{0.381250,0.318750,0.050000,0.050000},{0.393750,0.318750,0.025000,0.025000},{0.393750,0.318750,0.050000,0.050000},{0.406250,0.318750,0.025000,0.025000},{0.406250,0.318750,0.050000,0.050000},{0.418750,0.318750,0.025000,0.025000},{0.418750,0.318750,0.050000,0.050000},{0.431250,0.318750,0.025000,0.025000},{0.431250,0.318750,0.050000,0.050000},{0.443750,0.318750,0.025000,0.025000},{0.443750,0.318750,0.050000,0.050000},{0.456250,0.318750,0.025000,0.025000},{0.456250,0.318750,0.050000,0.050000},{0.468750,0.318750,0.025000,0.025000},{0.468750,0.318750,0.050000,0.050000},{0.481250,0.318750,0.025000,0.025000},{0.481250,0.318750,0.050000,0.050000},{0.493750,0.318750,0.025000,0.025000},{0.493750,0.318750,0.050000,0.050000},{0.506250,0.318750,0.025000,0.025000},{0.506250,0.318750,0.050000,0.050000},{0.518750,0.318750,0.025000,0.025000},{0.518750,0.318750,0.050000,0.050000},{0.531250,0.318750,0.025000,0.025000},{0.531250,0.318750,0.050000,0.050000},{0.543750,0.318750,0.025000,0.025000},{0.543750,0.318750,0.050000,0.050000},{0.556250,0.318750,0.025000,0.025000},{0.556250,0.318750,0.050000,0.050000},{0.568750,0.318750,0.025000,0.025000},{0.568750,0.318750,0.050000,0.050000},{0.581250,0.318750,0.025000,0.025000},{0.581250,0.318750,0.050000,0.050000},{0.593750,0.318750,0.025000,0.025000},{0.593750,0.318750,0.050000,0.050000},{0.606250,0.318750,0.025000,0.025000},{0.606250,0.318750,0.050000,0.050000},{0.618750,0.318750,0.025000,0.025000},{0.618750,0.318750,0.050000,0.050000},{0.631250,0.318750,0.025000,0.025000},{0.631250,0.318750,0.050000,0.050000},{0.643750,0.318750,0.025000,0.025000},{0.643750,0.318750,0.050000,0.050000},{0.656250,0.318750,0.025000,0.025000},{0.656250,0.318750,0.050000,0.050000},{0.668750,0.318750,0.025000,0.025000},{0.668750,0.318750,0.050000,0.050000},{0.681250,0.318750,0.025000,0.025000},{0.681250,0.318750,0.050000,0.050000},{0.693750,0.318750,0.025000,0.025000},{0.693750,0.318750,0.050000,0.050000},{0.706250,0.318750,0.025000,0.025000},{0.706250,0.318750,0.050000,0.050000},{0.718750,0.318750,0.025000,0.025000},{0.718750,0.318750,0.050000,0.050000},{0.731250,0.318750,0.025000,0.025000},{0.731250,0.318750,0.050000,0.050000},{0.743750,0.318750,0.025000,0.025000},{0.743750,0.318750,0.050000,0.050000},{0.756250,0.318750,0.025000,0.025000},{0.756250,0.318750,0.050000,0.050000},{0.768750,0.318750,0.025000,0.025000},{0.768750,0.318750,0.050000,0.050000},{0.781250,0.318750,0.025000,0.025000},{0.781250,0.318750,0.050000,0.050000},{0.793750,0.318750,0.025000,0.025000},{0.793750,0.318750,0.050000,0.050000},{0.806250,0.318750,0.025000,0.025000},{0.806250,0.318750,0.050000,0.050000},{0.818750,0.318750,0.025000,0.025000},{0.818750,0.318750,0.050000,0.050000},{0.831250,0.318750,0.025000,0.025000},{0.831250,0.318750,0.050000,0.050000},{0.843750,0.318750,0.025000,0.025000},{0.843750,0.318750,0.050000,0.050000},{0.856250,0.318750,0.025000,0.025000},{0.856250,0.318750,0.050000,0.050000},{0.868750,0.318750,0.025000,0.025000},{0.868750,0.318750,0.050000,0.050000},{0.881250,0.318750,0.025000,0.025000},{0.881250,0.318750,0.050000,0.050000},{0.893750,0.318750,0.025000,0.025000},{0.893750,0.318750,0.050000,0.050000},{0.906250,0.318750,0.025000,0.025000},{0.906250,0.318750,0.050000,0.050000},{0.918750,0.318750,0.025000,0.025000},{0.918750,0.318750,0.050000,0.050000},{0.931250,0.318750,0.025000,0.025000},{0.931250,0.318750,0.050000,0.050000},{0.943750,0.318750,0.025000,0.025000},{0.943750,0.318750,0.050000,0.050000},{0.956250,0.318750,0.025000,0.025000},{0.956250,0.318750,0.050000,0.050000},{0.968750,0.318750,0.025000,0.025000},{0.968750,0.318750,0.050000,0.050000},{0.981250,0.318750,0.025000,0.025000},{0.981250,0.318750,0.050000,0.050000},{0.993750,0.318750,0.025000,0.025000},{0.993750,0.318750,0.050000,0.050000},{0.006250,0.331250,0.025000,0.025000},{0.006250,0.331250,0.050000,0.050000},{0.018750,0.331250,0.025000,0.025000},{0.018750,0.331250,0.050000,0.050000},{0.031250,0.331250,0.025000,0.025000},{0.031250,0.331250,0.050000,0.050000},{0.043750,0.331250,0.025000,0.025000},{0.043750,0.331250,0.050000,0.050000},{0.056250,0.331250,0.025000,0.025000},{0.056250,0.331250,0.050000,0.050000},{0.068750,0.331250,0.025000,0.025000},{0.068750,0.331250,0.050000,0.050000},{0.081250,0.331250,0.025000,0.025000},{0.081250,0.331250,0.050000,0.050000},{0.093750,0.331250,0.025000,0.025000},{0.093750,0.331250,0.050000,0.050000},{0.106250,0.331250,0.025000,0.025000},{0.106250,0.331250,0.050000,0.050000},{0.118750,0.331250,0.025000,0.025000},{0.118750,0.331250,0.050000,0.050000},{0.131250,0.331250,0.025000,0.025000},{0.131250,0.331250,0.050000,0.050000},{0.143750,0.331250,0.025000,0.025000},{0.143750,0.331250,0.050000,0.050000},{0.156250,0.331250,0.025000,0.025000},{0.156250,0.331250,0.050000,0.050000},{0.168750,0.331250,0.025000,0.025000},{0.168750,0.331250,0.050000,0.050000},{0.181250,0.331250,0.025000,0.025000},{0.181250,0.331250,0.050000,0.050000},{0.193750,0.331250,0.025000,0.025000},{0.193750,0.331250,0.050000,0.050000},{0.206250,0.331250,0.025000,0.025000},{0.206250,0.331250,0.050000,0.050000},{0.218750,0.331250,0.025000,0.025000},{0.218750,0.331250,0.050000,0.050000},{0.231250,0.331250,0.025000,0.025000},{0.231250,0.331250,0.050000,0.050000},{0.243750,0.331250,0.025000,0.025000},{0.243750,0.331250,0.050000,0.050000},{0.256250,0.331250,0.025000,0.025000},{0.256250,0.331250,0.050000,0.050000},{0.268750,0.331250,0.025000,0.025000},{0.268750,0.331250,0.050000,0.050000},{0.281250,0.331250,0.025000,0.025000},{0.281250,0.331250,0.050000,0.050000},{0.293750,0.331250,0.025000,0.025000},{0.293750,0.331250,0.050000,0.050000},{0.306250,0.331250,0.025000,0.025000},{0.306250,0.331250,0.050000,0.050000},{0.318750,0.331250,0.025000,0.025000},{0.318750,0.331250,0.050000,0.050000},{0.331250,0.331250,0.025000,0.025000},{0.331250,0.331250,0.050000,0.050000},{0.343750,0.331250,0.025000,0.025000},{0.343750,0.331250,0.050000,0.050000},{0.356250,0.331250,0.025000,0.025000},{0.356250,0.331250,0.050000,0.050000},{0.368750,0.331250,0.025000,0.025000},{0.368750,0.331250,0.050000,0.050000},{0.381250,0.331250,0.025000,0.025000},{0.381250,0.331250,0.050000,0.050000},{0.393750,0.331250,0.025000,0.025000},{0.393750,0.331250,0.050000,0.050000},{0.406250,0.331250,0.025000,0.025000},{0.406250,0.331250,0.050000,0.050000},{0.418750,0.331250,0.025000,0.025000},{0.418750,0.331250,0.050000,0.050000},{0.431250,0.331250,0.025000,0.025000},{0.431250,0.331250,0.050000,0.050000},{0.443750,0.331250,0.025000,0.025000},{0.443750,0.331250,0.050000,0.050000},{0.456250,0.331250,0.025000,0.025000},{0.456250,0.331250,0.050000,0.050000},{0.468750,0.331250,0.025000,0.025000},{0.468750,0.331250,0.050000,0.050000},{0.481250,0.331250,0.025000,0.025000},{0.481250,0.331250,0.050000,0.050000},{0.493750,0.331250,0.025000,0.025000},{0.493750,0.331250,0.050000,0.050000},{0.506250,0.331250,0.025000,0.025000},{0.506250,0.331250,0.050000,0.050000},{0.518750,0.331250,0.025000,0.025000},{0.518750,0.331250,0.050000,0.050000},{0.531250,0.331250,0.025000,0.025000},{0.531250,0.331250,0.050000,0.050000},{0.543750,0.331250,0.025000,0.025000},{0.543750,0.331250,0.050000,0.050000},{0.556250,0.331250,0.025000,0.025000},{0.556250,0.331250,0.050000,0.050000},{0.568750,0.331250,0.025000,0.025000},{0.568750,0.331250,0.050000,0.050000},{0.581250,0.331250,0.025000,0.025000},{0.581250,0.331250,0.050000,0.050000},{0.593750,0.331250,0.025000,0.025000},{0.593750,0.331250,0.050000,0.050000},{0.606250,0.331250,0.025000,0.025000},{0.606250,0.331250,0.050000,0.050000},{0.618750,0.331250,0.025000,0.025000},{0.618750,0.331250,0.050000,0.050000},{0.631250,0.331250,0.025000,0.025000},{0.631250,0.331250,0.050000,0.050000},{0.643750,0.331250,0.025000,0.025000},{0.643750,0.331250,0.050000,0.050000},{0.656250,0.331250,0.025000,0.025000},{0.656250,0.331250,0.050000,0.050000},{0.668750,0.331250,0.025000,0.025000},{0.668750,0.331250,0.050000,0.050000},{0.681250,0.331250,0.025000,0.025000},{0.681250,0.331250,0.050000,0.050000},{0.693750,0.331250,0.025000,0.025000},{0.693750,0.331250,0.050000,0.050000},{0.706250,0.331250,0.025000,0.025000},{0.706250,0.331250,0.050000,0.050000},{0.718750,0.331250,0.025000,0.025000},{0.718750,0.331250,0.050000,0.050000},{0.731250,0.331250,0.025000,0.025000},{0.731250,0.331250,0.050000,0.050000},{0.743750,0.331250,0.025000,0.025000},{0.743750,0.331250,0.050000,0.050000},{0.756250,0.331250,0.025000,0.025000},{0.756250,0.331250,0.050000,0.050000},{0.768750,0.331250,0.025000,0.025000},{0.768750,0.331250,0.050000,0.050000},{0.781250,0.331250,0.025000,0.025000},{0.781250,0.331250,0.050000,0.050000},{0.793750,0.331250,0.025000,0.025000},{0.793750,0.331250,0.050000,0.050000},{0.806250,0.331250,0.025000,0.025000},{0.806250,0.331250,0.050000,0.050000},{0.818750,0.331250,0.025000,0.025000},{0.818750,0.331250,0.050000,0.050000},{0.831250,0.331250,0.025000,0.025000},{0.831250,0.331250,0.050000,0.050000},{0.843750,0.331250,0.025000,0.025000},{0.843750,0.331250,0.050000,0.050000},{0.856250,0.331250,0.025000,0.025000},{0.856250,0.331250,0.050000,0.050000},{0.868750,0.331250,0.025000,0.025000},{0.868750,0.331250,0.050000,0.050000},{0.881250,0.331250,0.025000,0.025000},{0.881250,0.331250,0.050000,0.050000},{0.893750,0.331250,0.025000,0.025000},{0.893750,0.331250,0.050000,0.050000},{0.906250,0.331250,0.025000,0.025000},{0.906250,0.331250,0.050000,0.050000},{0.918750,0.331250,0.025000,0.025000},{0.918750,0.331250,0.050000,0.050000},{0.931250,0.331250,0.025000,0.025000},{0.931250,0.331250,0.050000,0.050000},{0.943750,0.331250,0.025000,0.025000},{0.943750,0.331250,0.050000,0.050000},{0.956250,0.331250,0.025000,0.025000},{0.956250,0.331250,0.050000,0.050000},{0.968750,0.331250,0.025000,0.025000},{0.968750,0.331250,0.050000,0.050000},{0.981250,0.331250,0.025000,0.025000},{0.981250,0.331250,0.050000,0.050000},{0.993750,0.331250,0.025000,0.025000},{0.993750,0.331250,0.050000,0.050000},{0.006250,0.343750,0.025000,0.025000},{0.006250,0.343750,0.050000,0.050000},{0.018750,0.343750,0.025000,0.025000},{0.018750,0.343750,0.050000,0.050000},{0.031250,0.343750,0.025000,0.025000},{0.031250,0.343750,0.050000,0.050000},{0.043750,0.343750,0.025000,0.025000},{0.043750,0.343750,0.050000,0.050000},{0.056250,0.343750,0.025000,0.025000},{0.056250,0.343750,0.050000,0.050000},{0.068750,0.343750,0.025000,0.025000},{0.068750,0.343750,0.050000,0.050000},{0.081250,0.343750,0.025000,0.025000},{0.081250,0.343750,0.050000,0.050000},{0.093750,0.343750,0.025000,0.025000},{0.093750,0.343750,0.050000,0.050000},{0.106250,0.343750,0.025000,0.025000},{0.106250,0.343750,0.050000,0.050000},{0.118750,0.343750,0.025000,0.025000},{0.118750,0.343750,0.050000,0.050000},{0.131250,0.343750,0.025000,0.025000},{0.131250,0.343750,0.050000,0.050000},{0.143750,0.343750,0.025000,0.025000},{0.143750,0.343750,0.050000,0.050000},{0.156250,0.343750,0.025000,0.025000},{0.156250,0.343750,0.050000,0.050000},{0.168750,0.343750,0.025000,0.025000},{0.168750,0.343750,0.050000,0.050000},{0.181250,0.343750,0.025000,0.025000},{0.181250,0.343750,0.050000,0.050000},{0.193750,0.343750,0.025000,0.025000},{0.193750,0.343750,0.050000,0.050000},{0.206250,0.343750,0.025000,0.025000},{0.206250,0.343750,0.050000,0.050000},{0.218750,0.343750,0.025000,0.025000},{0.218750,0.343750,0.050000,0.050000},{0.231250,0.343750,0.025000,0.025000},{0.231250,0.343750,0.050000,0.050000},{0.243750,0.343750,0.025000,0.025000},{0.243750,0.343750,0.050000,0.050000},{0.256250,0.343750,0.025000,0.025000},{0.256250,0.343750,0.050000,0.050000},{0.268750,0.343750,0.025000,0.025000},{0.268750,0.343750,0.050000,0.050000},{0.281250,0.343750,0.025000,0.025000},{0.281250,0.343750,0.050000,0.050000},{0.293750,0.343750,0.025000,0.025000},{0.293750,0.343750,0.050000,0.050000},{0.306250,0.343750,0.025000,0.025000},{0.306250,0.343750,0.050000,0.050000},{0.318750,0.343750,0.025000,0.025000},{0.318750,0.343750,0.050000,0.050000},{0.331250,0.343750,0.025000,0.025000},{0.331250,0.343750,0.050000,0.050000},{0.343750,0.343750,0.025000,0.025000},{0.343750,0.343750,0.050000,0.050000},{0.356250,0.343750,0.025000,0.025000},{0.356250,0.343750,0.050000,0.050000},{0.368750,0.343750,0.025000,0.025000},{0.368750,0.343750,0.050000,0.050000},{0.381250,0.343750,0.025000,0.025000},{0.381250,0.343750,0.050000,0.050000},{0.393750,0.343750,0.025000,0.025000},{0.393750,0.343750,0.050000,0.050000},{0.406250,0.343750,0.025000,0.025000},{0.406250,0.343750,0.050000,0.050000},{0.418750,0.343750,0.025000,0.025000},{0.418750,0.343750,0.050000,0.050000},{0.431250,0.343750,0.025000,0.025000},{0.431250,0.343750,0.050000,0.050000},{0.443750,0.343750,0.025000,0.025000},{0.443750,0.343750,0.050000,0.050000},{0.456250,0.343750,0.025000,0.025000},{0.456250,0.343750,0.050000,0.050000},{0.468750,0.343750,0.025000,0.025000},{0.468750,0.343750,0.050000,0.050000},{0.481250,0.343750,0.025000,0.025000},{0.481250,0.343750,0.050000,0.050000},{0.493750,0.343750,0.025000,0.025000},{0.493750,0.343750,0.050000,0.050000},{0.506250,0.343750,0.025000,0.025000},{0.506250,0.343750,0.050000,0.050000},{0.518750,0.343750,0.025000,0.025000},{0.518750,0.343750,0.050000,0.050000},{0.531250,0.343750,0.025000,0.025000},{0.531250,0.343750,0.050000,0.050000},{0.543750,0.343750,0.025000,0.025000},{0.543750,0.343750,0.050000,0.050000},{0.556250,0.343750,0.025000,0.025000},{0.556250,0.343750,0.050000,0.050000},{0.568750,0.343750,0.025000,0.025000},{0.568750,0.343750,0.050000,0.050000},{0.581250,0.343750,0.025000,0.025000},{0.581250,0.343750,0.050000,0.050000},{0.593750,0.343750,0.025000,0.025000},{0.593750,0.343750,0.050000,0.050000},{0.606250,0.343750,0.025000,0.025000},{0.606250,0.343750,0.050000,0.050000},{0.618750,0.343750,0.025000,0.025000},{0.618750,0.343750,0.050000,0.050000},{0.631250,0.343750,0.025000,0.025000},{0.631250,0.343750,0.050000,0.050000},{0.643750,0.343750,0.025000,0.025000},{0.643750,0.343750,0.050000,0.050000},{0.656250,0.343750,0.025000,0.025000},{0.656250,0.343750,0.050000,0.050000},{0.668750,0.343750,0.025000,0.025000},{0.668750,0.343750,0.050000,0.050000},{0.681250,0.343750,0.025000,0.025000},{0.681250,0.343750,0.050000,0.050000},{0.693750,0.343750,0.025000,0.025000},{0.693750,0.343750,0.050000,0.050000},{0.706250,0.343750,0.025000,0.025000},{0.706250,0.343750,0.050000,0.050000},{0.718750,0.343750,0.025000,0.025000},{0.718750,0.343750,0.050000,0.050000},{0.731250,0.343750,0.025000,0.025000},{0.731250,0.343750,0.050000,0.050000},{0.743750,0.343750,0.025000,0.025000},{0.743750,0.343750,0.050000,0.050000},{0.756250,0.343750,0.025000,0.025000},{0.756250,0.343750,0.050000,0.050000},{0.768750,0.343750,0.025000,0.025000},{0.768750,0.343750,0.050000,0.050000},{0.781250,0.343750,0.025000,0.025000},{0.781250,0.343750,0.050000,0.050000},{0.793750,0.343750,0.025000,0.025000},{0.793750,0.343750,0.050000,0.050000},{0.806250,0.343750,0.025000,0.025000},{0.806250,0.343750,0.050000,0.050000},{0.818750,0.343750,0.025000,0.025000},{0.818750,0.343750,0.050000,0.050000},{0.831250,0.343750,0.025000,0.025000},{0.831250,0.343750,0.050000,0.050000},{0.843750,0.343750,0.025000,0.025000},{0.843750,0.343750,0.050000,0.050000},{0.856250,0.343750,0.025000,0.025000},{0.856250,0.343750,0.050000,0.050000},{0.868750,0.343750,0.025000,0.025000},{0.868750,0.343750,0.050000,0.050000},{0.881250,0.343750,0.025000,0.025000},{0.881250,0.343750,0.050000,0.050000},{0.893750,0.343750,0.025000,0.025000},{0.893750,0.343750,0.050000,0.050000},{0.906250,0.343750,0.025000,0.025000},{0.906250,0.343750,0.050000,0.050000},{0.918750,0.343750,0.025000,0.025000},{0.918750,0.343750,0.050000,0.050000},{0.931250,0.343750,0.025000,0.025000},{0.931250,0.343750,0.050000,0.050000},{0.943750,0.343750,0.025000,0.025000},{0.943750,0.343750,0.050000,0.050000},{0.956250,0.343750,0.025000,0.025000},{0.956250,0.343750,0.050000,0.050000},{0.968750,0.343750,0.025000,0.025000},{0.968750,0.343750,0.050000,0.050000},{0.981250,0.343750,0.025000,0.025000},{0.981250,0.343750,0.050000,0.050000},{0.993750,0.343750,0.025000,0.025000},{0.993750,0.343750,0.050000,0.050000},{0.006250,0.356250,0.025000,0.025000},{0.006250,0.356250,0.050000,0.050000},{0.018750,0.356250,0.025000,0.025000},{0.018750,0.356250,0.050000,0.050000},{0.031250,0.356250,0.025000,0.025000},{0.031250,0.356250,0.050000,0.050000},{0.043750,0.356250,0.025000,0.025000},{0.043750,0.356250,0.050000,0.050000},{0.056250,0.356250,0.025000,0.025000},{0.056250,0.356250,0.050000,0.050000},{0.068750,0.356250,0.025000,0.025000},{0.068750,0.356250,0.050000,0.050000},{0.081250,0.356250,0.025000,0.025000},{0.081250,0.356250,0.050000,0.050000},{0.093750,0.356250,0.025000,0.025000},{0.093750,0.356250,0.050000,0.050000},{0.106250,0.356250,0.025000,0.025000},{0.106250,0.356250,0.050000,0.050000},{0.118750,0.356250,0.025000,0.025000},{0.118750,0.356250,0.050000,0.050000},{0.131250,0.356250,0.025000,0.025000},{0.131250,0.356250,0.050000,0.050000},{0.143750,0.356250,0.025000,0.025000},{0.143750,0.356250,0.050000,0.050000},{0.156250,0.356250,0.025000,0.025000},{0.156250,0.356250,0.050000,0.050000},{0.168750,0.356250,0.025000,0.025000},{0.168750,0.356250,0.050000,0.050000},{0.181250,0.356250,0.025000,0.025000},{0.181250,0.356250,0.050000,0.050000},{0.193750,0.356250,0.025000,0.025000},{0.193750,0.356250,0.050000,0.050000},{0.206250,0.356250,0.025000,0.025000},{0.206250,0.356250,0.050000,0.050000},{0.218750,0.356250,0.025000,0.025000},{0.218750,0.356250,0.050000,0.050000},{0.231250,0.356250,0.025000,0.025000},{0.231250,0.356250,0.050000,0.050000},{0.243750,0.356250,0.025000,0.025000},{0.243750,0.356250,0.050000,0.050000},{0.256250,0.356250,0.025000,0.025000},{0.256250,0.356250,0.050000,0.050000},{0.268750,0.356250,0.025000,0.025000},{0.268750,0.356250,0.050000,0.050000},{0.281250,0.356250,0.025000,0.025000},{0.281250,0.356250,0.050000,0.050000},{0.293750,0.356250,0.025000,0.025000},{0.293750,0.356250,0.050000,0.050000},{0.306250,0.356250,0.025000,0.025000},{0.306250,0.356250,0.050000,0.050000},{0.318750,0.356250,0.025000,0.025000},{0.318750,0.356250,0.050000,0.050000},{0.331250,0.356250,0.025000,0.025000},{0.331250,0.356250,0.050000,0.050000},{0.343750,0.356250,0.025000,0.025000},{0.343750,0.356250,0.050000,0.050000},{0.356250,0.356250,0.025000,0.025000},{0.356250,0.356250,0.050000,0.050000},{0.368750,0.356250,0.025000,0.025000},{0.368750,0.356250,0.050000,0.050000},{0.381250,0.356250,0.025000,0.025000},{0.381250,0.356250,0.050000,0.050000},{0.393750,0.356250,0.025000,0.025000},{0.393750,0.356250,0.050000,0.050000},{0.406250,0.356250,0.025000,0.025000},{0.406250,0.356250,0.050000,0.050000},{0.418750,0.356250,0.025000,0.025000},{0.418750,0.356250,0.050000,0.050000},{0.431250,0.356250,0.025000,0.025000},{0.431250,0.356250,0.050000,0.050000},{0.443750,0.356250,0.025000,0.025000},{0.443750,0.356250,0.050000,0.050000},{0.456250,0.356250,0.025000,0.025000},{0.456250,0.356250,0.050000,0.050000},{0.468750,0.356250,0.025000,0.025000},{0.468750,0.356250,0.050000,0.050000},{0.481250,0.356250,0.025000,0.025000},{0.481250,0.356250,0.050000,0.050000},{0.493750,0.356250,0.025000,0.025000},{0.493750,0.356250,0.050000,0.050000},{0.506250,0.356250,0.025000,0.025000},{0.506250,0.356250,0.050000,0.050000},{0.518750,0.356250,0.025000,0.025000},{0.518750,0.356250,0.050000,0.050000},{0.531250,0.356250,0.025000,0.025000},{0.531250,0.356250,0.050000,0.050000},{0.543750,0.356250,0.025000,0.025000},{0.543750,0.356250,0.050000,0.050000},{0.556250,0.356250,0.025000,0.025000},{0.556250,0.356250,0.050000,0.050000},{0.568750,0.356250,0.025000,0.025000},{0.568750,0.356250,0.050000,0.050000},{0.581250,0.356250,0.025000,0.025000},{0.581250,0.356250,0.050000,0.050000},{0.593750,0.356250,0.025000,0.025000},{0.593750,0.356250,0.050000,0.050000},{0.606250,0.356250,0.025000,0.025000},{0.606250,0.356250,0.050000,0.050000},{0.618750,0.356250,0.025000,0.025000},{0.618750,0.356250,0.050000,0.050000},{0.631250,0.356250,0.025000,0.025000},{0.631250,0.356250,0.050000,0.050000},{0.643750,0.356250,0.025000,0.025000},{0.643750,0.356250,0.050000,0.050000},{0.656250,0.356250,0.025000,0.025000},{0.656250,0.356250,0.050000,0.050000},{0.668750,0.356250,0.025000,0.025000},{0.668750,0.356250,0.050000,0.050000},{0.681250,0.356250,0.025000,0.025000},{0.681250,0.356250,0.050000,0.050000},{0.693750,0.356250,0.025000,0.025000},{0.693750,0.356250,0.050000,0.050000},{0.706250,0.356250,0.025000,0.025000},{0.706250,0.356250,0.050000,0.050000},{0.718750,0.356250,0.025000,0.025000},{0.718750,0.356250,0.050000,0.050000},{0.731250,0.356250,0.025000,0.025000},{0.731250,0.356250,0.050000,0.050000},{0.743750,0.356250,0.025000,0.025000},{0.743750,0.356250,0.050000,0.050000},{0.756250,0.356250,0.025000,0.025000},{0.756250,0.356250,0.050000,0.050000},{0.768750,0.356250,0.025000,0.025000},{0.768750,0.356250,0.050000,0.050000},{0.781250,0.356250,0.025000,0.025000},{0.781250,0.356250,0.050000,0.050000},{0.793750,0.356250,0.025000,0.025000},{0.793750,0.356250,0.050000,0.050000},{0.806250,0.356250,0.025000,0.025000},{0.806250,0.356250,0.050000,0.050000},{0.818750,0.356250,0.025000,0.025000},{0.818750,0.356250,0.050000,0.050000},{0.831250,0.356250,0.025000,0.025000},{0.831250,0.356250,0.050000,0.050000},{0.843750,0.356250,0.025000,0.025000},{0.843750,0.356250,0.050000,0.050000},{0.856250,0.356250,0.025000,0.025000},{0.856250,0.356250,0.050000,0.050000},{0.868750,0.356250,0.025000,0.025000},{0.868750,0.356250,0.050000,0.050000},{0.881250,0.356250,0.025000,0.025000},{0.881250,0.356250,0.050000,0.050000},{0.893750,0.356250,0.025000,0.025000},{0.893750,0.356250,0.050000,0.050000},{0.906250,0.356250,0.025000,0.025000},{0.906250,0.356250,0.050000,0.050000},{0.918750,0.356250,0.025000,0.025000},{0.918750,0.356250,0.050000,0.050000},{0.931250,0.356250,0.025000,0.025000},{0.931250,0.356250,0.050000,0.050000},{0.943750,0.356250,0.025000,0.025000},{0.943750,0.356250,0.050000,0.050000},{0.956250,0.356250,0.025000,0.025000},{0.956250,0.356250,0.050000,0.050000},{0.968750,0.356250,0.025000,0.025000},{0.968750,0.356250,0.050000,0.050000},{0.981250,0.356250,0.025000,0.025000},{0.981250,0.356250,0.050000,0.050000},{0.993750,0.356250,0.025000,0.025000},{0.993750,0.356250,0.050000,0.050000},{0.006250,0.368750,0.025000,0.025000},{0.006250,0.368750,0.050000,0.050000},{0.018750,0.368750,0.025000,0.025000},{0.018750,0.368750,0.050000,0.050000},{0.031250,0.368750,0.025000,0.025000},{0.031250,0.368750,0.050000,0.050000},{0.043750,0.368750,0.025000,0.025000},{0.043750,0.368750,0.050000,0.050000},{0.056250,0.368750,0.025000,0.025000},{0.056250,0.368750,0.050000,0.050000},{0.068750,0.368750,0.025000,0.025000},{0.068750,0.368750,0.050000,0.050000},{0.081250,0.368750,0.025000,0.025000},{0.081250,0.368750,0.050000,0.050000},{0.093750,0.368750,0.025000,0.025000},{0.093750,0.368750,0.050000,0.050000},{0.106250,0.368750,0.025000,0.025000},{0.106250,0.368750,0.050000,0.050000},{0.118750,0.368750,0.025000,0.025000},{0.118750,0.368750,0.050000,0.050000},{0.131250,0.368750,0.025000,0.025000},{0.131250,0.368750,0.050000,0.050000},{0.143750,0.368750,0.025000,0.025000},{0.143750,0.368750,0.050000,0.050000},{0.156250,0.368750,0.025000,0.025000},{0.156250,0.368750,0.050000,0.050000},{0.168750,0.368750,0.025000,0.025000},{0.168750,0.368750,0.050000,0.050000},{0.181250,0.368750,0.025000,0.025000},{0.181250,0.368750,0.050000,0.050000},{0.193750,0.368750,0.025000,0.025000},{0.193750,0.368750,0.050000,0.050000},{0.206250,0.368750,0.025000,0.025000},{0.206250,0.368750,0.050000,0.050000},{0.218750,0.368750,0.025000,0.025000},{0.218750,0.368750,0.050000,0.050000},{0.231250,0.368750,0.025000,0.025000},{0.231250,0.368750,0.050000,0.050000},{0.243750,0.368750,0.025000,0.025000},{0.243750,0.368750,0.050000,0.050000},{0.256250,0.368750,0.025000,0.025000},{0.256250,0.368750,0.050000,0.050000},{0.268750,0.368750,0.025000,0.025000},{0.268750,0.368750,0.050000,0.050000},{0.281250,0.368750,0.025000,0.025000},{0.281250,0.368750,0.050000,0.050000},{0.293750,0.368750,0.025000,0.025000},{0.293750,0.368750,0.050000,0.050000},{0.306250,0.368750,0.025000,0.025000},{0.306250,0.368750,0.050000,0.050000},{0.318750,0.368750,0.025000,0.025000},{0.318750,0.368750,0.050000,0.050000},{0.331250,0.368750,0.025000,0.025000},{0.331250,0.368750,0.050000,0.050000},{0.343750,0.368750,0.025000,0.025000},{0.343750,0.368750,0.050000,0.050000},{0.356250,0.368750,0.025000,0.025000},{0.356250,0.368750,0.050000,0.050000},{0.368750,0.368750,0.025000,0.025000},{0.368750,0.368750,0.050000,0.050000},{0.381250,0.368750,0.025000,0.025000},{0.381250,0.368750,0.050000,0.050000},{0.393750,0.368750,0.025000,0.025000},{0.393750,0.368750,0.050000,0.050000},{0.406250,0.368750,0.025000,0.025000},{0.406250,0.368750,0.050000,0.050000},{0.418750,0.368750,0.025000,0.025000},{0.418750,0.368750,0.050000,0.050000},{0.431250,0.368750,0.025000,0.025000},{0.431250,0.368750,0.050000,0.050000},{0.443750,0.368750,0.025000,0.025000},{0.443750,0.368750,0.050000,0.050000},{0.456250,0.368750,0.025000,0.025000},{0.456250,0.368750,0.050000,0.050000},{0.468750,0.368750,0.025000,0.025000},{0.468750,0.368750,0.050000,0.050000},{0.481250,0.368750,0.025000,0.025000},{0.481250,0.368750,0.050000,0.050000},{0.493750,0.368750,0.025000,0.025000},{0.493750,0.368750,0.050000,0.050000},{0.506250,0.368750,0.025000,0.025000},{0.506250,0.368750,0.050000,0.050000},{0.518750,0.368750,0.025000,0.025000},{0.518750,0.368750,0.050000,0.050000},{0.531250,0.368750,0.025000,0.025000},{0.531250,0.368750,0.050000,0.050000},{0.543750,0.368750,0.025000,0.025000},{0.543750,0.368750,0.050000,0.050000},{0.556250,0.368750,0.025000,0.025000},{0.556250,0.368750,0.050000,0.050000},{0.568750,0.368750,0.025000,0.025000},{0.568750,0.368750,0.050000,0.050000},{0.581250,0.368750,0.025000,0.025000},{0.581250,0.368750,0.050000,0.050000},{0.593750,0.368750,0.025000,0.025000},{0.593750,0.368750,0.050000,0.050000},{0.606250,0.368750,0.025000,0.025000},{0.606250,0.368750,0.050000,0.050000},{0.618750,0.368750,0.025000,0.025000},{0.618750,0.368750,0.050000,0.050000},{0.631250,0.368750,0.025000,0.025000},{0.631250,0.368750,0.050000,0.050000},{0.643750,0.368750,0.025000,0.025000},{0.643750,0.368750,0.050000,0.050000},{0.656250,0.368750,0.025000,0.025000},{0.656250,0.368750,0.050000,0.050000},{0.668750,0.368750,0.025000,0.025000},{0.668750,0.368750,0.050000,0.050000},{0.681250,0.368750,0.025000,0.025000},{0.681250,0.368750,0.050000,0.050000},{0.693750,0.368750,0.025000,0.025000},{0.693750,0.368750,0.050000,0.050000},{0.706250,0.368750,0.025000,0.025000},{0.706250,0.368750,0.050000,0.050000},{0.718750,0.368750,0.025000,0.025000},{0.718750,0.368750,0.050000,0.050000},{0.731250,0.368750,0.025000,0.025000},{0.731250,0.368750,0.050000,0.050000},{0.743750,0.368750,0.025000,0.025000},{0.743750,0.368750,0.050000,0.050000},{0.756250,0.368750,0.025000,0.025000},{0.756250,0.368750,0.050000,0.050000},{0.768750,0.368750,0.025000,0.025000},{0.768750,0.368750,0.050000,0.050000},{0.781250,0.368750,0.025000,0.025000},{0.781250,0.368750,0.050000,0.050000},{0.793750,0.368750,0.025000,0.025000},{0.793750,0.368750,0.050000,0.050000},{0.806250,0.368750,0.025000,0.025000},{0.806250,0.368750,0.050000,0.050000},{0.818750,0.368750,0.025000,0.025000},{0.818750,0.368750,0.050000,0.050000},{0.831250,0.368750,0.025000,0.025000},{0.831250,0.368750,0.050000,0.050000},{0.843750,0.368750,0.025000,0.025000},{0.843750,0.368750,0.050000,0.050000},{0.856250,0.368750,0.025000,0.025000},{0.856250,0.368750,0.050000,0.050000},{0.868750,0.368750,0.025000,0.025000},{0.868750,0.368750,0.050000,0.050000},{0.881250,0.368750,0.025000,0.025000},{0.881250,0.368750,0.050000,0.050000},{0.893750,0.368750,0.025000,0.025000},{0.893750,0.368750,0.050000,0.050000},{0.906250,0.368750,0.025000,0.025000},{0.906250,0.368750,0.050000,0.050000},{0.918750,0.368750,0.025000,0.025000},{0.918750,0.368750,0.050000,0.050000},{0.931250,0.368750,0.025000,0.025000},{0.931250,0.368750,0.050000,0.050000},{0.943750,0.368750,0.025000,0.025000},{0.943750,0.368750,0.050000,0.050000},{0.956250,0.368750,0.025000,0.025000},{0.956250,0.368750,0.050000,0.050000},{0.968750,0.368750,0.025000,0.025000},{0.968750,0.368750,0.050000,0.050000},{0.981250,0.368750,0.025000,0.025000},{0.981250,0.368750,0.050000,0.050000},{0.993750,0.368750,0.025000,0.025000},{0.993750,0.368750,0.050000,0.050000},{0.006250,0.381250,0.025000,0.025000},{0.006250,0.381250,0.050000,0.050000},{0.018750,0.381250,0.025000,0.025000},{0.018750,0.381250,0.050000,0.050000},{0.031250,0.381250,0.025000,0.025000},{0.031250,0.381250,0.050000,0.050000},{0.043750,0.381250,0.025000,0.025000},{0.043750,0.381250,0.050000,0.050000},{0.056250,0.381250,0.025000,0.025000},{0.056250,0.381250,0.050000,0.050000},{0.068750,0.381250,0.025000,0.025000},{0.068750,0.381250,0.050000,0.050000},{0.081250,0.381250,0.025000,0.025000},{0.081250,0.381250,0.050000,0.050000},{0.093750,0.381250,0.025000,0.025000},{0.093750,0.381250,0.050000,0.050000},{0.106250,0.381250,0.025000,0.025000},{0.106250,0.381250,0.050000,0.050000},{0.118750,0.381250,0.025000,0.025000},{0.118750,0.381250,0.050000,0.050000},{0.131250,0.381250,0.025000,0.025000},{0.131250,0.381250,0.050000,0.050000},{0.143750,0.381250,0.025000,0.025000},{0.143750,0.381250,0.050000,0.050000},{0.156250,0.381250,0.025000,0.025000},{0.156250,0.381250,0.050000,0.050000},{0.168750,0.381250,0.025000,0.025000},{0.168750,0.381250,0.050000,0.050000},{0.181250,0.381250,0.025000,0.025000},{0.181250,0.381250,0.050000,0.050000},{0.193750,0.381250,0.025000,0.025000},{0.193750,0.381250,0.050000,0.050000},{0.206250,0.381250,0.025000,0.025000},{0.206250,0.381250,0.050000,0.050000},{0.218750,0.381250,0.025000,0.025000},{0.218750,0.381250,0.050000,0.050000},{0.231250,0.381250,0.025000,0.025000},{0.231250,0.381250,0.050000,0.050000},{0.243750,0.381250,0.025000,0.025000},{0.243750,0.381250,0.050000,0.050000},{0.256250,0.381250,0.025000,0.025000},{0.256250,0.381250,0.050000,0.050000},{0.268750,0.381250,0.025000,0.025000},{0.268750,0.381250,0.050000,0.050000},{0.281250,0.381250,0.025000,0.025000},{0.281250,0.381250,0.050000,0.050000},{0.293750,0.381250,0.025000,0.025000},{0.293750,0.381250,0.050000,0.050000},{0.306250,0.381250,0.025000,0.025000},{0.306250,0.381250,0.050000,0.050000},{0.318750,0.381250,0.025000,0.025000},{0.318750,0.381250,0.050000,0.050000},{0.331250,0.381250,0.025000,0.025000},{0.331250,0.381250,0.050000,0.050000},{0.343750,0.381250,0.025000,0.025000},{0.343750,0.381250,0.050000,0.050000},{0.356250,0.381250,0.025000,0.025000},{0.356250,0.381250,0.050000,0.050000},{0.368750,0.381250,0.025000,0.025000},{0.368750,0.381250,0.050000,0.050000},{0.381250,0.381250,0.025000,0.025000},{0.381250,0.381250,0.050000,0.050000},{0.393750,0.381250,0.025000,0.025000},{0.393750,0.381250,0.050000,0.050000},{0.406250,0.381250,0.025000,0.025000},{0.406250,0.381250,0.050000,0.050000},{0.418750,0.381250,0.025000,0.025000},{0.418750,0.381250,0.050000,0.050000},{0.431250,0.381250,0.025000,0.025000},{0.431250,0.381250,0.050000,0.050000},{0.443750,0.381250,0.025000,0.025000},{0.443750,0.381250,0.050000,0.050000},{0.456250,0.381250,0.025000,0.025000},{0.456250,0.381250,0.050000,0.050000},{0.468750,0.381250,0.025000,0.025000},{0.468750,0.381250,0.050000,0.050000},{0.481250,0.381250,0.025000,0.025000},{0.481250,0.381250,0.050000,0.050000},{0.493750,0.381250,0.025000,0.025000},{0.493750,0.381250,0.050000,0.050000},{0.506250,0.381250,0.025000,0.025000},{0.506250,0.381250,0.050000,0.050000},{0.518750,0.381250,0.025000,0.025000},{0.518750,0.381250,0.050000,0.050000},{0.531250,0.381250,0.025000,0.025000},{0.531250,0.381250,0.050000,0.050000},{0.543750,0.381250,0.025000,0.025000},{0.543750,0.381250,0.050000,0.050000},{0.556250,0.381250,0.025000,0.025000},{0.556250,0.381250,0.050000,0.050000},{0.568750,0.381250,0.025000,0.025000},{0.568750,0.381250,0.050000,0.050000},{0.581250,0.381250,0.025000,0.025000},{0.581250,0.381250,0.050000,0.050000},{0.593750,0.381250,0.025000,0.025000},{0.593750,0.381250,0.050000,0.050000},{0.606250,0.381250,0.025000,0.025000},{0.606250,0.381250,0.050000,0.050000},{0.618750,0.381250,0.025000,0.025000},{0.618750,0.381250,0.050000,0.050000},{0.631250,0.381250,0.025000,0.025000},{0.631250,0.381250,0.050000,0.050000},{0.643750,0.381250,0.025000,0.025000},{0.643750,0.381250,0.050000,0.050000},{0.656250,0.381250,0.025000,0.025000},{0.656250,0.381250,0.050000,0.050000},{0.668750,0.381250,0.025000,0.025000},{0.668750,0.381250,0.050000,0.050000},{0.681250,0.381250,0.025000,0.025000},{0.681250,0.381250,0.050000,0.050000},{0.693750,0.381250,0.025000,0.025000},{0.693750,0.381250,0.050000,0.050000},{0.706250,0.381250,0.025000,0.025000},{0.706250,0.381250,0.050000,0.050000},{0.718750,0.381250,0.025000,0.025000},{0.718750,0.381250,0.050000,0.050000},{0.731250,0.381250,0.025000,0.025000},{0.731250,0.381250,0.050000,0.050000},{0.743750,0.381250,0.025000,0.025000},{0.743750,0.381250,0.050000,0.050000},{0.756250,0.381250,0.025000,0.025000},{0.756250,0.381250,0.050000,0.050000},{0.768750,0.381250,0.025000,0.025000},{0.768750,0.381250,0.050000,0.050000},{0.781250,0.381250,0.025000,0.025000},{0.781250,0.381250,0.050000,0.050000},{0.793750,0.381250,0.025000,0.025000},{0.793750,0.381250,0.050000,0.050000},{0.806250,0.381250,0.025000,0.025000},{0.806250,0.381250,0.050000,0.050000},{0.818750,0.381250,0.025000,0.025000},{0.818750,0.381250,0.050000,0.050000},{0.831250,0.381250,0.025000,0.025000},{0.831250,0.381250,0.050000,0.050000},{0.843750,0.381250,0.025000,0.025000},{0.843750,0.381250,0.050000,0.050000},{0.856250,0.381250,0.025000,0.025000},{0.856250,0.381250,0.050000,0.050000},{0.868750,0.381250,0.025000,0.025000},{0.868750,0.381250,0.050000,0.050000},{0.881250,0.381250,0.025000,0.025000},{0.881250,0.381250,0.050000,0.050000},{0.893750,0.381250,0.025000,0.025000},{0.893750,0.381250,0.050000,0.050000},{0.906250,0.381250,0.025000,0.025000},{0.906250,0.381250,0.050000,0.050000},{0.918750,0.381250,0.025000,0.025000},{0.918750,0.381250,0.050000,0.050000},{0.931250,0.381250,0.025000,0.025000},{0.931250,0.381250,0.050000,0.050000},{0.943750,0.381250,0.025000,0.025000},{0.943750,0.381250,0.050000,0.050000},{0.956250,0.381250,0.025000,0.025000},{0.956250,0.381250,0.050000,0.050000},{0.968750,0.381250,0.025000,0.025000},{0.968750,0.381250,0.050000,0.050000},{0.981250,0.381250,0.025000,0.025000},{0.981250,0.381250,0.050000,0.050000},{0.993750,0.381250,0.025000,0.025000},{0.993750,0.381250,0.050000,0.050000},{0.006250,0.393750,0.025000,0.025000},{0.006250,0.393750,0.050000,0.050000},{0.018750,0.393750,0.025000,0.025000},{0.018750,0.393750,0.050000,0.050000},{0.031250,0.393750,0.025000,0.025000},{0.031250,0.393750,0.050000,0.050000},{0.043750,0.393750,0.025000,0.025000},{0.043750,0.393750,0.050000,0.050000},{0.056250,0.393750,0.025000,0.025000},{0.056250,0.393750,0.050000,0.050000},{0.068750,0.393750,0.025000,0.025000},{0.068750,0.393750,0.050000,0.050000},{0.081250,0.393750,0.025000,0.025000},{0.081250,0.393750,0.050000,0.050000},{0.093750,0.393750,0.025000,0.025000},{0.093750,0.393750,0.050000,0.050000},{0.106250,0.393750,0.025000,0.025000},{0.106250,0.393750,0.050000,0.050000},{0.118750,0.393750,0.025000,0.025000},{0.118750,0.393750,0.050000,0.050000},{0.131250,0.393750,0.025000,0.025000},{0.131250,0.393750,0.050000,0.050000},{0.143750,0.393750,0.025000,0.025000},{0.143750,0.393750,0.050000,0.050000},{0.156250,0.393750,0.025000,0.025000},{0.156250,0.393750,0.050000,0.050000},{0.168750,0.393750,0.025000,0.025000},{0.168750,0.393750,0.050000,0.050000},{0.181250,0.393750,0.025000,0.025000},{0.181250,0.393750,0.050000,0.050000},{0.193750,0.393750,0.025000,0.025000},{0.193750,0.393750,0.050000,0.050000},{0.206250,0.393750,0.025000,0.025000},{0.206250,0.393750,0.050000,0.050000},{0.218750,0.393750,0.025000,0.025000},{0.218750,0.393750,0.050000,0.050000},{0.231250,0.393750,0.025000,0.025000},{0.231250,0.393750,0.050000,0.050000},{0.243750,0.393750,0.025000,0.025000},{0.243750,0.393750,0.050000,0.050000},{0.256250,0.393750,0.025000,0.025000},{0.256250,0.393750,0.050000,0.050000},{0.268750,0.393750,0.025000,0.025000},{0.268750,0.393750,0.050000,0.050000},{0.281250,0.393750,0.025000,0.025000},{0.281250,0.393750,0.050000,0.050000},{0.293750,0.393750,0.025000,0.025000},{0.293750,0.393750,0.050000,0.050000},{0.306250,0.393750,0.025000,0.025000},{0.306250,0.393750,0.050000,0.050000},{0.318750,0.393750,0.025000,0.025000},{0.318750,0.393750,0.050000,0.050000},{0.331250,0.393750,0.025000,0.025000},{0.331250,0.393750,0.050000,0.050000},{0.343750,0.393750,0.025000,0.025000},{0.343750,0.393750,0.050000,0.050000},{0.356250,0.393750,0.025000,0.025000},{0.356250,0.393750,0.050000,0.050000},{0.368750,0.393750,0.025000,0.025000},{0.368750,0.393750,0.050000,0.050000},{0.381250,0.393750,0.025000,0.025000},{0.381250,0.393750,0.050000,0.050000},{0.393750,0.393750,0.025000,0.025000},{0.393750,0.393750,0.050000,0.050000},{0.406250,0.393750,0.025000,0.025000},{0.406250,0.393750,0.050000,0.050000},{0.418750,0.393750,0.025000,0.025000},{0.418750,0.393750,0.050000,0.050000},{0.431250,0.393750,0.025000,0.025000},{0.431250,0.393750,0.050000,0.050000},{0.443750,0.393750,0.025000,0.025000},{0.443750,0.393750,0.050000,0.050000},{0.456250,0.393750,0.025000,0.025000},{0.456250,0.393750,0.050000,0.050000},{0.468750,0.393750,0.025000,0.025000},{0.468750,0.393750,0.050000,0.050000},{0.481250,0.393750,0.025000,0.025000},{0.481250,0.393750,0.050000,0.050000},{0.493750,0.393750,0.025000,0.025000},{0.493750,0.393750,0.050000,0.050000},{0.506250,0.393750,0.025000,0.025000},{0.506250,0.393750,0.050000,0.050000},{0.518750,0.393750,0.025000,0.025000},{0.518750,0.393750,0.050000,0.050000},{0.531250,0.393750,0.025000,0.025000},{0.531250,0.393750,0.050000,0.050000},{0.543750,0.393750,0.025000,0.025000},{0.543750,0.393750,0.050000,0.050000},{0.556250,0.393750,0.025000,0.025000},{0.556250,0.393750,0.050000,0.050000},{0.568750,0.393750,0.025000,0.025000},{0.568750,0.393750,0.050000,0.050000},{0.581250,0.393750,0.025000,0.025000},{0.581250,0.393750,0.050000,0.050000},{0.593750,0.393750,0.025000,0.025000},{0.593750,0.393750,0.050000,0.050000},{0.606250,0.393750,0.025000,0.025000},{0.606250,0.393750,0.050000,0.050000},{0.618750,0.393750,0.025000,0.025000},{0.618750,0.393750,0.050000,0.050000},{0.631250,0.393750,0.025000,0.025000},{0.631250,0.393750,0.050000,0.050000},{0.643750,0.393750,0.025000,0.025000},{0.643750,0.393750,0.050000,0.050000},{0.656250,0.393750,0.025000,0.025000},{0.656250,0.393750,0.050000,0.050000},{0.668750,0.393750,0.025000,0.025000},{0.668750,0.393750,0.050000,0.050000},{0.681250,0.393750,0.025000,0.025000},{0.681250,0.393750,0.050000,0.050000},{0.693750,0.393750,0.025000,0.025000},{0.693750,0.393750,0.050000,0.050000},{0.706250,0.393750,0.025000,0.025000},{0.706250,0.393750,0.050000,0.050000},{0.718750,0.393750,0.025000,0.025000},{0.718750,0.393750,0.050000,0.050000},{0.731250,0.393750,0.025000,0.025000},{0.731250,0.393750,0.050000,0.050000},{0.743750,0.393750,0.025000,0.025000},{0.743750,0.393750,0.050000,0.050000},{0.756250,0.393750,0.025000,0.025000},{0.756250,0.393750,0.050000,0.050000},{0.768750,0.393750,0.025000,0.025000},{0.768750,0.393750,0.050000,0.050000},{0.781250,0.393750,0.025000,0.025000},{0.781250,0.393750,0.050000,0.050000},{0.793750,0.393750,0.025000,0.025000},{0.793750,0.393750,0.050000,0.050000},{0.806250,0.393750,0.025000,0.025000},{0.806250,0.393750,0.050000,0.050000},{0.818750,0.393750,0.025000,0.025000},{0.818750,0.393750,0.050000,0.050000},{0.831250,0.393750,0.025000,0.025000},{0.831250,0.393750,0.050000,0.050000},{0.843750,0.393750,0.025000,0.025000},{0.843750,0.393750,0.050000,0.050000},{0.856250,0.393750,0.025000,0.025000},{0.856250,0.393750,0.050000,0.050000},{0.868750,0.393750,0.025000,0.025000},{0.868750,0.393750,0.050000,0.050000},{0.881250,0.393750,0.025000,0.025000},{0.881250,0.393750,0.050000,0.050000},{0.893750,0.393750,0.025000,0.025000},{0.893750,0.393750,0.050000,0.050000},{0.906250,0.393750,0.025000,0.025000},{0.906250,0.393750,0.050000,0.050000},{0.918750,0.393750,0.025000,0.025000},{0.918750,0.393750,0.050000,0.050000},{0.931250,0.393750,0.025000,0.025000},{0.931250,0.393750,0.050000,0.050000},{0.943750,0.393750,0.025000,0.025000},{0.943750,0.393750,0.050000,0.050000},{0.956250,0.393750,0.025000,0.025000},{0.956250,0.393750,0.050000,0.050000},{0.968750,0.393750,0.025000,0.025000},{0.968750,0.393750,0.050000,0.050000},{0.981250,0.393750,0.025000,0.025000},{0.981250,0.393750,0.050000,0.050000},{0.993750,0.393750,0.025000,0.025000},{0.993750,0.393750,0.050000,0.050000},{0.006250,0.406250,0.025000,0.025000},{0.006250,0.406250,0.050000,0.050000},{0.018750,0.406250,0.025000,0.025000},{0.018750,0.406250,0.050000,0.050000},{0.031250,0.406250,0.025000,0.025000},{0.031250,0.406250,0.050000,0.050000},{0.043750,0.406250,0.025000,0.025000},{0.043750,0.406250,0.050000,0.050000},{0.056250,0.406250,0.025000,0.025000},{0.056250,0.406250,0.050000,0.050000},{0.068750,0.406250,0.025000,0.025000},{0.068750,0.406250,0.050000,0.050000},{0.081250,0.406250,0.025000,0.025000},{0.081250,0.406250,0.050000,0.050000},{0.093750,0.406250,0.025000,0.025000},{0.093750,0.406250,0.050000,0.050000},{0.106250,0.406250,0.025000,0.025000},{0.106250,0.406250,0.050000,0.050000},{0.118750,0.406250,0.025000,0.025000},{0.118750,0.406250,0.050000,0.050000},{0.131250,0.406250,0.025000,0.025000},{0.131250,0.406250,0.050000,0.050000},{0.143750,0.406250,0.025000,0.025000},{0.143750,0.406250,0.050000,0.050000},{0.156250,0.406250,0.025000,0.025000},{0.156250,0.406250,0.050000,0.050000},{0.168750,0.406250,0.025000,0.025000},{0.168750,0.406250,0.050000,0.050000},{0.181250,0.406250,0.025000,0.025000},{0.181250,0.406250,0.050000,0.050000},{0.193750,0.406250,0.025000,0.025000},{0.193750,0.406250,0.050000,0.050000},{0.206250,0.406250,0.025000,0.025000},{0.206250,0.406250,0.050000,0.050000},{0.218750,0.406250,0.025000,0.025000},{0.218750,0.406250,0.050000,0.050000},{0.231250,0.406250,0.025000,0.025000},{0.231250,0.406250,0.050000,0.050000},{0.243750,0.406250,0.025000,0.025000},{0.243750,0.406250,0.050000,0.050000},{0.256250,0.406250,0.025000,0.025000},{0.256250,0.406250,0.050000,0.050000},{0.268750,0.406250,0.025000,0.025000},{0.268750,0.406250,0.050000,0.050000},{0.281250,0.406250,0.025000,0.025000},{0.281250,0.406250,0.050000,0.050000},{0.293750,0.406250,0.025000,0.025000},{0.293750,0.406250,0.050000,0.050000},{0.306250,0.406250,0.025000,0.025000},{0.306250,0.406250,0.050000,0.050000},{0.318750,0.406250,0.025000,0.025000},{0.318750,0.406250,0.050000,0.050000},{0.331250,0.406250,0.025000,0.025000},{0.331250,0.406250,0.050000,0.050000},{0.343750,0.406250,0.025000,0.025000},{0.343750,0.406250,0.050000,0.050000},{0.356250,0.406250,0.025000,0.025000},{0.356250,0.406250,0.050000,0.050000},{0.368750,0.406250,0.025000,0.025000},{0.368750,0.406250,0.050000,0.050000},{0.381250,0.406250,0.025000,0.025000},{0.381250,0.406250,0.050000,0.050000},{0.393750,0.406250,0.025000,0.025000},{0.393750,0.406250,0.050000,0.050000},{0.406250,0.406250,0.025000,0.025000},{0.406250,0.406250,0.050000,0.050000},{0.418750,0.406250,0.025000,0.025000},{0.418750,0.406250,0.050000,0.050000},{0.431250,0.406250,0.025000,0.025000},{0.431250,0.406250,0.050000,0.050000},{0.443750,0.406250,0.025000,0.025000},{0.443750,0.406250,0.050000,0.050000},{0.456250,0.406250,0.025000,0.025000},{0.456250,0.406250,0.050000,0.050000},{0.468750,0.406250,0.025000,0.025000},{0.468750,0.406250,0.050000,0.050000},{0.481250,0.406250,0.025000,0.025000},{0.481250,0.406250,0.050000,0.050000},{0.493750,0.406250,0.025000,0.025000},{0.493750,0.406250,0.050000,0.050000},{0.506250,0.406250,0.025000,0.025000},{0.506250,0.406250,0.050000,0.050000},{0.518750,0.406250,0.025000,0.025000},{0.518750,0.406250,0.050000,0.050000},{0.531250,0.406250,0.025000,0.025000},{0.531250,0.406250,0.050000,0.050000},{0.543750,0.406250,0.025000,0.025000},{0.543750,0.406250,0.050000,0.050000},{0.556250,0.406250,0.025000,0.025000},{0.556250,0.406250,0.050000,0.050000},{0.568750,0.406250,0.025000,0.025000},{0.568750,0.406250,0.050000,0.050000},{0.581250,0.406250,0.025000,0.025000},{0.581250,0.406250,0.050000,0.050000},{0.593750,0.406250,0.025000,0.025000},{0.593750,0.406250,0.050000,0.050000},{0.606250,0.406250,0.025000,0.025000},{0.606250,0.406250,0.050000,0.050000},{0.618750,0.406250,0.025000,0.025000},{0.618750,0.406250,0.050000,0.050000},{0.631250,0.406250,0.025000,0.025000},{0.631250,0.406250,0.050000,0.050000},{0.643750,0.406250,0.025000,0.025000},{0.643750,0.406250,0.050000,0.050000},{0.656250,0.406250,0.025000,0.025000},{0.656250,0.406250,0.050000,0.050000},{0.668750,0.406250,0.025000,0.025000},{0.668750,0.406250,0.050000,0.050000},{0.681250,0.406250,0.025000,0.025000},{0.681250,0.406250,0.050000,0.050000},{0.693750,0.406250,0.025000,0.025000},{0.693750,0.406250,0.050000,0.050000},{0.706250,0.406250,0.025000,0.025000},{0.706250,0.406250,0.050000,0.050000},{0.718750,0.406250,0.025000,0.025000},{0.718750,0.406250,0.050000,0.050000},{0.731250,0.406250,0.025000,0.025000},{0.731250,0.406250,0.050000,0.050000},{0.743750,0.406250,0.025000,0.025000},{0.743750,0.406250,0.050000,0.050000},{0.756250,0.406250,0.025000,0.025000},{0.756250,0.406250,0.050000,0.050000},{0.768750,0.406250,0.025000,0.025000},{0.768750,0.406250,0.050000,0.050000},{0.781250,0.406250,0.025000,0.025000},{0.781250,0.406250,0.050000,0.050000},{0.793750,0.406250,0.025000,0.025000},{0.793750,0.406250,0.050000,0.050000},{0.806250,0.406250,0.025000,0.025000},{0.806250,0.406250,0.050000,0.050000},{0.818750,0.406250,0.025000,0.025000},{0.818750,0.406250,0.050000,0.050000},{0.831250,0.406250,0.025000,0.025000},{0.831250,0.406250,0.050000,0.050000},{0.843750,0.406250,0.025000,0.025000},{0.843750,0.406250,0.050000,0.050000},{0.856250,0.406250,0.025000,0.025000},{0.856250,0.406250,0.050000,0.050000},{0.868750,0.406250,0.025000,0.025000},{0.868750,0.406250,0.050000,0.050000},{0.881250,0.406250,0.025000,0.025000},{0.881250,0.406250,0.050000,0.050000},{0.893750,0.406250,0.025000,0.025000},{0.893750,0.406250,0.050000,0.050000},{0.906250,0.406250,0.025000,0.025000},{0.906250,0.406250,0.050000,0.050000},{0.918750,0.406250,0.025000,0.025000},{0.918750,0.406250,0.050000,0.050000},{0.931250,0.406250,0.025000,0.025000},{0.931250,0.406250,0.050000,0.050000},{0.943750,0.406250,0.025000,0.025000},{0.943750,0.406250,0.050000,0.050000},{0.956250,0.406250,0.025000,0.025000},{0.956250,0.406250,0.050000,0.050000},{0.968750,0.406250,0.025000,0.025000},{0.968750,0.406250,0.050000,0.050000},{0.981250,0.406250,0.025000,0.025000},{0.981250,0.406250,0.050000,0.050000},{0.993750,0.406250,0.025000,0.025000},{0.993750,0.406250,0.050000,0.050000},{0.006250,0.418750,0.025000,0.025000},{0.006250,0.418750,0.050000,0.050000},{0.018750,0.418750,0.025000,0.025000},{0.018750,0.418750,0.050000,0.050000},{0.031250,0.418750,0.025000,0.025000},{0.031250,0.418750,0.050000,0.050000},{0.043750,0.418750,0.025000,0.025000},{0.043750,0.418750,0.050000,0.050000},{0.056250,0.418750,0.025000,0.025000},{0.056250,0.418750,0.050000,0.050000},{0.068750,0.418750,0.025000,0.025000},{0.068750,0.418750,0.050000,0.050000},{0.081250,0.418750,0.025000,0.025000},{0.081250,0.418750,0.050000,0.050000},{0.093750,0.418750,0.025000,0.025000},{0.093750,0.418750,0.050000,0.050000},{0.106250,0.418750,0.025000,0.025000},{0.106250,0.418750,0.050000,0.050000},{0.118750,0.418750,0.025000,0.025000},{0.118750,0.418750,0.050000,0.050000},{0.131250,0.418750,0.025000,0.025000},{0.131250,0.418750,0.050000,0.050000},{0.143750,0.418750,0.025000,0.025000},{0.143750,0.418750,0.050000,0.050000},{0.156250,0.418750,0.025000,0.025000},{0.156250,0.418750,0.050000,0.050000},{0.168750,0.418750,0.025000,0.025000},{0.168750,0.418750,0.050000,0.050000},{0.181250,0.418750,0.025000,0.025000},{0.181250,0.418750,0.050000,0.050000},{0.193750,0.418750,0.025000,0.025000},{0.193750,0.418750,0.050000,0.050000},{0.206250,0.418750,0.025000,0.025000},{0.206250,0.418750,0.050000,0.050000},{0.218750,0.418750,0.025000,0.025000},{0.218750,0.418750,0.050000,0.050000},{0.231250,0.418750,0.025000,0.025000},{0.231250,0.418750,0.050000,0.050000},{0.243750,0.418750,0.025000,0.025000},{0.243750,0.418750,0.050000,0.050000},{0.256250,0.418750,0.025000,0.025000},{0.256250,0.418750,0.050000,0.050000},{0.268750,0.418750,0.025000,0.025000},{0.268750,0.418750,0.050000,0.050000},{0.281250,0.418750,0.025000,0.025000},{0.281250,0.418750,0.050000,0.050000},{0.293750,0.418750,0.025000,0.025000},{0.293750,0.418750,0.050000,0.050000},{0.306250,0.418750,0.025000,0.025000},{0.306250,0.418750,0.050000,0.050000},{0.318750,0.418750,0.025000,0.025000},{0.318750,0.418750,0.050000,0.050000},{0.331250,0.418750,0.025000,0.025000},{0.331250,0.418750,0.050000,0.050000},{0.343750,0.418750,0.025000,0.025000},{0.343750,0.418750,0.050000,0.050000},{0.356250,0.418750,0.025000,0.025000},{0.356250,0.418750,0.050000,0.050000},{0.368750,0.418750,0.025000,0.025000},{0.368750,0.418750,0.050000,0.050000},{0.381250,0.418750,0.025000,0.025000},{0.381250,0.418750,0.050000,0.050000},{0.393750,0.418750,0.025000,0.025000},{0.393750,0.418750,0.050000,0.050000},{0.406250,0.418750,0.025000,0.025000},{0.406250,0.418750,0.050000,0.050000},{0.418750,0.418750,0.025000,0.025000},{0.418750,0.418750,0.050000,0.050000},{0.431250,0.418750,0.025000,0.025000},{0.431250,0.418750,0.050000,0.050000},{0.443750,0.418750,0.025000,0.025000},{0.443750,0.418750,0.050000,0.050000},{0.456250,0.418750,0.025000,0.025000},{0.456250,0.418750,0.050000,0.050000},{0.468750,0.418750,0.025000,0.025000},{0.468750,0.418750,0.050000,0.050000},{0.481250,0.418750,0.025000,0.025000},{0.481250,0.418750,0.050000,0.050000},{0.493750,0.418750,0.025000,0.025000},{0.493750,0.418750,0.050000,0.050000},{0.506250,0.418750,0.025000,0.025000},{0.506250,0.418750,0.050000,0.050000},{0.518750,0.418750,0.025000,0.025000},{0.518750,0.418750,0.050000,0.050000},{0.531250,0.418750,0.025000,0.025000},{0.531250,0.418750,0.050000,0.050000},{0.543750,0.418750,0.025000,0.025000},{0.543750,0.418750,0.050000,0.050000},{0.556250,0.418750,0.025000,0.025000},{0.556250,0.418750,0.050000,0.050000},{0.568750,0.418750,0.025000,0.025000},{0.568750,0.418750,0.050000,0.050000},{0.581250,0.418750,0.025000,0.025000},{0.581250,0.418750,0.050000,0.050000},{0.593750,0.418750,0.025000,0.025000},{0.593750,0.418750,0.050000,0.050000},{0.606250,0.418750,0.025000,0.025000},{0.606250,0.418750,0.050000,0.050000},{0.618750,0.418750,0.025000,0.025000},{0.618750,0.418750,0.050000,0.050000},{0.631250,0.418750,0.025000,0.025000},{0.631250,0.418750,0.050000,0.050000},{0.643750,0.418750,0.025000,0.025000},{0.643750,0.418750,0.050000,0.050000},{0.656250,0.418750,0.025000,0.025000},{0.656250,0.418750,0.050000,0.050000},{0.668750,0.418750,0.025000,0.025000},{0.668750,0.418750,0.050000,0.050000},{0.681250,0.418750,0.025000,0.025000},{0.681250,0.418750,0.050000,0.050000},{0.693750,0.418750,0.025000,0.025000},{0.693750,0.418750,0.050000,0.050000},{0.706250,0.418750,0.025000,0.025000},{0.706250,0.418750,0.050000,0.050000},{0.718750,0.418750,0.025000,0.025000},{0.718750,0.418750,0.050000,0.050000},{0.731250,0.418750,0.025000,0.025000},{0.731250,0.418750,0.050000,0.050000},{0.743750,0.418750,0.025000,0.025000},{0.743750,0.418750,0.050000,0.050000},{0.756250,0.418750,0.025000,0.025000},{0.756250,0.418750,0.050000,0.050000},{0.768750,0.418750,0.025000,0.025000},{0.768750,0.418750,0.050000,0.050000},{0.781250,0.418750,0.025000,0.025000},{0.781250,0.418750,0.050000,0.050000},{0.793750,0.418750,0.025000,0.025000},{0.793750,0.418750,0.050000,0.050000},{0.806250,0.418750,0.025000,0.025000},{0.806250,0.418750,0.050000,0.050000},{0.818750,0.418750,0.025000,0.025000},{0.818750,0.418750,0.050000,0.050000},{0.831250,0.418750,0.025000,0.025000},{0.831250,0.418750,0.050000,0.050000},{0.843750,0.418750,0.025000,0.025000},{0.843750,0.418750,0.050000,0.050000},{0.856250,0.418750,0.025000,0.025000},{0.856250,0.418750,0.050000,0.050000},{0.868750,0.418750,0.025000,0.025000},{0.868750,0.418750,0.050000,0.050000},{0.881250,0.418750,0.025000,0.025000},{0.881250,0.418750,0.050000,0.050000},{0.893750,0.418750,0.025000,0.025000},{0.893750,0.418750,0.050000,0.050000},{0.906250,0.418750,0.025000,0.025000},{0.906250,0.418750,0.050000,0.050000},{0.918750,0.418750,0.025000,0.025000},{0.918750,0.418750,0.050000,0.050000},{0.931250,0.418750,0.025000,0.025000},{0.931250,0.418750,0.050000,0.050000},{0.943750,0.418750,0.025000,0.025000},{0.943750,0.418750,0.050000,0.050000},{0.956250,0.418750,0.025000,0.025000},{0.956250,0.418750,0.050000,0.050000},{0.968750,0.418750,0.025000,0.025000},{0.968750,0.418750,0.050000,0.050000},{0.981250,0.418750,0.025000,0.025000},{0.981250,0.418750,0.050000,0.050000},{0.993750,0.418750,0.025000,0.025000},{0.993750,0.418750,0.050000,0.050000},{0.006250,0.431250,0.025000,0.025000},{0.006250,0.431250,0.050000,0.050000},{0.018750,0.431250,0.025000,0.025000},{0.018750,0.431250,0.050000,0.050000},{0.031250,0.431250,0.025000,0.025000},{0.031250,0.431250,0.050000,0.050000},{0.043750,0.431250,0.025000,0.025000},{0.043750,0.431250,0.050000,0.050000},{0.056250,0.431250,0.025000,0.025000},{0.056250,0.431250,0.050000,0.050000},{0.068750,0.431250,0.025000,0.025000},{0.068750,0.431250,0.050000,0.050000},{0.081250,0.431250,0.025000,0.025000},{0.081250,0.431250,0.050000,0.050000},{0.093750,0.431250,0.025000,0.025000},{0.093750,0.431250,0.050000,0.050000},{0.106250,0.431250,0.025000,0.025000},{0.106250,0.431250,0.050000,0.050000},{0.118750,0.431250,0.025000,0.025000},{0.118750,0.431250,0.050000,0.050000},{0.131250,0.431250,0.025000,0.025000},{0.131250,0.431250,0.050000,0.050000},{0.143750,0.431250,0.025000,0.025000},{0.143750,0.431250,0.050000,0.050000},{0.156250,0.431250,0.025000,0.025000},{0.156250,0.431250,0.050000,0.050000},{0.168750,0.431250,0.025000,0.025000},{0.168750,0.431250,0.050000,0.050000},{0.181250,0.431250,0.025000,0.025000},{0.181250,0.431250,0.050000,0.050000},{0.193750,0.431250,0.025000,0.025000},{0.193750,0.431250,0.050000,0.050000},{0.206250,0.431250,0.025000,0.025000},{0.206250,0.431250,0.050000,0.050000},{0.218750,0.431250,0.025000,0.025000},{0.218750,0.431250,0.050000,0.050000},{0.231250,0.431250,0.025000,0.025000},{0.231250,0.431250,0.050000,0.050000},{0.243750,0.431250,0.025000,0.025000},{0.243750,0.431250,0.050000,0.050000},{0.256250,0.431250,0.025000,0.025000},{0.256250,0.431250,0.050000,0.050000},{0.268750,0.431250,0.025000,0.025000},{0.268750,0.431250,0.050000,0.050000},{0.281250,0.431250,0.025000,0.025000},{0.281250,0.431250,0.050000,0.050000},{0.293750,0.431250,0.025000,0.025000},{0.293750,0.431250,0.050000,0.050000},{0.306250,0.431250,0.025000,0.025000},{0.306250,0.431250,0.050000,0.050000},{0.318750,0.431250,0.025000,0.025000},{0.318750,0.431250,0.050000,0.050000},{0.331250,0.431250,0.025000,0.025000},{0.331250,0.431250,0.050000,0.050000},{0.343750,0.431250,0.025000,0.025000},{0.343750,0.431250,0.050000,0.050000},{0.356250,0.431250,0.025000,0.025000},{0.356250,0.431250,0.050000,0.050000},{0.368750,0.431250,0.025000,0.025000},{0.368750,0.431250,0.050000,0.050000},{0.381250,0.431250,0.025000,0.025000},{0.381250,0.431250,0.050000,0.050000},{0.393750,0.431250,0.025000,0.025000},{0.393750,0.431250,0.050000,0.050000},{0.406250,0.431250,0.025000,0.025000},{0.406250,0.431250,0.050000,0.050000},{0.418750,0.431250,0.025000,0.025000},{0.418750,0.431250,0.050000,0.050000},{0.431250,0.431250,0.025000,0.025000},{0.431250,0.431250,0.050000,0.050000},{0.443750,0.431250,0.025000,0.025000},{0.443750,0.431250,0.050000,0.050000},{0.456250,0.431250,0.025000,0.025000},{0.456250,0.431250,0.050000,0.050000},{0.468750,0.431250,0.025000,0.025000},{0.468750,0.431250,0.050000,0.050000},{0.481250,0.431250,0.025000,0.025000},{0.481250,0.431250,0.050000,0.050000},{0.493750,0.431250,0.025000,0.025000},{0.493750,0.431250,0.050000,0.050000},{0.506250,0.431250,0.025000,0.025000},{0.506250,0.431250,0.050000,0.050000},{0.518750,0.431250,0.025000,0.025000},{0.518750,0.431250,0.050000,0.050000},{0.531250,0.431250,0.025000,0.025000},{0.531250,0.431250,0.050000,0.050000},{0.543750,0.431250,0.025000,0.025000},{0.543750,0.431250,0.050000,0.050000},{0.556250,0.431250,0.025000,0.025000},{0.556250,0.431250,0.050000,0.050000},{0.568750,0.431250,0.025000,0.025000},{0.568750,0.431250,0.050000,0.050000},{0.581250,0.431250,0.025000,0.025000},{0.581250,0.431250,0.050000,0.050000},{0.593750,0.431250,0.025000,0.025000},{0.593750,0.431250,0.050000,0.050000},{0.606250,0.431250,0.025000,0.025000},{0.606250,0.431250,0.050000,0.050000},{0.618750,0.431250,0.025000,0.025000},{0.618750,0.431250,0.050000,0.050000},{0.631250,0.431250,0.025000,0.025000},{0.631250,0.431250,0.050000,0.050000},{0.643750,0.431250,0.025000,0.025000},{0.643750,0.431250,0.050000,0.050000},{0.656250,0.431250,0.025000,0.025000},{0.656250,0.431250,0.050000,0.050000},{0.668750,0.431250,0.025000,0.025000},{0.668750,0.431250,0.050000,0.050000},{0.681250,0.431250,0.025000,0.025000},{0.681250,0.431250,0.050000,0.050000},{0.693750,0.431250,0.025000,0.025000},{0.693750,0.431250,0.050000,0.050000},{0.706250,0.431250,0.025000,0.025000},{0.706250,0.431250,0.050000,0.050000},{0.718750,0.431250,0.025000,0.025000},{0.718750,0.431250,0.050000,0.050000},{0.731250,0.431250,0.025000,0.025000},{0.731250,0.431250,0.050000,0.050000},{0.743750,0.431250,0.025000,0.025000},{0.743750,0.431250,0.050000,0.050000},{0.756250,0.431250,0.025000,0.025000},{0.756250,0.431250,0.050000,0.050000},{0.768750,0.431250,0.025000,0.025000},{0.768750,0.431250,0.050000,0.050000},{0.781250,0.431250,0.025000,0.025000},{0.781250,0.431250,0.050000,0.050000},{0.793750,0.431250,0.025000,0.025000},{0.793750,0.431250,0.050000,0.050000},{0.806250,0.431250,0.025000,0.025000},{0.806250,0.431250,0.050000,0.050000},{0.818750,0.431250,0.025000,0.025000},{0.818750,0.431250,0.050000,0.050000},{0.831250,0.431250,0.025000,0.025000},{0.831250,0.431250,0.050000,0.050000},{0.843750,0.431250,0.025000,0.025000},{0.843750,0.431250,0.050000,0.050000},{0.856250,0.431250,0.025000,0.025000},{0.856250,0.431250,0.050000,0.050000},{0.868750,0.431250,0.025000,0.025000},{0.868750,0.431250,0.050000,0.050000},{0.881250,0.431250,0.025000,0.025000},{0.881250,0.431250,0.050000,0.050000},{0.893750,0.431250,0.025000,0.025000},{0.893750,0.431250,0.050000,0.050000},{0.906250,0.431250,0.025000,0.025000},{0.906250,0.431250,0.050000,0.050000},{0.918750,0.431250,0.025000,0.025000},{0.918750,0.431250,0.050000,0.050000},{0.931250,0.431250,0.025000,0.025000},{0.931250,0.431250,0.050000,0.050000},{0.943750,0.431250,0.025000,0.025000},{0.943750,0.431250,0.050000,0.050000},{0.956250,0.431250,0.025000,0.025000},{0.956250,0.431250,0.050000,0.050000},{0.968750,0.431250,0.025000,0.025000},{0.968750,0.431250,0.050000,0.050000},{0.981250,0.431250,0.025000,0.025000},{0.981250,0.431250,0.050000,0.050000},{0.993750,0.431250,0.025000,0.025000},{0.993750,0.431250,0.050000,0.050000},{0.006250,0.443750,0.025000,0.025000},{0.006250,0.443750,0.050000,0.050000},{0.018750,0.443750,0.025000,0.025000},{0.018750,0.443750,0.050000,0.050000},{0.031250,0.443750,0.025000,0.025000},{0.031250,0.443750,0.050000,0.050000},{0.043750,0.443750,0.025000,0.025000},{0.043750,0.443750,0.050000,0.050000},{0.056250,0.443750,0.025000,0.025000},{0.056250,0.443750,0.050000,0.050000},{0.068750,0.443750,0.025000,0.025000},{0.068750,0.443750,0.050000,0.050000},{0.081250,0.443750,0.025000,0.025000},{0.081250,0.443750,0.050000,0.050000},{0.093750,0.443750,0.025000,0.025000},{0.093750,0.443750,0.050000,0.050000},{0.106250,0.443750,0.025000,0.025000},{0.106250,0.443750,0.050000,0.050000},{0.118750,0.443750,0.025000,0.025000},{0.118750,0.443750,0.050000,0.050000},{0.131250,0.443750,0.025000,0.025000},{0.131250,0.443750,0.050000,0.050000},{0.143750,0.443750,0.025000,0.025000},{0.143750,0.443750,0.050000,0.050000},{0.156250,0.443750,0.025000,0.025000},{0.156250,0.443750,0.050000,0.050000},{0.168750,0.443750,0.025000,0.025000},{0.168750,0.443750,0.050000,0.050000},{0.181250,0.443750,0.025000,0.025000},{0.181250,0.443750,0.050000,0.050000},{0.193750,0.443750,0.025000,0.025000},{0.193750,0.443750,0.050000,0.050000},{0.206250,0.443750,0.025000,0.025000},{0.206250,0.443750,0.050000,0.050000},{0.218750,0.443750,0.025000,0.025000},{0.218750,0.443750,0.050000,0.050000},{0.231250,0.443750,0.025000,0.025000},{0.231250,0.443750,0.050000,0.050000},{0.243750,0.443750,0.025000,0.025000},{0.243750,0.443750,0.050000,0.050000},{0.256250,0.443750,0.025000,0.025000},{0.256250,0.443750,0.050000,0.050000},{0.268750,0.443750,0.025000,0.025000},{0.268750,0.443750,0.050000,0.050000},{0.281250,0.443750,0.025000,0.025000},{0.281250,0.443750,0.050000,0.050000},{0.293750,0.443750,0.025000,0.025000},{0.293750,0.443750,0.050000,0.050000},{0.306250,0.443750,0.025000,0.025000},{0.306250,0.443750,0.050000,0.050000},{0.318750,0.443750,0.025000,0.025000},{0.318750,0.443750,0.050000,0.050000},{0.331250,0.443750,0.025000,0.025000},{0.331250,0.443750,0.050000,0.050000},{0.343750,0.443750,0.025000,0.025000},{0.343750,0.443750,0.050000,0.050000},{0.356250,0.443750,0.025000,0.025000},{0.356250,0.443750,0.050000,0.050000},{0.368750,0.443750,0.025000,0.025000},{0.368750,0.443750,0.050000,0.050000},{0.381250,0.443750,0.025000,0.025000},{0.381250,0.443750,0.050000,0.050000},{0.393750,0.443750,0.025000,0.025000},{0.393750,0.443750,0.050000,0.050000},{0.406250,0.443750,0.025000,0.025000},{0.406250,0.443750,0.050000,0.050000},{0.418750,0.443750,0.025000,0.025000},{0.418750,0.443750,0.050000,0.050000},{0.431250,0.443750,0.025000,0.025000},{0.431250,0.443750,0.050000,0.050000},{0.443750,0.443750,0.025000,0.025000},{0.443750,0.443750,0.050000,0.050000},{0.456250,0.443750,0.025000,0.025000},{0.456250,0.443750,0.050000,0.050000},{0.468750,0.443750,0.025000,0.025000},{0.468750,0.443750,0.050000,0.050000},{0.481250,0.443750,0.025000,0.025000},{0.481250,0.443750,0.050000,0.050000},{0.493750,0.443750,0.025000,0.025000},{0.493750,0.443750,0.050000,0.050000},{0.506250,0.443750,0.025000,0.025000},{0.506250,0.443750,0.050000,0.050000},{0.518750,0.443750,0.025000,0.025000},{0.518750,0.443750,0.050000,0.050000},{0.531250,0.443750,0.025000,0.025000},{0.531250,0.443750,0.050000,0.050000},{0.543750,0.443750,0.025000,0.025000},{0.543750,0.443750,0.050000,0.050000},{0.556250,0.443750,0.025000,0.025000},{0.556250,0.443750,0.050000,0.050000},{0.568750,0.443750,0.025000,0.025000},{0.568750,0.443750,0.050000,0.050000},{0.581250,0.443750,0.025000,0.025000},{0.581250,0.443750,0.050000,0.050000},{0.593750,0.443750,0.025000,0.025000},{0.593750,0.443750,0.050000,0.050000},{0.606250,0.443750,0.025000,0.025000},{0.606250,0.443750,0.050000,0.050000},{0.618750,0.443750,0.025000,0.025000},{0.618750,0.443750,0.050000,0.050000},{0.631250,0.443750,0.025000,0.025000},{0.631250,0.443750,0.050000,0.050000},{0.643750,0.443750,0.025000,0.025000},{0.643750,0.443750,0.050000,0.050000},{0.656250,0.443750,0.025000,0.025000},{0.656250,0.443750,0.050000,0.050000},{0.668750,0.443750,0.025000,0.025000},{0.668750,0.443750,0.050000,0.050000},{0.681250,0.443750,0.025000,0.025000},{0.681250,0.443750,0.050000,0.050000},{0.693750,0.443750,0.025000,0.025000},{0.693750,0.443750,0.050000,0.050000},{0.706250,0.443750,0.025000,0.025000},{0.706250,0.443750,0.050000,0.050000},{0.718750,0.443750,0.025000,0.025000},{0.718750,0.443750,0.050000,0.050000},{0.731250,0.443750,0.025000,0.025000},{0.731250,0.443750,0.050000,0.050000},{0.743750,0.443750,0.025000,0.025000},{0.743750,0.443750,0.050000,0.050000},{0.756250,0.443750,0.025000,0.025000},{0.756250,0.443750,0.050000,0.050000},{0.768750,0.443750,0.025000,0.025000},{0.768750,0.443750,0.050000,0.050000},{0.781250,0.443750,0.025000,0.025000},{0.781250,0.443750,0.050000,0.050000},{0.793750,0.443750,0.025000,0.025000},{0.793750,0.443750,0.050000,0.050000},{0.806250,0.443750,0.025000,0.025000},{0.806250,0.443750,0.050000,0.050000},{0.818750,0.443750,0.025000,0.025000},{0.818750,0.443750,0.050000,0.050000},{0.831250,0.443750,0.025000,0.025000},{0.831250,0.443750,0.050000,0.050000},{0.843750,0.443750,0.025000,0.025000},{0.843750,0.443750,0.050000,0.050000},{0.856250,0.443750,0.025000,0.025000},{0.856250,0.443750,0.050000,0.050000},{0.868750,0.443750,0.025000,0.025000},{0.868750,0.443750,0.050000,0.050000},{0.881250,0.443750,0.025000,0.025000},{0.881250,0.443750,0.050000,0.050000},{0.893750,0.443750,0.025000,0.025000},{0.893750,0.443750,0.050000,0.050000},{0.906250,0.443750,0.025000,0.025000},{0.906250,0.443750,0.050000,0.050000},{0.918750,0.443750,0.025000,0.025000},{0.918750,0.443750,0.050000,0.050000},{0.931250,0.443750,0.025000,0.025000},{0.931250,0.443750,0.050000,0.050000},{0.943750,0.443750,0.025000,0.025000},{0.943750,0.443750,0.050000,0.050000},{0.956250,0.443750,0.025000,0.025000},{0.956250,0.443750,0.050000,0.050000},{0.968750,0.443750,0.025000,0.025000},{0.968750,0.443750,0.050000,0.050000},{0.981250,0.443750,0.025000,0.025000},{0.981250,0.443750,0.050000,0.050000},{0.993750,0.443750,0.025000,0.025000},{0.993750,0.443750,0.050000,0.050000},{0.006250,0.456250,0.025000,0.025000},{0.006250,0.456250,0.050000,0.050000},{0.018750,0.456250,0.025000,0.025000},{0.018750,0.456250,0.050000,0.050000},{0.031250,0.456250,0.025000,0.025000},{0.031250,0.456250,0.050000,0.050000},{0.043750,0.456250,0.025000,0.025000},{0.043750,0.456250,0.050000,0.050000},{0.056250,0.456250,0.025000,0.025000},{0.056250,0.456250,0.050000,0.050000},{0.068750,0.456250,0.025000,0.025000},{0.068750,0.456250,0.050000,0.050000},{0.081250,0.456250,0.025000,0.025000},{0.081250,0.456250,0.050000,0.050000},{0.093750,0.456250,0.025000,0.025000},{0.093750,0.456250,0.050000,0.050000},{0.106250,0.456250,0.025000,0.025000},{0.106250,0.456250,0.050000,0.050000},{0.118750,0.456250,0.025000,0.025000},{0.118750,0.456250,0.050000,0.050000},{0.131250,0.456250,0.025000,0.025000},{0.131250,0.456250,0.050000,0.050000},{0.143750,0.456250,0.025000,0.025000},{0.143750,0.456250,0.050000,0.050000},{0.156250,0.456250,0.025000,0.025000},{0.156250,0.456250,0.050000,0.050000},{0.168750,0.456250,0.025000,0.025000},{0.168750,0.456250,0.050000,0.050000},{0.181250,0.456250,0.025000,0.025000},{0.181250,0.456250,0.050000,0.050000},{0.193750,0.456250,0.025000,0.025000},{0.193750,0.456250,0.050000,0.050000},{0.206250,0.456250,0.025000,0.025000},{0.206250,0.456250,0.050000,0.050000},{0.218750,0.456250,0.025000,0.025000},{0.218750,0.456250,0.050000,0.050000},{0.231250,0.456250,0.025000,0.025000},{0.231250,0.456250,0.050000,0.050000},{0.243750,0.456250,0.025000,0.025000},{0.243750,0.456250,0.050000,0.050000},{0.256250,0.456250,0.025000,0.025000},{0.256250,0.456250,0.050000,0.050000},{0.268750,0.456250,0.025000,0.025000},{0.268750,0.456250,0.050000,0.050000},{0.281250,0.456250,0.025000,0.025000},{0.281250,0.456250,0.050000,0.050000},{0.293750,0.456250,0.025000,0.025000},{0.293750,0.456250,0.050000,0.050000},{0.306250,0.456250,0.025000,0.025000},{0.306250,0.456250,0.050000,0.050000},{0.318750,0.456250,0.025000,0.025000},{0.318750,0.456250,0.050000,0.050000},{0.331250,0.456250,0.025000,0.025000},{0.331250,0.456250,0.050000,0.050000},{0.343750,0.456250,0.025000,0.025000},{0.343750,0.456250,0.050000,0.050000},{0.356250,0.456250,0.025000,0.025000},{0.356250,0.456250,0.050000,0.050000},{0.368750,0.456250,0.025000,0.025000},{0.368750,0.456250,0.050000,0.050000},{0.381250,0.456250,0.025000,0.025000},{0.381250,0.456250,0.050000,0.050000},{0.393750,0.456250,0.025000,0.025000},{0.393750,0.456250,0.050000,0.050000},{0.406250,0.456250,0.025000,0.025000},{0.406250,0.456250,0.050000,0.050000},{0.418750,0.456250,0.025000,0.025000},{0.418750,0.456250,0.050000,0.050000},{0.431250,0.456250,0.025000,0.025000},{0.431250,0.456250,0.050000,0.050000},{0.443750,0.456250,0.025000,0.025000},{0.443750,0.456250,0.050000,0.050000},{0.456250,0.456250,0.025000,0.025000},{0.456250,0.456250,0.050000,0.050000},{0.468750,0.456250,0.025000,0.025000},{0.468750,0.456250,0.050000,0.050000},{0.481250,0.456250,0.025000,0.025000},{0.481250,0.456250,0.050000,0.050000},{0.493750,0.456250,0.025000,0.025000},{0.493750,0.456250,0.050000,0.050000},{0.506250,0.456250,0.025000,0.025000},{0.506250,0.456250,0.050000,0.050000},{0.518750,0.456250,0.025000,0.025000},{0.518750,0.456250,0.050000,0.050000},{0.531250,0.456250,0.025000,0.025000},{0.531250,0.456250,0.050000,0.050000},{0.543750,0.456250,0.025000,0.025000},{0.543750,0.456250,0.050000,0.050000},{0.556250,0.456250,0.025000,0.025000},{0.556250,0.456250,0.050000,0.050000},{0.568750,0.456250,0.025000,0.025000},{0.568750,0.456250,0.050000,0.050000},{0.581250,0.456250,0.025000,0.025000},{0.581250,0.456250,0.050000,0.050000},{0.593750,0.456250,0.025000,0.025000},{0.593750,0.456250,0.050000,0.050000},{0.606250,0.456250,0.025000,0.025000},{0.606250,0.456250,0.050000,0.050000},{0.618750,0.456250,0.025000,0.025000},{0.618750,0.456250,0.050000,0.050000},{0.631250,0.456250,0.025000,0.025000},{0.631250,0.456250,0.050000,0.050000},{0.643750,0.456250,0.025000,0.025000},{0.643750,0.456250,0.050000,0.050000},{0.656250,0.456250,0.025000,0.025000},{0.656250,0.456250,0.050000,0.050000},{0.668750,0.456250,0.025000,0.025000},{0.668750,0.456250,0.050000,0.050000},{0.681250,0.456250,0.025000,0.025000},{0.681250,0.456250,0.050000,0.050000},{0.693750,0.456250,0.025000,0.025000},{0.693750,0.456250,0.050000,0.050000},{0.706250,0.456250,0.025000,0.025000},{0.706250,0.456250,0.050000,0.050000},{0.718750,0.456250,0.025000,0.025000},{0.718750,0.456250,0.050000,0.050000},{0.731250,0.456250,0.025000,0.025000},{0.731250,0.456250,0.050000,0.050000},{0.743750,0.456250,0.025000,0.025000},{0.743750,0.456250,0.050000,0.050000},{0.756250,0.456250,0.025000,0.025000},{0.756250,0.456250,0.050000,0.050000},{0.768750,0.456250,0.025000,0.025000},{0.768750,0.456250,0.050000,0.050000},{0.781250,0.456250,0.025000,0.025000},{0.781250,0.456250,0.050000,0.050000},{0.793750,0.456250,0.025000,0.025000},{0.793750,0.456250,0.050000,0.050000},{0.806250,0.456250,0.025000,0.025000},{0.806250,0.456250,0.050000,0.050000},{0.818750,0.456250,0.025000,0.025000},{0.818750,0.456250,0.050000,0.050000},{0.831250,0.456250,0.025000,0.025000},{0.831250,0.456250,0.050000,0.050000},{0.843750,0.456250,0.025000,0.025000},{0.843750,0.456250,0.050000,0.050000},{0.856250,0.456250,0.025000,0.025000},{0.856250,0.456250,0.050000,0.050000},{0.868750,0.456250,0.025000,0.025000},{0.868750,0.456250,0.050000,0.050000},{0.881250,0.456250,0.025000,0.025000},{0.881250,0.456250,0.050000,0.050000},{0.893750,0.456250,0.025000,0.025000},{0.893750,0.456250,0.050000,0.050000},{0.906250,0.456250,0.025000,0.025000},{0.906250,0.456250,0.050000,0.050000},{0.918750,0.456250,0.025000,0.025000},{0.918750,0.456250,0.050000,0.050000},{0.931250,0.456250,0.025000,0.025000},{0.931250,0.456250,0.050000,0.050000},{0.943750,0.456250,0.025000,0.025000},{0.943750,0.456250,0.050000,0.050000},{0.956250,0.456250,0.025000,0.025000},{0.956250,0.456250,0.050000,0.050000},{0.968750,0.456250,0.025000,0.025000},{0.968750,0.456250,0.050000,0.050000},{0.981250,0.456250,0.025000,0.025000},{0.981250,0.456250,0.050000,0.050000},{0.993750,0.456250,0.025000,0.025000},{0.993750,0.456250,0.050000,0.050000},{0.006250,0.468750,0.025000,0.025000},{0.006250,0.468750,0.050000,0.050000},{0.018750,0.468750,0.025000,0.025000},{0.018750,0.468750,0.050000,0.050000},{0.031250,0.468750,0.025000,0.025000},{0.031250,0.468750,0.050000,0.050000},{0.043750,0.468750,0.025000,0.025000},{0.043750,0.468750,0.050000,0.050000},{0.056250,0.468750,0.025000,0.025000},{0.056250,0.468750,0.050000,0.050000},{0.068750,0.468750,0.025000,0.025000},{0.068750,0.468750,0.050000,0.050000},{0.081250,0.468750,0.025000,0.025000},{0.081250,0.468750,0.050000,0.050000},{0.093750,0.468750,0.025000,0.025000},{0.093750,0.468750,0.050000,0.050000},{0.106250,0.468750,0.025000,0.025000},{0.106250,0.468750,0.050000,0.050000},{0.118750,0.468750,0.025000,0.025000},{0.118750,0.468750,0.050000,0.050000},{0.131250,0.468750,0.025000,0.025000},{0.131250,0.468750,0.050000,0.050000},{0.143750,0.468750,0.025000,0.025000},{0.143750,0.468750,0.050000,0.050000},{0.156250,0.468750,0.025000,0.025000},{0.156250,0.468750,0.050000,0.050000},{0.168750,0.468750,0.025000,0.025000},{0.168750,0.468750,0.050000,0.050000},{0.181250,0.468750,0.025000,0.025000},{0.181250,0.468750,0.050000,0.050000},{0.193750,0.468750,0.025000,0.025000},{0.193750,0.468750,0.050000,0.050000},{0.206250,0.468750,0.025000,0.025000},{0.206250,0.468750,0.050000,0.050000},{0.218750,0.468750,0.025000,0.025000},{0.218750,0.468750,0.050000,0.050000},{0.231250,0.468750,0.025000,0.025000},{0.231250,0.468750,0.050000,0.050000},{0.243750,0.468750,0.025000,0.025000},{0.243750,0.468750,0.050000,0.050000},{0.256250,0.468750,0.025000,0.025000},{0.256250,0.468750,0.050000,0.050000},{0.268750,0.468750,0.025000,0.025000},{0.268750,0.468750,0.050000,0.050000},{0.281250,0.468750,0.025000,0.025000},{0.281250,0.468750,0.050000,0.050000},{0.293750,0.468750,0.025000,0.025000},{0.293750,0.468750,0.050000,0.050000},{0.306250,0.468750,0.025000,0.025000},{0.306250,0.468750,0.050000,0.050000},{0.318750,0.468750,0.025000,0.025000},{0.318750,0.468750,0.050000,0.050000},{0.331250,0.468750,0.025000,0.025000},{0.331250,0.468750,0.050000,0.050000},{0.343750,0.468750,0.025000,0.025000},{0.343750,0.468750,0.050000,0.050000},{0.356250,0.468750,0.025000,0.025000},{0.356250,0.468750,0.050000,0.050000},{0.368750,0.468750,0.025000,0.025000},{0.368750,0.468750,0.050000,0.050000},{0.381250,0.468750,0.025000,0.025000},{0.381250,0.468750,0.050000,0.050000},{0.393750,0.468750,0.025000,0.025000},{0.393750,0.468750,0.050000,0.050000},{0.406250,0.468750,0.025000,0.025000},{0.406250,0.468750,0.050000,0.050000},{0.418750,0.468750,0.025000,0.025000},{0.418750,0.468750,0.050000,0.050000},{0.431250,0.468750,0.025000,0.025000},{0.431250,0.468750,0.050000,0.050000},{0.443750,0.468750,0.025000,0.025000},{0.443750,0.468750,0.050000,0.050000},{0.456250,0.468750,0.025000,0.025000},{0.456250,0.468750,0.050000,0.050000},{0.468750,0.468750,0.025000,0.025000},{0.468750,0.468750,0.050000,0.050000},{0.481250,0.468750,0.025000,0.025000},{0.481250,0.468750,0.050000,0.050000},{0.493750,0.468750,0.025000,0.025000},{0.493750,0.468750,0.050000,0.050000},{0.506250,0.468750,0.025000,0.025000},{0.506250,0.468750,0.050000,0.050000},{0.518750,0.468750,0.025000,0.025000},{0.518750,0.468750,0.050000,0.050000},{0.531250,0.468750,0.025000,0.025000},{0.531250,0.468750,0.050000,0.050000},{0.543750,0.468750,0.025000,0.025000},{0.543750,0.468750,0.050000,0.050000},{0.556250,0.468750,0.025000,0.025000},{0.556250,0.468750,0.050000,0.050000},{0.568750,0.468750,0.025000,0.025000},{0.568750,0.468750,0.050000,0.050000},{0.581250,0.468750,0.025000,0.025000},{0.581250,0.468750,0.050000,0.050000},{0.593750,0.468750,0.025000,0.025000},{0.593750,0.468750,0.050000,0.050000},{0.606250,0.468750,0.025000,0.025000},{0.606250,0.468750,0.050000,0.050000},{0.618750,0.468750,0.025000,0.025000},{0.618750,0.468750,0.050000,0.050000},{0.631250,0.468750,0.025000,0.025000},{0.631250,0.468750,0.050000,0.050000},{0.643750,0.468750,0.025000,0.025000},{0.643750,0.468750,0.050000,0.050000},{0.656250,0.468750,0.025000,0.025000},{0.656250,0.468750,0.050000,0.050000},{0.668750,0.468750,0.025000,0.025000},{0.668750,0.468750,0.050000,0.050000},{0.681250,0.468750,0.025000,0.025000},{0.681250,0.468750,0.050000,0.050000},{0.693750,0.468750,0.025000,0.025000},{0.693750,0.468750,0.050000,0.050000},{0.706250,0.468750,0.025000,0.025000},{0.706250,0.468750,0.050000,0.050000},{0.718750,0.468750,0.025000,0.025000},{0.718750,0.468750,0.050000,0.050000},{0.731250,0.468750,0.025000,0.025000},{0.731250,0.468750,0.050000,0.050000},{0.743750,0.468750,0.025000,0.025000},{0.743750,0.468750,0.050000,0.050000},{0.756250,0.468750,0.025000,0.025000},{0.756250,0.468750,0.050000,0.050000},{0.768750,0.468750,0.025000,0.025000},{0.768750,0.468750,0.050000,0.050000},{0.781250,0.468750,0.025000,0.025000},{0.781250,0.468750,0.050000,0.050000},{0.793750,0.468750,0.025000,0.025000},{0.793750,0.468750,0.050000,0.050000},{0.806250,0.468750,0.025000,0.025000},{0.806250,0.468750,0.050000,0.050000},{0.818750,0.468750,0.025000,0.025000},{0.818750,0.468750,0.050000,0.050000},{0.831250,0.468750,0.025000,0.025000},{0.831250,0.468750,0.050000,0.050000},{0.843750,0.468750,0.025000,0.025000},{0.843750,0.468750,0.050000,0.050000},{0.856250,0.468750,0.025000,0.025000},{0.856250,0.468750,0.050000,0.050000},{0.868750,0.468750,0.025000,0.025000},{0.868750,0.468750,0.050000,0.050000},{0.881250,0.468750,0.025000,0.025000},{0.881250,0.468750,0.050000,0.050000},{0.893750,0.468750,0.025000,0.025000},{0.893750,0.468750,0.050000,0.050000},{0.906250,0.468750,0.025000,0.025000},{0.906250,0.468750,0.050000,0.050000},{0.918750,0.468750,0.025000,0.025000},{0.918750,0.468750,0.050000,0.050000},{0.931250,0.468750,0.025000,0.025000},{0.931250,0.468750,0.050000,0.050000},{0.943750,0.468750,0.025000,0.025000},{0.943750,0.468750,0.050000,0.050000},{0.956250,0.468750,0.025000,0.025000},{0.956250,0.468750,0.050000,0.050000},{0.968750,0.468750,0.025000,0.025000},{0.968750,0.468750,0.050000,0.050000},{0.981250,0.468750,0.025000,0.025000},{0.981250,0.468750,0.050000,0.050000},{0.993750,0.468750,0.025000,0.025000},{0.993750,0.468750,0.050000,0.050000},{0.006250,0.481250,0.025000,0.025000},{0.006250,0.481250,0.050000,0.050000},{0.018750,0.481250,0.025000,0.025000},{0.018750,0.481250,0.050000,0.050000},{0.031250,0.481250,0.025000,0.025000},{0.031250,0.481250,0.050000,0.050000},{0.043750,0.481250,0.025000,0.025000},{0.043750,0.481250,0.050000,0.050000},{0.056250,0.481250,0.025000,0.025000},{0.056250,0.481250,0.050000,0.050000},{0.068750,0.481250,0.025000,0.025000},{0.068750,0.481250,0.050000,0.050000},{0.081250,0.481250,0.025000,0.025000},{0.081250,0.481250,0.050000,0.050000},{0.093750,0.481250,0.025000,0.025000},{0.093750,0.481250,0.050000,0.050000},{0.106250,0.481250,0.025000,0.025000},{0.106250,0.481250,0.050000,0.050000},{0.118750,0.481250,0.025000,0.025000},{0.118750,0.481250,0.050000,0.050000},{0.131250,0.481250,0.025000,0.025000},{0.131250,0.481250,0.050000,0.050000},{0.143750,0.481250,0.025000,0.025000},{0.143750,0.481250,0.050000,0.050000},{0.156250,0.481250,0.025000,0.025000},{0.156250,0.481250,0.050000,0.050000},{0.168750,0.481250,0.025000,0.025000},{0.168750,0.481250,0.050000,0.050000},{0.181250,0.481250,0.025000,0.025000},{0.181250,0.481250,0.050000,0.050000},{0.193750,0.481250,0.025000,0.025000},{0.193750,0.481250,0.050000,0.050000},{0.206250,0.481250,0.025000,0.025000},{0.206250,0.481250,0.050000,0.050000},{0.218750,0.481250,0.025000,0.025000},{0.218750,0.481250,0.050000,0.050000},{0.231250,0.481250,0.025000,0.025000},{0.231250,0.481250,0.050000,0.050000},{0.243750,0.481250,0.025000,0.025000},{0.243750,0.481250,0.050000,0.050000},{0.256250,0.481250,0.025000,0.025000},{0.256250,0.481250,0.050000,0.050000},{0.268750,0.481250,0.025000,0.025000},{0.268750,0.481250,0.050000,0.050000},{0.281250,0.481250,0.025000,0.025000},{0.281250,0.481250,0.050000,0.050000},{0.293750,0.481250,0.025000,0.025000},{0.293750,0.481250,0.050000,0.050000},{0.306250,0.481250,0.025000,0.025000},{0.306250,0.481250,0.050000,0.050000},{0.318750,0.481250,0.025000,0.025000},{0.318750,0.481250,0.050000,0.050000},{0.331250,0.481250,0.025000,0.025000},{0.331250,0.481250,0.050000,0.050000},{0.343750,0.481250,0.025000,0.025000},{0.343750,0.481250,0.050000,0.050000},{0.356250,0.481250,0.025000,0.025000},{0.356250,0.481250,0.050000,0.050000},{0.368750,0.481250,0.025000,0.025000},{0.368750,0.481250,0.050000,0.050000},{0.381250,0.481250,0.025000,0.025000},{0.381250,0.481250,0.050000,0.050000},{0.393750,0.481250,0.025000,0.025000},{0.393750,0.481250,0.050000,0.050000},{0.406250,0.481250,0.025000,0.025000},{0.406250,0.481250,0.050000,0.050000},{0.418750,0.481250,0.025000,0.025000},{0.418750,0.481250,0.050000,0.050000},{0.431250,0.481250,0.025000,0.025000},{0.431250,0.481250,0.050000,0.050000},{0.443750,0.481250,0.025000,0.025000},{0.443750,0.481250,0.050000,0.050000},{0.456250,0.481250,0.025000,0.025000},{0.456250,0.481250,0.050000,0.050000},{0.468750,0.481250,0.025000,0.025000},{0.468750,0.481250,0.050000,0.050000},{0.481250,0.481250,0.025000,0.025000},{0.481250,0.481250,0.050000,0.050000},{0.493750,0.481250,0.025000,0.025000},{0.493750,0.481250,0.050000,0.050000},{0.506250,0.481250,0.025000,0.025000},{0.506250,0.481250,0.050000,0.050000},{0.518750,0.481250,0.025000,0.025000},{0.518750,0.481250,0.050000,0.050000},{0.531250,0.481250,0.025000,0.025000},{0.531250,0.481250,0.050000,0.050000},{0.543750,0.481250,0.025000,0.025000},{0.543750,0.481250,0.050000,0.050000},{0.556250,0.481250,0.025000,0.025000},{0.556250,0.481250,0.050000,0.050000},{0.568750,0.481250,0.025000,0.025000},{0.568750,0.481250,0.050000,0.050000},{0.581250,0.481250,0.025000,0.025000},{0.581250,0.481250,0.050000,0.050000},{0.593750,0.481250,0.025000,0.025000},{0.593750,0.481250,0.050000,0.050000},{0.606250,0.481250,0.025000,0.025000},{0.606250,0.481250,0.050000,0.050000},{0.618750,0.481250,0.025000,0.025000},{0.618750,0.481250,0.050000,0.050000},{0.631250,0.481250,0.025000,0.025000},{0.631250,0.481250,0.050000,0.050000},{0.643750,0.481250,0.025000,0.025000},{0.643750,0.481250,0.050000,0.050000},{0.656250,0.481250,0.025000,0.025000},{0.656250,0.481250,0.050000,0.050000},{0.668750,0.481250,0.025000,0.025000},{0.668750,0.481250,0.050000,0.050000},{0.681250,0.481250,0.025000,0.025000},{0.681250,0.481250,0.050000,0.050000},{0.693750,0.481250,0.025000,0.025000},{0.693750,0.481250,0.050000,0.050000},{0.706250,0.481250,0.025000,0.025000},{0.706250,0.481250,0.050000,0.050000},{0.718750,0.481250,0.025000,0.025000},{0.718750,0.481250,0.050000,0.050000},{0.731250,0.481250,0.025000,0.025000},{0.731250,0.481250,0.050000,0.050000},{0.743750,0.481250,0.025000,0.025000},{0.743750,0.481250,0.050000,0.050000},{0.756250,0.481250,0.025000,0.025000},{0.756250,0.481250,0.050000,0.050000},{0.768750,0.481250,0.025000,0.025000},{0.768750,0.481250,0.050000,0.050000},{0.781250,0.481250,0.025000,0.025000},{0.781250,0.481250,0.050000,0.050000},{0.793750,0.481250,0.025000,0.025000},{0.793750,0.481250,0.050000,0.050000},{0.806250,0.481250,0.025000,0.025000},{0.806250,0.481250,0.050000,0.050000},{0.818750,0.481250,0.025000,0.025000},{0.818750,0.481250,0.050000,0.050000},{0.831250,0.481250,0.025000,0.025000},{0.831250,0.481250,0.050000,0.050000},{0.843750,0.481250,0.025000,0.025000},{0.843750,0.481250,0.050000,0.050000},{0.856250,0.481250,0.025000,0.025000},{0.856250,0.481250,0.050000,0.050000},{0.868750,0.481250,0.025000,0.025000},{0.868750,0.481250,0.050000,0.050000},{0.881250,0.481250,0.025000,0.025000},{0.881250,0.481250,0.050000,0.050000},{0.893750,0.481250,0.025000,0.025000},{0.893750,0.481250,0.050000,0.050000},{0.906250,0.481250,0.025000,0.025000},{0.906250,0.481250,0.050000,0.050000},{0.918750,0.481250,0.025000,0.025000},{0.918750,0.481250,0.050000,0.050000},{0.931250,0.481250,0.025000,0.025000},{0.931250,0.481250,0.050000,0.050000},{0.943750,0.481250,0.025000,0.025000},{0.943750,0.481250,0.050000,0.050000},{0.956250,0.481250,0.025000,0.025000},{0.956250,0.481250,0.050000,0.050000},{0.968750,0.481250,0.025000,0.025000},{0.968750,0.481250,0.050000,0.050000},{0.981250,0.481250,0.025000,0.025000},{0.981250,0.481250,0.050000,0.050000},{0.993750,0.481250,0.025000,0.025000},{0.993750,0.481250,0.050000,0.050000},{0.006250,0.493750,0.025000,0.025000},{0.006250,0.493750,0.050000,0.050000},{0.018750,0.493750,0.025000,0.025000},{0.018750,0.493750,0.050000,0.050000},{0.031250,0.493750,0.025000,0.025000},{0.031250,0.493750,0.050000,0.050000},{0.043750,0.493750,0.025000,0.025000},{0.043750,0.493750,0.050000,0.050000},{0.056250,0.493750,0.025000,0.025000},{0.056250,0.493750,0.050000,0.050000},{0.068750,0.493750,0.025000,0.025000},{0.068750,0.493750,0.050000,0.050000},{0.081250,0.493750,0.025000,0.025000},{0.081250,0.493750,0.050000,0.050000},{0.093750,0.493750,0.025000,0.025000},{0.093750,0.493750,0.050000,0.050000},{0.106250,0.493750,0.025000,0.025000},{0.106250,0.493750,0.050000,0.050000},{0.118750,0.493750,0.025000,0.025000},{0.118750,0.493750,0.050000,0.050000},{0.131250,0.493750,0.025000,0.025000},{0.131250,0.493750,0.050000,0.050000},{0.143750,0.493750,0.025000,0.025000},{0.143750,0.493750,0.050000,0.050000},{0.156250,0.493750,0.025000,0.025000},{0.156250,0.493750,0.050000,0.050000},{0.168750,0.493750,0.025000,0.025000},{0.168750,0.493750,0.050000,0.050000},{0.181250,0.493750,0.025000,0.025000},{0.181250,0.493750,0.050000,0.050000},{0.193750,0.493750,0.025000,0.025000},{0.193750,0.493750,0.050000,0.050000},{0.206250,0.493750,0.025000,0.025000},{0.206250,0.493750,0.050000,0.050000},{0.218750,0.493750,0.025000,0.025000},{0.218750,0.493750,0.050000,0.050000},{0.231250,0.493750,0.025000,0.025000},{0.231250,0.493750,0.050000,0.050000},{0.243750,0.493750,0.025000,0.025000},{0.243750,0.493750,0.050000,0.050000},{0.256250,0.493750,0.025000,0.025000},{0.256250,0.493750,0.050000,0.050000},{0.268750,0.493750,0.025000,0.025000},{0.268750,0.493750,0.050000,0.050000},{0.281250,0.493750,0.025000,0.025000},{0.281250,0.493750,0.050000,0.050000},{0.293750,0.493750,0.025000,0.025000},{0.293750,0.493750,0.050000,0.050000},{0.306250,0.493750,0.025000,0.025000},{0.306250,0.493750,0.050000,0.050000},{0.318750,0.493750,0.025000,0.025000},{0.318750,0.493750,0.050000,0.050000},{0.331250,0.493750,0.025000,0.025000},{0.331250,0.493750,0.050000,0.050000},{0.343750,0.493750,0.025000,0.025000},{0.343750,0.493750,0.050000,0.050000},{0.356250,0.493750,0.025000,0.025000},{0.356250,0.493750,0.050000,0.050000},{0.368750,0.493750,0.025000,0.025000},{0.368750,0.493750,0.050000,0.050000},{0.381250,0.493750,0.025000,0.025000},{0.381250,0.493750,0.050000,0.050000},{0.393750,0.493750,0.025000,0.025000},{0.393750,0.493750,0.050000,0.050000},{0.406250,0.493750,0.025000,0.025000},{0.406250,0.493750,0.050000,0.050000},{0.418750,0.493750,0.025000,0.025000},{0.418750,0.493750,0.050000,0.050000},{0.431250,0.493750,0.025000,0.025000},{0.431250,0.493750,0.050000,0.050000},{0.443750,0.493750,0.025000,0.025000},{0.443750,0.493750,0.050000,0.050000},{0.456250,0.493750,0.025000,0.025000},{0.456250,0.493750,0.050000,0.050000},{0.468750,0.493750,0.025000,0.025000},{0.468750,0.493750,0.050000,0.050000},{0.481250,0.493750,0.025000,0.025000},{0.481250,0.493750,0.050000,0.050000},{0.493750,0.493750,0.025000,0.025000},{0.493750,0.493750,0.050000,0.050000},{0.506250,0.493750,0.025000,0.025000},{0.506250,0.493750,0.050000,0.050000},{0.518750,0.493750,0.025000,0.025000},{0.518750,0.493750,0.050000,0.050000},{0.531250,0.493750,0.025000,0.025000},{0.531250,0.493750,0.050000,0.050000},{0.543750,0.493750,0.025000,0.025000},{0.543750,0.493750,0.050000,0.050000},{0.556250,0.493750,0.025000,0.025000},{0.556250,0.493750,0.050000,0.050000},{0.568750,0.493750,0.025000,0.025000},{0.568750,0.493750,0.050000,0.050000},{0.581250,0.493750,0.025000,0.025000},{0.581250,0.493750,0.050000,0.050000},{0.593750,0.493750,0.025000,0.025000},{0.593750,0.493750,0.050000,0.050000},{0.606250,0.493750,0.025000,0.025000},{0.606250,0.493750,0.050000,0.050000},{0.618750,0.493750,0.025000,0.025000},{0.618750,0.493750,0.050000,0.050000},{0.631250,0.493750,0.025000,0.025000},{0.631250,0.493750,0.050000,0.050000},{0.643750,0.493750,0.025000,0.025000},{0.643750,0.493750,0.050000,0.050000},{0.656250,0.493750,0.025000,0.025000},{0.656250,0.493750,0.050000,0.050000},{0.668750,0.493750,0.025000,0.025000},{0.668750,0.493750,0.050000,0.050000},{0.681250,0.493750,0.025000,0.025000},{0.681250,0.493750,0.050000,0.050000},{0.693750,0.493750,0.025000,0.025000},{0.693750,0.493750,0.050000,0.050000},{0.706250,0.493750,0.025000,0.025000},{0.706250,0.493750,0.050000,0.050000},{0.718750,0.493750,0.025000,0.025000},{0.718750,0.493750,0.050000,0.050000},{0.731250,0.493750,0.025000,0.025000},{0.731250,0.493750,0.050000,0.050000},{0.743750,0.493750,0.025000,0.025000},{0.743750,0.493750,0.050000,0.050000},{0.756250,0.493750,0.025000,0.025000},{0.756250,0.493750,0.050000,0.050000},{0.768750,0.493750,0.025000,0.025000},{0.768750,0.493750,0.050000,0.050000},{0.781250,0.493750,0.025000,0.025000},{0.781250,0.493750,0.050000,0.050000},{0.793750,0.493750,0.025000,0.025000},{0.793750,0.493750,0.050000,0.050000},{0.806250,0.493750,0.025000,0.025000},{0.806250,0.493750,0.050000,0.050000},{0.818750,0.493750,0.025000,0.025000},{0.818750,0.493750,0.050000,0.050000},{0.831250,0.493750,0.025000,0.025000},{0.831250,0.493750,0.050000,0.050000},{0.843750,0.493750,0.025000,0.025000},{0.843750,0.493750,0.050000,0.050000},{0.856250,0.493750,0.025000,0.025000},{0.856250,0.493750,0.050000,0.050000},{0.868750,0.493750,0.025000,0.025000},{0.868750,0.493750,0.050000,0.050000},{0.881250,0.493750,0.025000,0.025000},{0.881250,0.493750,0.050000,0.050000},{0.893750,0.493750,0.025000,0.025000},{0.893750,0.493750,0.050000,0.050000},{0.906250,0.493750,0.025000,0.025000},{0.906250,0.493750,0.050000,0.050000},{0.918750,0.493750,0.025000,0.025000},{0.918750,0.493750,0.050000,0.050000},{0.931250,0.493750,0.025000,0.025000},{0.931250,0.493750,0.050000,0.050000},{0.943750,0.493750,0.025000,0.025000},{0.943750,0.493750,0.050000,0.050000},{0.956250,0.493750,0.025000,0.025000},{0.956250,0.493750,0.050000,0.050000},{0.968750,0.493750,0.025000,0.025000},{0.968750,0.493750,0.050000,0.050000},{0.981250,0.493750,0.025000,0.025000},{0.981250,0.493750,0.050000,0.050000},{0.993750,0.493750,0.025000,0.025000},{0.993750,0.493750,0.050000,0.050000},{0.006250,0.506250,0.025000,0.025000},{0.006250,0.506250,0.050000,0.050000},{0.018750,0.506250,0.025000,0.025000},{0.018750,0.506250,0.050000,0.050000},{0.031250,0.506250,0.025000,0.025000},{0.031250,0.506250,0.050000,0.050000},{0.043750,0.506250,0.025000,0.025000},{0.043750,0.506250,0.050000,0.050000},{0.056250,0.506250,0.025000,0.025000},{0.056250,0.506250,0.050000,0.050000},{0.068750,0.506250,0.025000,0.025000},{0.068750,0.506250,0.050000,0.050000},{0.081250,0.506250,0.025000,0.025000},{0.081250,0.506250,0.050000,0.050000},{0.093750,0.506250,0.025000,0.025000},{0.093750,0.506250,0.050000,0.050000},{0.106250,0.506250,0.025000,0.025000},{0.106250,0.506250,0.050000,0.050000},{0.118750,0.506250,0.025000,0.025000},{0.118750,0.506250,0.050000,0.050000},{0.131250,0.506250,0.025000,0.025000},{0.131250,0.506250,0.050000,0.050000},{0.143750,0.506250,0.025000,0.025000},{0.143750,0.506250,0.050000,0.050000},{0.156250,0.506250,0.025000,0.025000},{0.156250,0.506250,0.050000,0.050000},{0.168750,0.506250,0.025000,0.025000},{0.168750,0.506250,0.050000,0.050000},{0.181250,0.506250,0.025000,0.025000},{0.181250,0.506250,0.050000,0.050000},{0.193750,0.506250,0.025000,0.025000},{0.193750,0.506250,0.050000,0.050000},{0.206250,0.506250,0.025000,0.025000},{0.206250,0.506250,0.050000,0.050000},{0.218750,0.506250,0.025000,0.025000},{0.218750,0.506250,0.050000,0.050000},{0.231250,0.506250,0.025000,0.025000},{0.231250,0.506250,0.050000,0.050000},{0.243750,0.506250,0.025000,0.025000},{0.243750,0.506250,0.050000,0.050000},{0.256250,0.506250,0.025000,0.025000},{0.256250,0.506250,0.050000,0.050000},{0.268750,0.506250,0.025000,0.025000},{0.268750,0.506250,0.050000,0.050000},{0.281250,0.506250,0.025000,0.025000},{0.281250,0.506250,0.050000,0.050000},{0.293750,0.506250,0.025000,0.025000},{0.293750,0.506250,0.050000,0.050000},{0.306250,0.506250,0.025000,0.025000},{0.306250,0.506250,0.050000,0.050000},{0.318750,0.506250,0.025000,0.025000},{0.318750,0.506250,0.050000,0.050000},{0.331250,0.506250,0.025000,0.025000},{0.331250,0.506250,0.050000,0.050000},{0.343750,0.506250,0.025000,0.025000},{0.343750,0.506250,0.050000,0.050000},{0.356250,0.506250,0.025000,0.025000},{0.356250,0.506250,0.050000,0.050000},{0.368750,0.506250,0.025000,0.025000},{0.368750,0.506250,0.050000,0.050000},{0.381250,0.506250,0.025000,0.025000},{0.381250,0.506250,0.050000,0.050000},{0.393750,0.506250,0.025000,0.025000},{0.393750,0.506250,0.050000,0.050000},{0.406250,0.506250,0.025000,0.025000},{0.406250,0.506250,0.050000,0.050000},{0.418750,0.506250,0.025000,0.025000},{0.418750,0.506250,0.050000,0.050000},{0.431250,0.506250,0.025000,0.025000},{0.431250,0.506250,0.050000,0.050000},{0.443750,0.506250,0.025000,0.025000},{0.443750,0.506250,0.050000,0.050000},{0.456250,0.506250,0.025000,0.025000},{0.456250,0.506250,0.050000,0.050000},{0.468750,0.506250,0.025000,0.025000},{0.468750,0.506250,0.050000,0.050000},{0.481250,0.506250,0.025000,0.025000},{0.481250,0.506250,0.050000,0.050000},{0.493750,0.506250,0.025000,0.025000},{0.493750,0.506250,0.050000,0.050000},{0.506250,0.506250,0.025000,0.025000},{0.506250,0.506250,0.050000,0.050000},{0.518750,0.506250,0.025000,0.025000},{0.518750,0.506250,0.050000,0.050000},{0.531250,0.506250,0.025000,0.025000},{0.531250,0.506250,0.050000,0.050000},{0.543750,0.506250,0.025000,0.025000},{0.543750,0.506250,0.050000,0.050000},{0.556250,0.506250,0.025000,0.025000},{0.556250,0.506250,0.050000,0.050000},{0.568750,0.506250,0.025000,0.025000},{0.568750,0.506250,0.050000,0.050000},{0.581250,0.506250,0.025000,0.025000},{0.581250,0.506250,0.050000,0.050000},{0.593750,0.506250,0.025000,0.025000},{0.593750,0.506250,0.050000,0.050000},{0.606250,0.506250,0.025000,0.025000},{0.606250,0.506250,0.050000,0.050000},{0.618750,0.506250,0.025000,0.025000},{0.618750,0.506250,0.050000,0.050000},{0.631250,0.506250,0.025000,0.025000},{0.631250,0.506250,0.050000,0.050000},{0.643750,0.506250,0.025000,0.025000},{0.643750,0.506250,0.050000,0.050000},{0.656250,0.506250,0.025000,0.025000},{0.656250,0.506250,0.050000,0.050000},{0.668750,0.506250,0.025000,0.025000},{0.668750,0.506250,0.050000,0.050000},{0.681250,0.506250,0.025000,0.025000},{0.681250,0.506250,0.050000,0.050000},{0.693750,0.506250,0.025000,0.025000},{0.693750,0.506250,0.050000,0.050000},{0.706250,0.506250,0.025000,0.025000},{0.706250,0.506250,0.050000,0.050000},{0.718750,0.506250,0.025000,0.025000},{0.718750,0.506250,0.050000,0.050000},{0.731250,0.506250,0.025000,0.025000},{0.731250,0.506250,0.050000,0.050000},{0.743750,0.506250,0.025000,0.025000},{0.743750,0.506250,0.050000,0.050000},{0.756250,0.506250,0.025000,0.025000},{0.756250,0.506250,0.050000,0.050000},{0.768750,0.506250,0.025000,0.025000},{0.768750,0.506250,0.050000,0.050000},{0.781250,0.506250,0.025000,0.025000},{0.781250,0.506250,0.050000,0.050000},{0.793750,0.506250,0.025000,0.025000},{0.793750,0.506250,0.050000,0.050000},{0.806250,0.506250,0.025000,0.025000},{0.806250,0.506250,0.050000,0.050000},{0.818750,0.506250,0.025000,0.025000},{0.818750,0.506250,0.050000,0.050000},{0.831250,0.506250,0.025000,0.025000},{0.831250,0.506250,0.050000,0.050000},{0.843750,0.506250,0.025000,0.025000},{0.843750,0.506250,0.050000,0.050000},{0.856250,0.506250,0.025000,0.025000},{0.856250,0.506250,0.050000,0.050000},{0.868750,0.506250,0.025000,0.025000},{0.868750,0.506250,0.050000,0.050000},{0.881250,0.506250,0.025000,0.025000},{0.881250,0.506250,0.050000,0.050000},{0.893750,0.506250,0.025000,0.025000},{0.893750,0.506250,0.050000,0.050000},{0.906250,0.506250,0.025000,0.025000},{0.906250,0.506250,0.050000,0.050000},{0.918750,0.506250,0.025000,0.025000},{0.918750,0.506250,0.050000,0.050000},{0.931250,0.506250,0.025000,0.025000},{0.931250,0.506250,0.050000,0.050000},{0.943750,0.506250,0.025000,0.025000},{0.943750,0.506250,0.050000,0.050000},{0.956250,0.506250,0.025000,0.025000},{0.956250,0.506250,0.050000,0.050000},{0.968750,0.506250,0.025000,0.025000},{0.968750,0.506250,0.050000,0.050000},{0.981250,0.506250,0.025000,0.025000},{0.981250,0.506250,0.050000,0.050000},{0.993750,0.506250,0.025000,0.025000},{0.993750,0.506250,0.050000,0.050000},{0.006250,0.518750,0.025000,0.025000},{0.006250,0.518750,0.050000,0.050000},{0.018750,0.518750,0.025000,0.025000},{0.018750,0.518750,0.050000,0.050000},{0.031250,0.518750,0.025000,0.025000},{0.031250,0.518750,0.050000,0.050000},{0.043750,0.518750,0.025000,0.025000},{0.043750,0.518750,0.050000,0.050000},{0.056250,0.518750,0.025000,0.025000},{0.056250,0.518750,0.050000,0.050000},{0.068750,0.518750,0.025000,0.025000},{0.068750,0.518750,0.050000,0.050000},{0.081250,0.518750,0.025000,0.025000},{0.081250,0.518750,0.050000,0.050000},{0.093750,0.518750,0.025000,0.025000},{0.093750,0.518750,0.050000,0.050000},{0.106250,0.518750,0.025000,0.025000},{0.106250,0.518750,0.050000,0.050000},{0.118750,0.518750,0.025000,0.025000},{0.118750,0.518750,0.050000,0.050000},{0.131250,0.518750,0.025000,0.025000},{0.131250,0.518750,0.050000,0.050000},{0.143750,0.518750,0.025000,0.025000},{0.143750,0.518750,0.050000,0.050000},{0.156250,0.518750,0.025000,0.025000},{0.156250,0.518750,0.050000,0.050000},{0.168750,0.518750,0.025000,0.025000},{0.168750,0.518750,0.050000,0.050000},{0.181250,0.518750,0.025000,0.025000},{0.181250,0.518750,0.050000,0.050000},{0.193750,0.518750,0.025000,0.025000},{0.193750,0.518750,0.050000,0.050000},{0.206250,0.518750,0.025000,0.025000},{0.206250,0.518750,0.050000,0.050000},{0.218750,0.518750,0.025000,0.025000},{0.218750,0.518750,0.050000,0.050000},{0.231250,0.518750,0.025000,0.025000},{0.231250,0.518750,0.050000,0.050000},{0.243750,0.518750,0.025000,0.025000},{0.243750,0.518750,0.050000,0.050000},{0.256250,0.518750,0.025000,0.025000},{0.256250,0.518750,0.050000,0.050000},{0.268750,0.518750,0.025000,0.025000},{0.268750,0.518750,0.050000,0.050000},{0.281250,0.518750,0.025000,0.025000},{0.281250,0.518750,0.050000,0.050000},{0.293750,0.518750,0.025000,0.025000},{0.293750,0.518750,0.050000,0.050000},{0.306250,0.518750,0.025000,0.025000},{0.306250,0.518750,0.050000,0.050000},{0.318750,0.518750,0.025000,0.025000},{0.318750,0.518750,0.050000,0.050000},{0.331250,0.518750,0.025000,0.025000},{0.331250,0.518750,0.050000,0.050000},{0.343750,0.518750,0.025000,0.025000},{0.343750,0.518750,0.050000,0.050000},{0.356250,0.518750,0.025000,0.025000},{0.356250,0.518750,0.050000,0.050000},{0.368750,0.518750,0.025000,0.025000},{0.368750,0.518750,0.050000,0.050000},{0.381250,0.518750,0.025000,0.025000},{0.381250,0.518750,0.050000,0.050000},{0.393750,0.518750,0.025000,0.025000},{0.393750,0.518750,0.050000,0.050000},{0.406250,0.518750,0.025000,0.025000},{0.406250,0.518750,0.050000,0.050000},{0.418750,0.518750,0.025000,0.025000},{0.418750,0.518750,0.050000,0.050000},{0.431250,0.518750,0.025000,0.025000},{0.431250,0.518750,0.050000,0.050000},{0.443750,0.518750,0.025000,0.025000},{0.443750,0.518750,0.050000,0.050000},{0.456250,0.518750,0.025000,0.025000},{0.456250,0.518750,0.050000,0.050000},{0.468750,0.518750,0.025000,0.025000},{0.468750,0.518750,0.050000,0.050000},{0.481250,0.518750,0.025000,0.025000},{0.481250,0.518750,0.050000,0.050000},{0.493750,0.518750,0.025000,0.025000},{0.493750,0.518750,0.050000,0.050000},{0.506250,0.518750,0.025000,0.025000},{0.506250,0.518750,0.050000,0.050000},{0.518750,0.518750,0.025000,0.025000},{0.518750,0.518750,0.050000,0.050000},{0.531250,0.518750,0.025000,0.025000},{0.531250,0.518750,0.050000,0.050000},{0.543750,0.518750,0.025000,0.025000},{0.543750,0.518750,0.050000,0.050000},{0.556250,0.518750,0.025000,0.025000},{0.556250,0.518750,0.050000,0.050000},{0.568750,0.518750,0.025000,0.025000},{0.568750,0.518750,0.050000,0.050000},{0.581250,0.518750,0.025000,0.025000},{0.581250,0.518750,0.050000,0.050000},{0.593750,0.518750,0.025000,0.025000},{0.593750,0.518750,0.050000,0.050000},{0.606250,0.518750,0.025000,0.025000},{0.606250,0.518750,0.050000,0.050000},{0.618750,0.518750,0.025000,0.025000},{0.618750,0.518750,0.050000,0.050000},{0.631250,0.518750,0.025000,0.025000},{0.631250,0.518750,0.050000,0.050000},{0.643750,0.518750,0.025000,0.025000},{0.643750,0.518750,0.050000,0.050000},{0.656250,0.518750,0.025000,0.025000},{0.656250,0.518750,0.050000,0.050000},{0.668750,0.518750,0.025000,0.025000},{0.668750,0.518750,0.050000,0.050000},{0.681250,0.518750,0.025000,0.025000},{0.681250,0.518750,0.050000,0.050000},{0.693750,0.518750,0.025000,0.025000},{0.693750,0.518750,0.050000,0.050000},{0.706250,0.518750,0.025000,0.025000},{0.706250,0.518750,0.050000,0.050000},{0.718750,0.518750,0.025000,0.025000},{0.718750,0.518750,0.050000,0.050000},{0.731250,0.518750,0.025000,0.025000},{0.731250,0.518750,0.050000,0.050000},{0.743750,0.518750,0.025000,0.025000},{0.743750,0.518750,0.050000,0.050000},{0.756250,0.518750,0.025000,0.025000},{0.756250,0.518750,0.050000,0.050000},{0.768750,0.518750,0.025000,0.025000},{0.768750,0.518750,0.050000,0.050000},{0.781250,0.518750,0.025000,0.025000},{0.781250,0.518750,0.050000,0.050000},{0.793750,0.518750,0.025000,0.025000},{0.793750,0.518750,0.050000,0.050000},{0.806250,0.518750,0.025000,0.025000},{0.806250,0.518750,0.050000,0.050000},{0.818750,0.518750,0.025000,0.025000},{0.818750,0.518750,0.050000,0.050000},{0.831250,0.518750,0.025000,0.025000},{0.831250,0.518750,0.050000,0.050000},{0.843750,0.518750,0.025000,0.025000},{0.843750,0.518750,0.050000,0.050000},{0.856250,0.518750,0.025000,0.025000},{0.856250,0.518750,0.050000,0.050000},{0.868750,0.518750,0.025000,0.025000},{0.868750,0.518750,0.050000,0.050000},{0.881250,0.518750,0.025000,0.025000},{0.881250,0.518750,0.050000,0.050000},{0.893750,0.518750,0.025000,0.025000},{0.893750,0.518750,0.050000,0.050000},{0.906250,0.518750,0.025000,0.025000},{0.906250,0.518750,0.050000,0.050000},{0.918750,0.518750,0.025000,0.025000},{0.918750,0.518750,0.050000,0.050000},{0.931250,0.518750,0.025000,0.025000},{0.931250,0.518750,0.050000,0.050000},{0.943750,0.518750,0.025000,0.025000},{0.943750,0.518750,0.050000,0.050000},{0.956250,0.518750,0.025000,0.025000},{0.956250,0.518750,0.050000,0.050000},{0.968750,0.518750,0.025000,0.025000},{0.968750,0.518750,0.050000,0.050000},{0.981250,0.518750,0.025000,0.025000},{0.981250,0.518750,0.050000,0.050000},{0.993750,0.518750,0.025000,0.025000},{0.993750,0.518750,0.050000,0.050000},{0.006250,0.531250,0.025000,0.025000},{0.006250,0.531250,0.050000,0.050000},{0.018750,0.531250,0.025000,0.025000},{0.018750,0.531250,0.050000,0.050000},{0.031250,0.531250,0.025000,0.025000},{0.031250,0.531250,0.050000,0.050000},{0.043750,0.531250,0.025000,0.025000},{0.043750,0.531250,0.050000,0.050000},{0.056250,0.531250,0.025000,0.025000},{0.056250,0.531250,0.050000,0.050000},{0.068750,0.531250,0.025000,0.025000},{0.068750,0.531250,0.050000,0.050000},{0.081250,0.531250,0.025000,0.025000},{0.081250,0.531250,0.050000,0.050000},{0.093750,0.531250,0.025000,0.025000},{0.093750,0.531250,0.050000,0.050000},{0.106250,0.531250,0.025000,0.025000},{0.106250,0.531250,0.050000,0.050000},{0.118750,0.531250,0.025000,0.025000},{0.118750,0.531250,0.050000,0.050000},{0.131250,0.531250,0.025000,0.025000},{0.131250,0.531250,0.050000,0.050000},{0.143750,0.531250,0.025000,0.025000},{0.143750,0.531250,0.050000,0.050000},{0.156250,0.531250,0.025000,0.025000},{0.156250,0.531250,0.050000,0.050000},{0.168750,0.531250,0.025000,0.025000},{0.168750,0.531250,0.050000,0.050000},{0.181250,0.531250,0.025000,0.025000},{0.181250,0.531250,0.050000,0.050000},{0.193750,0.531250,0.025000,0.025000},{0.193750,0.531250,0.050000,0.050000},{0.206250,0.531250,0.025000,0.025000},{0.206250,0.531250,0.050000,0.050000},{0.218750,0.531250,0.025000,0.025000},{0.218750,0.531250,0.050000,0.050000},{0.231250,0.531250,0.025000,0.025000},{0.231250,0.531250,0.050000,0.050000},{0.243750,0.531250,0.025000,0.025000},{0.243750,0.531250,0.050000,0.050000},{0.256250,0.531250,0.025000,0.025000},{0.256250,0.531250,0.050000,0.050000},{0.268750,0.531250,0.025000,0.025000},{0.268750,0.531250,0.050000,0.050000},{0.281250,0.531250,0.025000,0.025000},{0.281250,0.531250,0.050000,0.050000},{0.293750,0.531250,0.025000,0.025000},{0.293750,0.531250,0.050000,0.050000},{0.306250,0.531250,0.025000,0.025000},{0.306250,0.531250,0.050000,0.050000},{0.318750,0.531250,0.025000,0.025000},{0.318750,0.531250,0.050000,0.050000},{0.331250,0.531250,0.025000,0.025000},{0.331250,0.531250,0.050000,0.050000},{0.343750,0.531250,0.025000,0.025000},{0.343750,0.531250,0.050000,0.050000},{0.356250,0.531250,0.025000,0.025000},{0.356250,0.531250,0.050000,0.050000},{0.368750,0.531250,0.025000,0.025000},{0.368750,0.531250,0.050000,0.050000},{0.381250,0.531250,0.025000,0.025000},{0.381250,0.531250,0.050000,0.050000},{0.393750,0.531250,0.025000,0.025000},{0.393750,0.531250,0.050000,0.050000},{0.406250,0.531250,0.025000,0.025000},{0.406250,0.531250,0.050000,0.050000},{0.418750,0.531250,0.025000,0.025000},{0.418750,0.531250,0.050000,0.050000},{0.431250,0.531250,0.025000,0.025000},{0.431250,0.531250,0.050000,0.050000},{0.443750,0.531250,0.025000,0.025000},{0.443750,0.531250,0.050000,0.050000},{0.456250,0.531250,0.025000,0.025000},{0.456250,0.531250,0.050000,0.050000},{0.468750,0.531250,0.025000,0.025000},{0.468750,0.531250,0.050000,0.050000},{0.481250,0.531250,0.025000,0.025000},{0.481250,0.531250,0.050000,0.050000},{0.493750,0.531250,0.025000,0.025000},{0.493750,0.531250,0.050000,0.050000},{0.506250,0.531250,0.025000,0.025000},{0.506250,0.531250,0.050000,0.050000},{0.518750,0.531250,0.025000,0.025000},{0.518750,0.531250,0.050000,0.050000},{0.531250,0.531250,0.025000,0.025000},{0.531250,0.531250,0.050000,0.050000},{0.543750,0.531250,0.025000,0.025000},{0.543750,0.531250,0.050000,0.050000},{0.556250,0.531250,0.025000,0.025000},{0.556250,0.531250,0.050000,0.050000},{0.568750,0.531250,0.025000,0.025000},{0.568750,0.531250,0.050000,0.050000},{0.581250,0.531250,0.025000,0.025000},{0.581250,0.531250,0.050000,0.050000},{0.593750,0.531250,0.025000,0.025000},{0.593750,0.531250,0.050000,0.050000},{0.606250,0.531250,0.025000,0.025000},{0.606250,0.531250,0.050000,0.050000},{0.618750,0.531250,0.025000,0.025000},{0.618750,0.531250,0.050000,0.050000},{0.631250,0.531250,0.025000,0.025000},{0.631250,0.531250,0.050000,0.050000},{0.643750,0.531250,0.025000,0.025000},{0.643750,0.531250,0.050000,0.050000},{0.656250,0.531250,0.025000,0.025000},{0.656250,0.531250,0.050000,0.050000},{0.668750,0.531250,0.025000,0.025000},{0.668750,0.531250,0.050000,0.050000},{0.681250,0.531250,0.025000,0.025000},{0.681250,0.531250,0.050000,0.050000},{0.693750,0.531250,0.025000,0.025000},{0.693750,0.531250,0.050000,0.050000},{0.706250,0.531250,0.025000,0.025000},{0.706250,0.531250,0.050000,0.050000},{0.718750,0.531250,0.025000,0.025000},{0.718750,0.531250,0.050000,0.050000},{0.731250,0.531250,0.025000,0.025000},{0.731250,0.531250,0.050000,0.050000},{0.743750,0.531250,0.025000,0.025000},{0.743750,0.531250,0.050000,0.050000},{0.756250,0.531250,0.025000,0.025000},{0.756250,0.531250,0.050000,0.050000},{0.768750,0.531250,0.025000,0.025000},{0.768750,0.531250,0.050000,0.050000},{0.781250,0.531250,0.025000,0.025000},{0.781250,0.531250,0.050000,0.050000},{0.793750,0.531250,0.025000,0.025000},{0.793750,0.531250,0.050000,0.050000},{0.806250,0.531250,0.025000,0.025000},{0.806250,0.531250,0.050000,0.050000},{0.818750,0.531250,0.025000,0.025000},{0.818750,0.531250,0.050000,0.050000},{0.831250,0.531250,0.025000,0.025000},{0.831250,0.531250,0.050000,0.050000},{0.843750,0.531250,0.025000,0.025000},{0.843750,0.531250,0.050000,0.050000},{0.856250,0.531250,0.025000,0.025000},{0.856250,0.531250,0.050000,0.050000},{0.868750,0.531250,0.025000,0.025000},{0.868750,0.531250,0.050000,0.050000},{0.881250,0.531250,0.025000,0.025000},{0.881250,0.531250,0.050000,0.050000},{0.893750,0.531250,0.025000,0.025000},{0.893750,0.531250,0.050000,0.050000},{0.906250,0.531250,0.025000,0.025000},{0.906250,0.531250,0.050000,0.050000},{0.918750,0.531250,0.025000,0.025000},{0.918750,0.531250,0.050000,0.050000},{0.931250,0.531250,0.025000,0.025000},{0.931250,0.531250,0.050000,0.050000},{0.943750,0.531250,0.025000,0.025000},{0.943750,0.531250,0.050000,0.050000},{0.956250,0.531250,0.025000,0.025000},{0.956250,0.531250,0.050000,0.050000},{0.968750,0.531250,0.025000,0.025000},{0.968750,0.531250,0.050000,0.050000},{0.981250,0.531250,0.025000,0.025000},{0.981250,0.531250,0.050000,0.050000},{0.993750,0.531250,0.025000,0.025000},{0.993750,0.531250,0.050000,0.050000},{0.006250,0.543750,0.025000,0.025000},{0.006250,0.543750,0.050000,0.050000},{0.018750,0.543750,0.025000,0.025000},{0.018750,0.543750,0.050000,0.050000},{0.031250,0.543750,0.025000,0.025000},{0.031250,0.543750,0.050000,0.050000},{0.043750,0.543750,0.025000,0.025000},{0.043750,0.543750,0.050000,0.050000},{0.056250,0.543750,0.025000,0.025000},{0.056250,0.543750,0.050000,0.050000},{0.068750,0.543750,0.025000,0.025000},{0.068750,0.543750,0.050000,0.050000},{0.081250,0.543750,0.025000,0.025000},{0.081250,0.543750,0.050000,0.050000},{0.093750,0.543750,0.025000,0.025000},{0.093750,0.543750,0.050000,0.050000},{0.106250,0.543750,0.025000,0.025000},{0.106250,0.543750,0.050000,0.050000},{0.118750,0.543750,0.025000,0.025000},{0.118750,0.543750,0.050000,0.050000},{0.131250,0.543750,0.025000,0.025000},{0.131250,0.543750,0.050000,0.050000},{0.143750,0.543750,0.025000,0.025000},{0.143750,0.543750,0.050000,0.050000},{0.156250,0.543750,0.025000,0.025000},{0.156250,0.543750,0.050000,0.050000},{0.168750,0.543750,0.025000,0.025000},{0.168750,0.543750,0.050000,0.050000},{0.181250,0.543750,0.025000,0.025000},{0.181250,0.543750,0.050000,0.050000},{0.193750,0.543750,0.025000,0.025000},{0.193750,0.543750,0.050000,0.050000},{0.206250,0.543750,0.025000,0.025000},{0.206250,0.543750,0.050000,0.050000},{0.218750,0.543750,0.025000,0.025000},{0.218750,0.543750,0.050000,0.050000},{0.231250,0.543750,0.025000,0.025000},{0.231250,0.543750,0.050000,0.050000},{0.243750,0.543750,0.025000,0.025000},{0.243750,0.543750,0.050000,0.050000},{0.256250,0.543750,0.025000,0.025000},{0.256250,0.543750,0.050000,0.050000},{0.268750,0.543750,0.025000,0.025000},{0.268750,0.543750,0.050000,0.050000},{0.281250,0.543750,0.025000,0.025000},{0.281250,0.543750,0.050000,0.050000},{0.293750,0.543750,0.025000,0.025000},{0.293750,0.543750,0.050000,0.050000},{0.306250,0.543750,0.025000,0.025000},{0.306250,0.543750,0.050000,0.050000},{0.318750,0.543750,0.025000,0.025000},{0.318750,0.543750,0.050000,0.050000},{0.331250,0.543750,0.025000,0.025000},{0.331250,0.543750,0.050000,0.050000},{0.343750,0.543750,0.025000,0.025000},{0.343750,0.543750,0.050000,0.050000},{0.356250,0.543750,0.025000,0.025000},{0.356250,0.543750,0.050000,0.050000},{0.368750,0.543750,0.025000,0.025000},{0.368750,0.543750,0.050000,0.050000},{0.381250,0.543750,0.025000,0.025000},{0.381250,0.543750,0.050000,0.050000},{0.393750,0.543750,0.025000,0.025000},{0.393750,0.543750,0.050000,0.050000},{0.406250,0.543750,0.025000,0.025000},{0.406250,0.543750,0.050000,0.050000},{0.418750,0.543750,0.025000,0.025000},{0.418750,0.543750,0.050000,0.050000},{0.431250,0.543750,0.025000,0.025000},{0.431250,0.543750,0.050000,0.050000},{0.443750,0.543750,0.025000,0.025000},{0.443750,0.543750,0.050000,0.050000},{0.456250,0.543750,0.025000,0.025000},{0.456250,0.543750,0.050000,0.050000},{0.468750,0.543750,0.025000,0.025000},{0.468750,0.543750,0.050000,0.050000},{0.481250,0.543750,0.025000,0.025000},{0.481250,0.543750,0.050000,0.050000},{0.493750,0.543750,0.025000,0.025000},{0.493750,0.543750,0.050000,0.050000},{0.506250,0.543750,0.025000,0.025000},{0.506250,0.543750,0.050000,0.050000},{0.518750,0.543750,0.025000,0.025000},{0.518750,0.543750,0.050000,0.050000},{0.531250,0.543750,0.025000,0.025000},{0.531250,0.543750,0.050000,0.050000},{0.543750,0.543750,0.025000,0.025000},{0.543750,0.543750,0.050000,0.050000},{0.556250,0.543750,0.025000,0.025000},{0.556250,0.543750,0.050000,0.050000},{0.568750,0.543750,0.025000,0.025000},{0.568750,0.543750,0.050000,0.050000},{0.581250,0.543750,0.025000,0.025000},{0.581250,0.543750,0.050000,0.050000},{0.593750,0.543750,0.025000,0.025000},{0.593750,0.543750,0.050000,0.050000},{0.606250,0.543750,0.025000,0.025000},{0.606250,0.543750,0.050000,0.050000},{0.618750,0.543750,0.025000,0.025000},{0.618750,0.543750,0.050000,0.050000},{0.631250,0.543750,0.025000,0.025000},{0.631250,0.543750,0.050000,0.050000},{0.643750,0.543750,0.025000,0.025000},{0.643750,0.543750,0.050000,0.050000},{0.656250,0.543750,0.025000,0.025000},{0.656250,0.543750,0.050000,0.050000},{0.668750,0.543750,0.025000,0.025000},{0.668750,0.543750,0.050000,0.050000},{0.681250,0.543750,0.025000,0.025000},{0.681250,0.543750,0.050000,0.050000},{0.693750,0.543750,0.025000,0.025000},{0.693750,0.543750,0.050000,0.050000},{0.706250,0.543750,0.025000,0.025000},{0.706250,0.543750,0.050000,0.050000},{0.718750,0.543750,0.025000,0.025000},{0.718750,0.543750,0.050000,0.050000},{0.731250,0.543750,0.025000,0.025000},{0.731250,0.543750,0.050000,0.050000},{0.743750,0.543750,0.025000,0.025000},{0.743750,0.543750,0.050000,0.050000},{0.756250,0.543750,0.025000,0.025000},{0.756250,0.543750,0.050000,0.050000},{0.768750,0.543750,0.025000,0.025000},{0.768750,0.543750,0.050000,0.050000},{0.781250,0.543750,0.025000,0.025000},{0.781250,0.543750,0.050000,0.050000},{0.793750,0.543750,0.025000,0.025000},{0.793750,0.543750,0.050000,0.050000},{0.806250,0.543750,0.025000,0.025000},{0.806250,0.543750,0.050000,0.050000},{0.818750,0.543750,0.025000,0.025000},{0.818750,0.543750,0.050000,0.050000},{0.831250,0.543750,0.025000,0.025000},{0.831250,0.543750,0.050000,0.050000},{0.843750,0.543750,0.025000,0.025000},{0.843750,0.543750,0.050000,0.050000},{0.856250,0.543750,0.025000,0.025000},{0.856250,0.543750,0.050000,0.050000},{0.868750,0.543750,0.025000,0.025000},{0.868750,0.543750,0.050000,0.050000},{0.881250,0.543750,0.025000,0.025000},{0.881250,0.543750,0.050000,0.050000},{0.893750,0.543750,0.025000,0.025000},{0.893750,0.543750,0.050000,0.050000},{0.906250,0.543750,0.025000,0.025000},{0.906250,0.543750,0.050000,0.050000},{0.918750,0.543750,0.025000,0.025000},{0.918750,0.543750,0.050000,0.050000},{0.931250,0.543750,0.025000,0.025000},{0.931250,0.543750,0.050000,0.050000},{0.943750,0.543750,0.025000,0.025000},{0.943750,0.543750,0.050000,0.050000},{0.956250,0.543750,0.025000,0.025000},{0.956250,0.543750,0.050000,0.050000},{0.968750,0.543750,0.025000,0.025000},{0.968750,0.543750,0.050000,0.050000},{0.981250,0.543750,0.025000,0.025000},{0.981250,0.543750,0.050000,0.050000},{0.993750,0.543750,0.025000,0.025000},{0.993750,0.543750,0.050000,0.050000},{0.006250,0.556250,0.025000,0.025000},{0.006250,0.556250,0.050000,0.050000},{0.018750,0.556250,0.025000,0.025000},{0.018750,0.556250,0.050000,0.050000},{0.031250,0.556250,0.025000,0.025000},{0.031250,0.556250,0.050000,0.050000},{0.043750,0.556250,0.025000,0.025000},{0.043750,0.556250,0.050000,0.050000},{0.056250,0.556250,0.025000,0.025000},{0.056250,0.556250,0.050000,0.050000},{0.068750,0.556250,0.025000,0.025000},{0.068750,0.556250,0.050000,0.050000},{0.081250,0.556250,0.025000,0.025000},{0.081250,0.556250,0.050000,0.050000},{0.093750,0.556250,0.025000,0.025000},{0.093750,0.556250,0.050000,0.050000},{0.106250,0.556250,0.025000,0.025000},{0.106250,0.556250,0.050000,0.050000},{0.118750,0.556250,0.025000,0.025000},{0.118750,0.556250,0.050000,0.050000},{0.131250,0.556250,0.025000,0.025000},{0.131250,0.556250,0.050000,0.050000},{0.143750,0.556250,0.025000,0.025000},{0.143750,0.556250,0.050000,0.050000},{0.156250,0.556250,0.025000,0.025000},{0.156250,0.556250,0.050000,0.050000},{0.168750,0.556250,0.025000,0.025000},{0.168750,0.556250,0.050000,0.050000},{0.181250,0.556250,0.025000,0.025000},{0.181250,0.556250,0.050000,0.050000},{0.193750,0.556250,0.025000,0.025000},{0.193750,0.556250,0.050000,0.050000},{0.206250,0.556250,0.025000,0.025000},{0.206250,0.556250,0.050000,0.050000},{0.218750,0.556250,0.025000,0.025000},{0.218750,0.556250,0.050000,0.050000},{0.231250,0.556250,0.025000,0.025000},{0.231250,0.556250,0.050000,0.050000},{0.243750,0.556250,0.025000,0.025000},{0.243750,0.556250,0.050000,0.050000},{0.256250,0.556250,0.025000,0.025000},{0.256250,0.556250,0.050000,0.050000},{0.268750,0.556250,0.025000,0.025000},{0.268750,0.556250,0.050000,0.050000},{0.281250,0.556250,0.025000,0.025000},{0.281250,0.556250,0.050000,0.050000},{0.293750,0.556250,0.025000,0.025000},{0.293750,0.556250,0.050000,0.050000},{0.306250,0.556250,0.025000,0.025000},{0.306250,0.556250,0.050000,0.050000},{0.318750,0.556250,0.025000,0.025000},{0.318750,0.556250,0.050000,0.050000},{0.331250,0.556250,0.025000,0.025000},{0.331250,0.556250,0.050000,0.050000},{0.343750,0.556250,0.025000,0.025000},{0.343750,0.556250,0.050000,0.050000},{0.356250,0.556250,0.025000,0.025000},{0.356250,0.556250,0.050000,0.050000},{0.368750,0.556250,0.025000,0.025000},{0.368750,0.556250,0.050000,0.050000},{0.381250,0.556250,0.025000,0.025000},{0.381250,0.556250,0.050000,0.050000},{0.393750,0.556250,0.025000,0.025000},{0.393750,0.556250,0.050000,0.050000},{0.406250,0.556250,0.025000,0.025000},{0.406250,0.556250,0.050000,0.050000},{0.418750,0.556250,0.025000,0.025000},{0.418750,0.556250,0.050000,0.050000},{0.431250,0.556250,0.025000,0.025000},{0.431250,0.556250,0.050000,0.050000},{0.443750,0.556250,0.025000,0.025000},{0.443750,0.556250,0.050000,0.050000},{0.456250,0.556250,0.025000,0.025000},{0.456250,0.556250,0.050000,0.050000},{0.468750,0.556250,0.025000,0.025000},{0.468750,0.556250,0.050000,0.050000},{0.481250,0.556250,0.025000,0.025000},{0.481250,0.556250,0.050000,0.050000},{0.493750,0.556250,0.025000,0.025000},{0.493750,0.556250,0.050000,0.050000},{0.506250,0.556250,0.025000,0.025000},{0.506250,0.556250,0.050000,0.050000},{0.518750,0.556250,0.025000,0.025000},{0.518750,0.556250,0.050000,0.050000},{0.531250,0.556250,0.025000,0.025000},{0.531250,0.556250,0.050000,0.050000},{0.543750,0.556250,0.025000,0.025000},{0.543750,0.556250,0.050000,0.050000},{0.556250,0.556250,0.025000,0.025000},{0.556250,0.556250,0.050000,0.050000},{0.568750,0.556250,0.025000,0.025000},{0.568750,0.556250,0.050000,0.050000},{0.581250,0.556250,0.025000,0.025000},{0.581250,0.556250,0.050000,0.050000},{0.593750,0.556250,0.025000,0.025000},{0.593750,0.556250,0.050000,0.050000},{0.606250,0.556250,0.025000,0.025000},{0.606250,0.556250,0.050000,0.050000},{0.618750,0.556250,0.025000,0.025000},{0.618750,0.556250,0.050000,0.050000},{0.631250,0.556250,0.025000,0.025000},{0.631250,0.556250,0.050000,0.050000},{0.643750,0.556250,0.025000,0.025000},{0.643750,0.556250,0.050000,0.050000},{0.656250,0.556250,0.025000,0.025000},{0.656250,0.556250,0.050000,0.050000},{0.668750,0.556250,0.025000,0.025000},{0.668750,0.556250,0.050000,0.050000},{0.681250,0.556250,0.025000,0.025000},{0.681250,0.556250,0.050000,0.050000},{0.693750,0.556250,0.025000,0.025000},{0.693750,0.556250,0.050000,0.050000},{0.706250,0.556250,0.025000,0.025000},{0.706250,0.556250,0.050000,0.050000},{0.718750,0.556250,0.025000,0.025000},{0.718750,0.556250,0.050000,0.050000},{0.731250,0.556250,0.025000,0.025000},{0.731250,0.556250,0.050000,0.050000},{0.743750,0.556250,0.025000,0.025000},{0.743750,0.556250,0.050000,0.050000},{0.756250,0.556250,0.025000,0.025000},{0.756250,0.556250,0.050000,0.050000},{0.768750,0.556250,0.025000,0.025000},{0.768750,0.556250,0.050000,0.050000},{0.781250,0.556250,0.025000,0.025000},{0.781250,0.556250,0.050000,0.050000},{0.793750,0.556250,0.025000,0.025000},{0.793750,0.556250,0.050000,0.050000},{0.806250,0.556250,0.025000,0.025000},{0.806250,0.556250,0.050000,0.050000},{0.818750,0.556250,0.025000,0.025000},{0.818750,0.556250,0.050000,0.050000},{0.831250,0.556250,0.025000,0.025000},{0.831250,0.556250,0.050000,0.050000},{0.843750,0.556250,0.025000,0.025000},{0.843750,0.556250,0.050000,0.050000},{0.856250,0.556250,0.025000,0.025000},{0.856250,0.556250,0.050000,0.050000},{0.868750,0.556250,0.025000,0.025000},{0.868750,0.556250,0.050000,0.050000},{0.881250,0.556250,0.025000,0.025000},{0.881250,0.556250,0.050000,0.050000},{0.893750,0.556250,0.025000,0.025000},{0.893750,0.556250,0.050000,0.050000},{0.906250,0.556250,0.025000,0.025000},{0.906250,0.556250,0.050000,0.050000},{0.918750,0.556250,0.025000,0.025000},{0.918750,0.556250,0.050000,0.050000},{0.931250,0.556250,0.025000,0.025000},{0.931250,0.556250,0.050000,0.050000},{0.943750,0.556250,0.025000,0.025000},{0.943750,0.556250,0.050000,0.050000},{0.956250,0.556250,0.025000,0.025000},{0.956250,0.556250,0.050000,0.050000},{0.968750,0.556250,0.025000,0.025000},{0.968750,0.556250,0.050000,0.050000},{0.981250,0.556250,0.025000,0.025000},{0.981250,0.556250,0.050000,0.050000},{0.993750,0.556250,0.025000,0.025000},{0.993750,0.556250,0.050000,0.050000},{0.006250,0.568750,0.025000,0.025000},{0.006250,0.568750,0.050000,0.050000},{0.018750,0.568750,0.025000,0.025000},{0.018750,0.568750,0.050000,0.050000},{0.031250,0.568750,0.025000,0.025000},{0.031250,0.568750,0.050000,0.050000},{0.043750,0.568750,0.025000,0.025000},{0.043750,0.568750,0.050000,0.050000},{0.056250,0.568750,0.025000,0.025000},{0.056250,0.568750,0.050000,0.050000},{0.068750,0.568750,0.025000,0.025000},{0.068750,0.568750,0.050000,0.050000},{0.081250,0.568750,0.025000,0.025000},{0.081250,0.568750,0.050000,0.050000},{0.093750,0.568750,0.025000,0.025000},{0.093750,0.568750,0.050000,0.050000},{0.106250,0.568750,0.025000,0.025000},{0.106250,0.568750,0.050000,0.050000},{0.118750,0.568750,0.025000,0.025000},{0.118750,0.568750,0.050000,0.050000},{0.131250,0.568750,0.025000,0.025000},{0.131250,0.568750,0.050000,0.050000},{0.143750,0.568750,0.025000,0.025000},{0.143750,0.568750,0.050000,0.050000},{0.156250,0.568750,0.025000,0.025000},{0.156250,0.568750,0.050000,0.050000},{0.168750,0.568750,0.025000,0.025000},{0.168750,0.568750,0.050000,0.050000},{0.181250,0.568750,0.025000,0.025000},{0.181250,0.568750,0.050000,0.050000},{0.193750,0.568750,0.025000,0.025000},{0.193750,0.568750,0.050000,0.050000},{0.206250,0.568750,0.025000,0.025000},{0.206250,0.568750,0.050000,0.050000},{0.218750,0.568750,0.025000,0.025000},{0.218750,0.568750,0.050000,0.050000},{0.231250,0.568750,0.025000,0.025000},{0.231250,0.568750,0.050000,0.050000},{0.243750,0.568750,0.025000,0.025000},{0.243750,0.568750,0.050000,0.050000},{0.256250,0.568750,0.025000,0.025000},{0.256250,0.568750,0.050000,0.050000},{0.268750,0.568750,0.025000,0.025000},{0.268750,0.568750,0.050000,0.050000},{0.281250,0.568750,0.025000,0.025000},{0.281250,0.568750,0.050000,0.050000},{0.293750,0.568750,0.025000,0.025000},{0.293750,0.568750,0.050000,0.050000},{0.306250,0.568750,0.025000,0.025000},{0.306250,0.568750,0.050000,0.050000},{0.318750,0.568750,0.025000,0.025000},{0.318750,0.568750,0.050000,0.050000},{0.331250,0.568750,0.025000,0.025000},{0.331250,0.568750,0.050000,0.050000},{0.343750,0.568750,0.025000,0.025000},{0.343750,0.568750,0.050000,0.050000},{0.356250,0.568750,0.025000,0.025000},{0.356250,0.568750,0.050000,0.050000},{0.368750,0.568750,0.025000,0.025000},{0.368750,0.568750,0.050000,0.050000},{0.381250,0.568750,0.025000,0.025000},{0.381250,0.568750,0.050000,0.050000},{0.393750,0.568750,0.025000,0.025000},{0.393750,0.568750,0.050000,0.050000},{0.406250,0.568750,0.025000,0.025000},{0.406250,0.568750,0.050000,0.050000},{0.418750,0.568750,0.025000,0.025000},{0.418750,0.568750,0.050000,0.050000},{0.431250,0.568750,0.025000,0.025000},{0.431250,0.568750,0.050000,0.050000},{0.443750,0.568750,0.025000,0.025000},{0.443750,0.568750,0.050000,0.050000},{0.456250,0.568750,0.025000,0.025000},{0.456250,0.568750,0.050000,0.050000},{0.468750,0.568750,0.025000,0.025000},{0.468750,0.568750,0.050000,0.050000},{0.481250,0.568750,0.025000,0.025000},{0.481250,0.568750,0.050000,0.050000},{0.493750,0.568750,0.025000,0.025000},{0.493750,0.568750,0.050000,0.050000},{0.506250,0.568750,0.025000,0.025000},{0.506250,0.568750,0.050000,0.050000},{0.518750,0.568750,0.025000,0.025000},{0.518750,0.568750,0.050000,0.050000},{0.531250,0.568750,0.025000,0.025000},{0.531250,0.568750,0.050000,0.050000},{0.543750,0.568750,0.025000,0.025000},{0.543750,0.568750,0.050000,0.050000},{0.556250,0.568750,0.025000,0.025000},{0.556250,0.568750,0.050000,0.050000},{0.568750,0.568750,0.025000,0.025000},{0.568750,0.568750,0.050000,0.050000},{0.581250,0.568750,0.025000,0.025000},{0.581250,0.568750,0.050000,0.050000},{0.593750,0.568750,0.025000,0.025000},{0.593750,0.568750,0.050000,0.050000},{0.606250,0.568750,0.025000,0.025000},{0.606250,0.568750,0.050000,0.050000},{0.618750,0.568750,0.025000,0.025000},{0.618750,0.568750,0.050000,0.050000},{0.631250,0.568750,0.025000,0.025000},{0.631250,0.568750,0.050000,0.050000},{0.643750,0.568750,0.025000,0.025000},{0.643750,0.568750,0.050000,0.050000},{0.656250,0.568750,0.025000,0.025000},{0.656250,0.568750,0.050000,0.050000},{0.668750,0.568750,0.025000,0.025000},{0.668750,0.568750,0.050000,0.050000},{0.681250,0.568750,0.025000,0.025000},{0.681250,0.568750,0.050000,0.050000},{0.693750,0.568750,0.025000,0.025000},{0.693750,0.568750,0.050000,0.050000},{0.706250,0.568750,0.025000,0.025000},{0.706250,0.568750,0.050000,0.050000},{0.718750,0.568750,0.025000,0.025000},{0.718750,0.568750,0.050000,0.050000},{0.731250,0.568750,0.025000,0.025000},{0.731250,0.568750,0.050000,0.050000},{0.743750,0.568750,0.025000,0.025000},{0.743750,0.568750,0.050000,0.050000},{0.756250,0.568750,0.025000,0.025000},{0.756250,0.568750,0.050000,0.050000},{0.768750,0.568750,0.025000,0.025000},{0.768750,0.568750,0.050000,0.050000},{0.781250,0.568750,0.025000,0.025000},{0.781250,0.568750,0.050000,0.050000},{0.793750,0.568750,0.025000,0.025000},{0.793750,0.568750,0.050000,0.050000},{0.806250,0.568750,0.025000,0.025000},{0.806250,0.568750,0.050000,0.050000},{0.818750,0.568750,0.025000,0.025000},{0.818750,0.568750,0.050000,0.050000},{0.831250,0.568750,0.025000,0.025000},{0.831250,0.568750,0.050000,0.050000},{0.843750,0.568750,0.025000,0.025000},{0.843750,0.568750,0.050000,0.050000},{0.856250,0.568750,0.025000,0.025000},{0.856250,0.568750,0.050000,0.050000},{0.868750,0.568750,0.025000,0.025000},{0.868750,0.568750,0.050000,0.050000},{0.881250,0.568750,0.025000,0.025000},{0.881250,0.568750,0.050000,0.050000},{0.893750,0.568750,0.025000,0.025000},{0.893750,0.568750,0.050000,0.050000},{0.906250,0.568750,0.025000,0.025000},{0.906250,0.568750,0.050000,0.050000},{0.918750,0.568750,0.025000,0.025000},{0.918750,0.568750,0.050000,0.050000},{0.931250,0.568750,0.025000,0.025000},{0.931250,0.568750,0.050000,0.050000},{0.943750,0.568750,0.025000,0.025000},{0.943750,0.568750,0.050000,0.050000},{0.956250,0.568750,0.025000,0.025000},{0.956250,0.568750,0.050000,0.050000},{0.968750,0.568750,0.025000,0.025000},{0.968750,0.568750,0.050000,0.050000},{0.981250,0.568750,0.025000,0.025000},{0.981250,0.568750,0.050000,0.050000},{0.993750,0.568750,0.025000,0.025000},{0.993750,0.568750,0.050000,0.050000},{0.006250,0.581250,0.025000,0.025000},{0.006250,0.581250,0.050000,0.050000},{0.018750,0.581250,0.025000,0.025000},{0.018750,0.581250,0.050000,0.050000},{0.031250,0.581250,0.025000,0.025000},{0.031250,0.581250,0.050000,0.050000},{0.043750,0.581250,0.025000,0.025000},{0.043750,0.581250,0.050000,0.050000},{0.056250,0.581250,0.025000,0.025000},{0.056250,0.581250,0.050000,0.050000},{0.068750,0.581250,0.025000,0.025000},{0.068750,0.581250,0.050000,0.050000},{0.081250,0.581250,0.025000,0.025000},{0.081250,0.581250,0.050000,0.050000},{0.093750,0.581250,0.025000,0.025000},{0.093750,0.581250,0.050000,0.050000},{0.106250,0.581250,0.025000,0.025000},{0.106250,0.581250,0.050000,0.050000},{0.118750,0.581250,0.025000,0.025000},{0.118750,0.581250,0.050000,0.050000},{0.131250,0.581250,0.025000,0.025000},{0.131250,0.581250,0.050000,0.050000},{0.143750,0.581250,0.025000,0.025000},{0.143750,0.581250,0.050000,0.050000},{0.156250,0.581250,0.025000,0.025000},{0.156250,0.581250,0.050000,0.050000},{0.168750,0.581250,0.025000,0.025000},{0.168750,0.581250,0.050000,0.050000},{0.181250,0.581250,0.025000,0.025000},{0.181250,0.581250,0.050000,0.050000},{0.193750,0.581250,0.025000,0.025000},{0.193750,0.581250,0.050000,0.050000},{0.206250,0.581250,0.025000,0.025000},{0.206250,0.581250,0.050000,0.050000},{0.218750,0.581250,0.025000,0.025000},{0.218750,0.581250,0.050000,0.050000},{0.231250,0.581250,0.025000,0.025000},{0.231250,0.581250,0.050000,0.050000},{0.243750,0.581250,0.025000,0.025000},{0.243750,0.581250,0.050000,0.050000},{0.256250,0.581250,0.025000,0.025000},{0.256250,0.581250,0.050000,0.050000},{0.268750,0.581250,0.025000,0.025000},{0.268750,0.581250,0.050000,0.050000},{0.281250,0.581250,0.025000,0.025000},{0.281250,0.581250,0.050000,0.050000},{0.293750,0.581250,0.025000,0.025000},{0.293750,0.581250,0.050000,0.050000},{0.306250,0.581250,0.025000,0.025000},{0.306250,0.581250,0.050000,0.050000},{0.318750,0.581250,0.025000,0.025000},{0.318750,0.581250,0.050000,0.050000},{0.331250,0.581250,0.025000,0.025000},{0.331250,0.581250,0.050000,0.050000},{0.343750,0.581250,0.025000,0.025000},{0.343750,0.581250,0.050000,0.050000},{0.356250,0.581250,0.025000,0.025000},{0.356250,0.581250,0.050000,0.050000},{0.368750,0.581250,0.025000,0.025000},{0.368750,0.581250,0.050000,0.050000},{0.381250,0.581250,0.025000,0.025000},{0.381250,0.581250,0.050000,0.050000},{0.393750,0.581250,0.025000,0.025000},{0.393750,0.581250,0.050000,0.050000},{0.406250,0.581250,0.025000,0.025000},{0.406250,0.581250,0.050000,0.050000},{0.418750,0.581250,0.025000,0.025000},{0.418750,0.581250,0.050000,0.050000},{0.431250,0.581250,0.025000,0.025000},{0.431250,0.581250,0.050000,0.050000},{0.443750,0.581250,0.025000,0.025000},{0.443750,0.581250,0.050000,0.050000},{0.456250,0.581250,0.025000,0.025000},{0.456250,0.581250,0.050000,0.050000},{0.468750,0.581250,0.025000,0.025000},{0.468750,0.581250,0.050000,0.050000},{0.481250,0.581250,0.025000,0.025000},{0.481250,0.581250,0.050000,0.050000},{0.493750,0.581250,0.025000,0.025000},{0.493750,0.581250,0.050000,0.050000},{0.506250,0.581250,0.025000,0.025000},{0.506250,0.581250,0.050000,0.050000},{0.518750,0.581250,0.025000,0.025000},{0.518750,0.581250,0.050000,0.050000},{0.531250,0.581250,0.025000,0.025000},{0.531250,0.581250,0.050000,0.050000},{0.543750,0.581250,0.025000,0.025000},{0.543750,0.581250,0.050000,0.050000},{0.556250,0.581250,0.025000,0.025000},{0.556250,0.581250,0.050000,0.050000},{0.568750,0.581250,0.025000,0.025000},{0.568750,0.581250,0.050000,0.050000},{0.581250,0.581250,0.025000,0.025000},{0.581250,0.581250,0.050000,0.050000},{0.593750,0.581250,0.025000,0.025000},{0.593750,0.581250,0.050000,0.050000},{0.606250,0.581250,0.025000,0.025000},{0.606250,0.581250,0.050000,0.050000},{0.618750,0.581250,0.025000,0.025000},{0.618750,0.581250,0.050000,0.050000},{0.631250,0.581250,0.025000,0.025000},{0.631250,0.581250,0.050000,0.050000},{0.643750,0.581250,0.025000,0.025000},{0.643750,0.581250,0.050000,0.050000},{0.656250,0.581250,0.025000,0.025000},{0.656250,0.581250,0.050000,0.050000},{0.668750,0.581250,0.025000,0.025000},{0.668750,0.581250,0.050000,0.050000},{0.681250,0.581250,0.025000,0.025000},{0.681250,0.581250,0.050000,0.050000},{0.693750,0.581250,0.025000,0.025000},{0.693750,0.581250,0.050000,0.050000},{0.706250,0.581250,0.025000,0.025000},{0.706250,0.581250,0.050000,0.050000},{0.718750,0.581250,0.025000,0.025000},{0.718750,0.581250,0.050000,0.050000},{0.731250,0.581250,0.025000,0.025000},{0.731250,0.581250,0.050000,0.050000},{0.743750,0.581250,0.025000,0.025000},{0.743750,0.581250,0.050000,0.050000},{0.756250,0.581250,0.025000,0.025000},{0.756250,0.581250,0.050000,0.050000},{0.768750,0.581250,0.025000,0.025000},{0.768750,0.581250,0.050000,0.050000},{0.781250,0.581250,0.025000,0.025000},{0.781250,0.581250,0.050000,0.050000},{0.793750,0.581250,0.025000,0.025000},{0.793750,0.581250,0.050000,0.050000},{0.806250,0.581250,0.025000,0.025000},{0.806250,0.581250,0.050000,0.050000},{0.818750,0.581250,0.025000,0.025000},{0.818750,0.581250,0.050000,0.050000},{0.831250,0.581250,0.025000,0.025000},{0.831250,0.581250,0.050000,0.050000},{0.843750,0.581250,0.025000,0.025000},{0.843750,0.581250,0.050000,0.050000},{0.856250,0.581250,0.025000,0.025000},{0.856250,0.581250,0.050000,0.050000},{0.868750,0.581250,0.025000,0.025000},{0.868750,0.581250,0.050000,0.050000},{0.881250,0.581250,0.025000,0.025000},{0.881250,0.581250,0.050000,0.050000},{0.893750,0.581250,0.025000,0.025000},{0.893750,0.581250,0.050000,0.050000},{0.906250,0.581250,0.025000,0.025000},{0.906250,0.581250,0.050000,0.050000},{0.918750,0.581250,0.025000,0.025000},{0.918750,0.581250,0.050000,0.050000},{0.931250,0.581250,0.025000,0.025000},{0.931250,0.581250,0.050000,0.050000},{0.943750,0.581250,0.025000,0.025000},{0.943750,0.581250,0.050000,0.050000},{0.956250,0.581250,0.025000,0.025000},{0.956250,0.581250,0.050000,0.050000},{0.968750,0.581250,0.025000,0.025000},{0.968750,0.581250,0.050000,0.050000},{0.981250,0.581250,0.025000,0.025000},{0.981250,0.581250,0.050000,0.050000},{0.993750,0.581250,0.025000,0.025000},{0.993750,0.581250,0.050000,0.050000},{0.006250,0.593750,0.025000,0.025000},{0.006250,0.593750,0.050000,0.050000},{0.018750,0.593750,0.025000,0.025000},{0.018750,0.593750,0.050000,0.050000},{0.031250,0.593750,0.025000,0.025000},{0.031250,0.593750,0.050000,0.050000},{0.043750,0.593750,0.025000,0.025000},{0.043750,0.593750,0.050000,0.050000},{0.056250,0.593750,0.025000,0.025000},{0.056250,0.593750,0.050000,0.050000},{0.068750,0.593750,0.025000,0.025000},{0.068750,0.593750,0.050000,0.050000},{0.081250,0.593750,0.025000,0.025000},{0.081250,0.593750,0.050000,0.050000},{0.093750,0.593750,0.025000,0.025000},{0.093750,0.593750,0.050000,0.050000},{0.106250,0.593750,0.025000,0.025000},{0.106250,0.593750,0.050000,0.050000},{0.118750,0.593750,0.025000,0.025000},{0.118750,0.593750,0.050000,0.050000},{0.131250,0.593750,0.025000,0.025000},{0.131250,0.593750,0.050000,0.050000},{0.143750,0.593750,0.025000,0.025000},{0.143750,0.593750,0.050000,0.050000},{0.156250,0.593750,0.025000,0.025000},{0.156250,0.593750,0.050000,0.050000},{0.168750,0.593750,0.025000,0.025000},{0.168750,0.593750,0.050000,0.050000},{0.181250,0.593750,0.025000,0.025000},{0.181250,0.593750,0.050000,0.050000},{0.193750,0.593750,0.025000,0.025000},{0.193750,0.593750,0.050000,0.050000},{0.206250,0.593750,0.025000,0.025000},{0.206250,0.593750,0.050000,0.050000},{0.218750,0.593750,0.025000,0.025000},{0.218750,0.593750,0.050000,0.050000},{0.231250,0.593750,0.025000,0.025000},{0.231250,0.593750,0.050000,0.050000},{0.243750,0.593750,0.025000,0.025000},{0.243750,0.593750,0.050000,0.050000},{0.256250,0.593750,0.025000,0.025000},{0.256250,0.593750,0.050000,0.050000},{0.268750,0.593750,0.025000,0.025000},{0.268750,0.593750,0.050000,0.050000},{0.281250,0.593750,0.025000,0.025000},{0.281250,0.593750,0.050000,0.050000},{0.293750,0.593750,0.025000,0.025000},{0.293750,0.593750,0.050000,0.050000},{0.306250,0.593750,0.025000,0.025000},{0.306250,0.593750,0.050000,0.050000},{0.318750,0.593750,0.025000,0.025000},{0.318750,0.593750,0.050000,0.050000},{0.331250,0.593750,0.025000,0.025000},{0.331250,0.593750,0.050000,0.050000},{0.343750,0.593750,0.025000,0.025000},{0.343750,0.593750,0.050000,0.050000},{0.356250,0.593750,0.025000,0.025000},{0.356250,0.593750,0.050000,0.050000},{0.368750,0.593750,0.025000,0.025000},{0.368750,0.593750,0.050000,0.050000},{0.381250,0.593750,0.025000,0.025000},{0.381250,0.593750,0.050000,0.050000},{0.393750,0.593750,0.025000,0.025000},{0.393750,0.593750,0.050000,0.050000},{0.406250,0.593750,0.025000,0.025000},{0.406250,0.593750,0.050000,0.050000},{0.418750,0.593750,0.025000,0.025000},{0.418750,0.593750,0.050000,0.050000},{0.431250,0.593750,0.025000,0.025000},{0.431250,0.593750,0.050000,0.050000},{0.443750,0.593750,0.025000,0.025000},{0.443750,0.593750,0.050000,0.050000},{0.456250,0.593750,0.025000,0.025000},{0.456250,0.593750,0.050000,0.050000},{0.468750,0.593750,0.025000,0.025000},{0.468750,0.593750,0.050000,0.050000},{0.481250,0.593750,0.025000,0.025000},{0.481250,0.593750,0.050000,0.050000},{0.493750,0.593750,0.025000,0.025000},{0.493750,0.593750,0.050000,0.050000},{0.506250,0.593750,0.025000,0.025000},{0.506250,0.593750,0.050000,0.050000},{0.518750,0.593750,0.025000,0.025000},{0.518750,0.593750,0.050000,0.050000},{0.531250,0.593750,0.025000,0.025000},{0.531250,0.593750,0.050000,0.050000},{0.543750,0.593750,0.025000,0.025000},{0.543750,0.593750,0.050000,0.050000},{0.556250,0.593750,0.025000,0.025000},{0.556250,0.593750,0.050000,0.050000},{0.568750,0.593750,0.025000,0.025000},{0.568750,0.593750,0.050000,0.050000},{0.581250,0.593750,0.025000,0.025000},{0.581250,0.593750,0.050000,0.050000},{0.593750,0.593750,0.025000,0.025000},{0.593750,0.593750,0.050000,0.050000},{0.606250,0.593750,0.025000,0.025000},{0.606250,0.593750,0.050000,0.050000},{0.618750,0.593750,0.025000,0.025000},{0.618750,0.593750,0.050000,0.050000},{0.631250,0.593750,0.025000,0.025000},{0.631250,0.593750,0.050000,0.050000},{0.643750,0.593750,0.025000,0.025000},{0.643750,0.593750,0.050000,0.050000},{0.656250,0.593750,0.025000,0.025000},{0.656250,0.593750,0.050000,0.050000},{0.668750,0.593750,0.025000,0.025000},{0.668750,0.593750,0.050000,0.050000},{0.681250,0.593750,0.025000,0.025000},{0.681250,0.593750,0.050000,0.050000},{0.693750,0.593750,0.025000,0.025000},{0.693750,0.593750,0.050000,0.050000},{0.706250,0.593750,0.025000,0.025000},{0.706250,0.593750,0.050000,0.050000},{0.718750,0.593750,0.025000,0.025000},{0.718750,0.593750,0.050000,0.050000},{0.731250,0.593750,0.025000,0.025000},{0.731250,0.593750,0.050000,0.050000},{0.743750,0.593750,0.025000,0.025000},{0.743750,0.593750,0.050000,0.050000},{0.756250,0.593750,0.025000,0.025000},{0.756250,0.593750,0.050000,0.050000},{0.768750,0.593750,0.025000,0.025000},{0.768750,0.593750,0.050000,0.050000},{0.781250,0.593750,0.025000,0.025000},{0.781250,0.593750,0.050000,0.050000},{0.793750,0.593750,0.025000,0.025000},{0.793750,0.593750,0.050000,0.050000},{0.806250,0.593750,0.025000,0.025000},{0.806250,0.593750,0.050000,0.050000},{0.818750,0.593750,0.025000,0.025000},{0.818750,0.593750,0.050000,0.050000},{0.831250,0.593750,0.025000,0.025000},{0.831250,0.593750,0.050000,0.050000},{0.843750,0.593750,0.025000,0.025000},{0.843750,0.593750,0.050000,0.050000},{0.856250,0.593750,0.025000,0.025000},{0.856250,0.593750,0.050000,0.050000},{0.868750,0.593750,0.025000,0.025000},{0.868750,0.593750,0.050000,0.050000},{0.881250,0.593750,0.025000,0.025000},{0.881250,0.593750,0.050000,0.050000},{0.893750,0.593750,0.025000,0.025000},{0.893750,0.593750,0.050000,0.050000},{0.906250,0.593750,0.025000,0.025000},{0.906250,0.593750,0.050000,0.050000},{0.918750,0.593750,0.025000,0.025000},{0.918750,0.593750,0.050000,0.050000},{0.931250,0.593750,0.025000,0.025000},{0.931250,0.593750,0.050000,0.050000},{0.943750,0.593750,0.025000,0.025000},{0.943750,0.593750,0.050000,0.050000},{0.956250,0.593750,0.025000,0.025000},{0.956250,0.593750,0.050000,0.050000},{0.968750,0.593750,0.025000,0.025000},{0.968750,0.593750,0.050000,0.050000},{0.981250,0.593750,0.025000,0.025000},{0.981250,0.593750,0.050000,0.050000},{0.993750,0.593750,0.025000,0.025000},{0.993750,0.593750,0.050000,0.050000},{0.006250,0.606250,0.025000,0.025000},{0.006250,0.606250,0.050000,0.050000},{0.018750,0.606250,0.025000,0.025000},{0.018750,0.606250,0.050000,0.050000},{0.031250,0.606250,0.025000,0.025000},{0.031250,0.606250,0.050000,0.050000},{0.043750,0.606250,0.025000,0.025000},{0.043750,0.606250,0.050000,0.050000},{0.056250,0.606250,0.025000,0.025000},{0.056250,0.606250,0.050000,0.050000},{0.068750,0.606250,0.025000,0.025000},{0.068750,0.606250,0.050000,0.050000},{0.081250,0.606250,0.025000,0.025000},{0.081250,0.606250,0.050000,0.050000},{0.093750,0.606250,0.025000,0.025000},{0.093750,0.606250,0.050000,0.050000},{0.106250,0.606250,0.025000,0.025000},{0.106250,0.606250,0.050000,0.050000},{0.118750,0.606250,0.025000,0.025000},{0.118750,0.606250,0.050000,0.050000},{0.131250,0.606250,0.025000,0.025000},{0.131250,0.606250,0.050000,0.050000},{0.143750,0.606250,0.025000,0.025000},{0.143750,0.606250,0.050000,0.050000},{0.156250,0.606250,0.025000,0.025000},{0.156250,0.606250,0.050000,0.050000},{0.168750,0.606250,0.025000,0.025000},{0.168750,0.606250,0.050000,0.050000},{0.181250,0.606250,0.025000,0.025000},{0.181250,0.606250,0.050000,0.050000},{0.193750,0.606250,0.025000,0.025000},{0.193750,0.606250,0.050000,0.050000},{0.206250,0.606250,0.025000,0.025000},{0.206250,0.606250,0.050000,0.050000},{0.218750,0.606250,0.025000,0.025000},{0.218750,0.606250,0.050000,0.050000},{0.231250,0.606250,0.025000,0.025000},{0.231250,0.606250,0.050000,0.050000},{0.243750,0.606250,0.025000,0.025000},{0.243750,0.606250,0.050000,0.050000},{0.256250,0.606250,0.025000,0.025000},{0.256250,0.606250,0.050000,0.050000},{0.268750,0.606250,0.025000,0.025000},{0.268750,0.606250,0.050000,0.050000},{0.281250,0.606250,0.025000,0.025000},{0.281250,0.606250,0.050000,0.050000},{0.293750,0.606250,0.025000,0.025000},{0.293750,0.606250,0.050000,0.050000},{0.306250,0.606250,0.025000,0.025000},{0.306250,0.606250,0.050000,0.050000},{0.318750,0.606250,0.025000,0.025000},{0.318750,0.606250,0.050000,0.050000},{0.331250,0.606250,0.025000,0.025000},{0.331250,0.606250,0.050000,0.050000},{0.343750,0.606250,0.025000,0.025000},{0.343750,0.606250,0.050000,0.050000},{0.356250,0.606250,0.025000,0.025000},{0.356250,0.606250,0.050000,0.050000},{0.368750,0.606250,0.025000,0.025000},{0.368750,0.606250,0.050000,0.050000},{0.381250,0.606250,0.025000,0.025000},{0.381250,0.606250,0.050000,0.050000},{0.393750,0.606250,0.025000,0.025000},{0.393750,0.606250,0.050000,0.050000},{0.406250,0.606250,0.025000,0.025000},{0.406250,0.606250,0.050000,0.050000},{0.418750,0.606250,0.025000,0.025000},{0.418750,0.606250,0.050000,0.050000},{0.431250,0.606250,0.025000,0.025000},{0.431250,0.606250,0.050000,0.050000},{0.443750,0.606250,0.025000,0.025000},{0.443750,0.606250,0.050000,0.050000},{0.456250,0.606250,0.025000,0.025000},{0.456250,0.606250,0.050000,0.050000},{0.468750,0.606250,0.025000,0.025000},{0.468750,0.606250,0.050000,0.050000},{0.481250,0.606250,0.025000,0.025000},{0.481250,0.606250,0.050000,0.050000},{0.493750,0.606250,0.025000,0.025000},{0.493750,0.606250,0.050000,0.050000},{0.506250,0.606250,0.025000,0.025000},{0.506250,0.606250,0.050000,0.050000},{0.518750,0.606250,0.025000,0.025000},{0.518750,0.606250,0.050000,0.050000},{0.531250,0.606250,0.025000,0.025000},{0.531250,0.606250,0.050000,0.050000},{0.543750,0.606250,0.025000,0.025000},{0.543750,0.606250,0.050000,0.050000},{0.556250,0.606250,0.025000,0.025000},{0.556250,0.606250,0.050000,0.050000},{0.568750,0.606250,0.025000,0.025000},{0.568750,0.606250,0.050000,0.050000},{0.581250,0.606250,0.025000,0.025000},{0.581250,0.606250,0.050000,0.050000},{0.593750,0.606250,0.025000,0.025000},{0.593750,0.606250,0.050000,0.050000},{0.606250,0.606250,0.025000,0.025000},{0.606250,0.606250,0.050000,0.050000},{0.618750,0.606250,0.025000,0.025000},{0.618750,0.606250,0.050000,0.050000},{0.631250,0.606250,0.025000,0.025000},{0.631250,0.606250,0.050000,0.050000},{0.643750,0.606250,0.025000,0.025000},{0.643750,0.606250,0.050000,0.050000},{0.656250,0.606250,0.025000,0.025000},{0.656250,0.606250,0.050000,0.050000},{0.668750,0.606250,0.025000,0.025000},{0.668750,0.606250,0.050000,0.050000},{0.681250,0.606250,0.025000,0.025000},{0.681250,0.606250,0.050000,0.050000},{0.693750,0.606250,0.025000,0.025000},{0.693750,0.606250,0.050000,0.050000},{0.706250,0.606250,0.025000,0.025000},{0.706250,0.606250,0.050000,0.050000},{0.718750,0.606250,0.025000,0.025000},{0.718750,0.606250,0.050000,0.050000},{0.731250,0.606250,0.025000,0.025000},{0.731250,0.606250,0.050000,0.050000},{0.743750,0.606250,0.025000,0.025000},{0.743750,0.606250,0.050000,0.050000},{0.756250,0.606250,0.025000,0.025000},{0.756250,0.606250,0.050000,0.050000},{0.768750,0.606250,0.025000,0.025000},{0.768750,0.606250,0.050000,0.050000},{0.781250,0.606250,0.025000,0.025000},{0.781250,0.606250,0.050000,0.050000},{0.793750,0.606250,0.025000,0.025000},{0.793750,0.606250,0.050000,0.050000},{0.806250,0.606250,0.025000,0.025000},{0.806250,0.606250,0.050000,0.050000},{0.818750,0.606250,0.025000,0.025000},{0.818750,0.606250,0.050000,0.050000},{0.831250,0.606250,0.025000,0.025000},{0.831250,0.606250,0.050000,0.050000},{0.843750,0.606250,0.025000,0.025000},{0.843750,0.606250,0.050000,0.050000},{0.856250,0.606250,0.025000,0.025000},{0.856250,0.606250,0.050000,0.050000},{0.868750,0.606250,0.025000,0.025000},{0.868750,0.606250,0.050000,0.050000},{0.881250,0.606250,0.025000,0.025000},{0.881250,0.606250,0.050000,0.050000},{0.893750,0.606250,0.025000,0.025000},{0.893750,0.606250,0.050000,0.050000},{0.906250,0.606250,0.025000,0.025000},{0.906250,0.606250,0.050000,0.050000},{0.918750,0.606250,0.025000,0.025000},{0.918750,0.606250,0.050000,0.050000},{0.931250,0.606250,0.025000,0.025000},{0.931250,0.606250,0.050000,0.050000},{0.943750,0.606250,0.025000,0.025000},{0.943750,0.606250,0.050000,0.050000},{0.956250,0.606250,0.025000,0.025000},{0.956250,0.606250,0.050000,0.050000},{0.968750,0.606250,0.025000,0.025000},{0.968750,0.606250,0.050000,0.050000},{0.981250,0.606250,0.025000,0.025000},{0.981250,0.606250,0.050000,0.050000},{0.993750,0.606250,0.025000,0.025000},{0.993750,0.606250,0.050000,0.050000},{0.006250,0.618750,0.025000,0.025000},{0.006250,0.618750,0.050000,0.050000},{0.018750,0.618750,0.025000,0.025000},{0.018750,0.618750,0.050000,0.050000},{0.031250,0.618750,0.025000,0.025000},{0.031250,0.618750,0.050000,0.050000},{0.043750,0.618750,0.025000,0.025000},{0.043750,0.618750,0.050000,0.050000},{0.056250,0.618750,0.025000,0.025000},{0.056250,0.618750,0.050000,0.050000},{0.068750,0.618750,0.025000,0.025000},{0.068750,0.618750,0.050000,0.050000},{0.081250,0.618750,0.025000,0.025000},{0.081250,0.618750,0.050000,0.050000},{0.093750,0.618750,0.025000,0.025000},{0.093750,0.618750,0.050000,0.050000},{0.106250,0.618750,0.025000,0.025000},{0.106250,0.618750,0.050000,0.050000},{0.118750,0.618750,0.025000,0.025000},{0.118750,0.618750,0.050000,0.050000},{0.131250,0.618750,0.025000,0.025000},{0.131250,0.618750,0.050000,0.050000},{0.143750,0.618750,0.025000,0.025000},{0.143750,0.618750,0.050000,0.050000},{0.156250,0.618750,0.025000,0.025000},{0.156250,0.618750,0.050000,0.050000},{0.168750,0.618750,0.025000,0.025000},{0.168750,0.618750,0.050000,0.050000},{0.181250,0.618750,0.025000,0.025000},{0.181250,0.618750,0.050000,0.050000},{0.193750,0.618750,0.025000,0.025000},{0.193750,0.618750,0.050000,0.050000},{0.206250,0.618750,0.025000,0.025000},{0.206250,0.618750,0.050000,0.050000},{0.218750,0.618750,0.025000,0.025000},{0.218750,0.618750,0.050000,0.050000},{0.231250,0.618750,0.025000,0.025000},{0.231250,0.618750,0.050000,0.050000},{0.243750,0.618750,0.025000,0.025000},{0.243750,0.618750,0.050000,0.050000},{0.256250,0.618750,0.025000,0.025000},{0.256250,0.618750,0.050000,0.050000},{0.268750,0.618750,0.025000,0.025000},{0.268750,0.618750,0.050000,0.050000},{0.281250,0.618750,0.025000,0.025000},{0.281250,0.618750,0.050000,0.050000},{0.293750,0.618750,0.025000,0.025000},{0.293750,0.618750,0.050000,0.050000},{0.306250,0.618750,0.025000,0.025000},{0.306250,0.618750,0.050000,0.050000},{0.318750,0.618750,0.025000,0.025000},{0.318750,0.618750,0.050000,0.050000},{0.331250,0.618750,0.025000,0.025000},{0.331250,0.618750,0.050000,0.050000},{0.343750,0.618750,0.025000,0.025000},{0.343750,0.618750,0.050000,0.050000},{0.356250,0.618750,0.025000,0.025000},{0.356250,0.618750,0.050000,0.050000},{0.368750,0.618750,0.025000,0.025000},{0.368750,0.618750,0.050000,0.050000},{0.381250,0.618750,0.025000,0.025000},{0.381250,0.618750,0.050000,0.050000},{0.393750,0.618750,0.025000,0.025000},{0.393750,0.618750,0.050000,0.050000},{0.406250,0.618750,0.025000,0.025000},{0.406250,0.618750,0.050000,0.050000},{0.418750,0.618750,0.025000,0.025000},{0.418750,0.618750,0.050000,0.050000},{0.431250,0.618750,0.025000,0.025000},{0.431250,0.618750,0.050000,0.050000},{0.443750,0.618750,0.025000,0.025000},{0.443750,0.618750,0.050000,0.050000},{0.456250,0.618750,0.025000,0.025000},{0.456250,0.618750,0.050000,0.050000},{0.468750,0.618750,0.025000,0.025000},{0.468750,0.618750,0.050000,0.050000},{0.481250,0.618750,0.025000,0.025000},{0.481250,0.618750,0.050000,0.050000},{0.493750,0.618750,0.025000,0.025000},{0.493750,0.618750,0.050000,0.050000},{0.506250,0.618750,0.025000,0.025000},{0.506250,0.618750,0.050000,0.050000},{0.518750,0.618750,0.025000,0.025000},{0.518750,0.618750,0.050000,0.050000},{0.531250,0.618750,0.025000,0.025000},{0.531250,0.618750,0.050000,0.050000},{0.543750,0.618750,0.025000,0.025000},{0.543750,0.618750,0.050000,0.050000},{0.556250,0.618750,0.025000,0.025000},{0.556250,0.618750,0.050000,0.050000},{0.568750,0.618750,0.025000,0.025000},{0.568750,0.618750,0.050000,0.050000},{0.581250,0.618750,0.025000,0.025000},{0.581250,0.618750,0.050000,0.050000},{0.593750,0.618750,0.025000,0.025000},{0.593750,0.618750,0.050000,0.050000},{0.606250,0.618750,0.025000,0.025000},{0.606250,0.618750,0.050000,0.050000},{0.618750,0.618750,0.025000,0.025000},{0.618750,0.618750,0.050000,0.050000},{0.631250,0.618750,0.025000,0.025000},{0.631250,0.618750,0.050000,0.050000},{0.643750,0.618750,0.025000,0.025000},{0.643750,0.618750,0.050000,0.050000},{0.656250,0.618750,0.025000,0.025000},{0.656250,0.618750,0.050000,0.050000},{0.668750,0.618750,0.025000,0.025000},{0.668750,0.618750,0.050000,0.050000},{0.681250,0.618750,0.025000,0.025000},{0.681250,0.618750,0.050000,0.050000},{0.693750,0.618750,0.025000,0.025000},{0.693750,0.618750,0.050000,0.050000},{0.706250,0.618750,0.025000,0.025000},{0.706250,0.618750,0.050000,0.050000},{0.718750,0.618750,0.025000,0.025000},{0.718750,0.618750,0.050000,0.050000},{0.731250,0.618750,0.025000,0.025000},{0.731250,0.618750,0.050000,0.050000},{0.743750,0.618750,0.025000,0.025000},{0.743750,0.618750,0.050000,0.050000},{0.756250,0.618750,0.025000,0.025000},{0.756250,0.618750,0.050000,0.050000},{0.768750,0.618750,0.025000,0.025000},{0.768750,0.618750,0.050000,0.050000},{0.781250,0.618750,0.025000,0.025000},{0.781250,0.618750,0.050000,0.050000},{0.793750,0.618750,0.025000,0.025000},{0.793750,0.618750,0.050000,0.050000},{0.806250,0.618750,0.025000,0.025000},{0.806250,0.618750,0.050000,0.050000},{0.818750,0.618750,0.025000,0.025000},{0.818750,0.618750,0.050000,0.050000},{0.831250,0.618750,0.025000,0.025000},{0.831250,0.618750,0.050000,0.050000},{0.843750,0.618750,0.025000,0.025000},{0.843750,0.618750,0.050000,0.050000},{0.856250,0.618750,0.025000,0.025000},{0.856250,0.618750,0.050000,0.050000},{0.868750,0.618750,0.025000,0.025000},{0.868750,0.618750,0.050000,0.050000},{0.881250,0.618750,0.025000,0.025000},{0.881250,0.618750,0.050000,0.050000},{0.893750,0.618750,0.025000,0.025000},{0.893750,0.618750,0.050000,0.050000},{0.906250,0.618750,0.025000,0.025000},{0.906250,0.618750,0.050000,0.050000},{0.918750,0.618750,0.025000,0.025000},{0.918750,0.618750,0.050000,0.050000},{0.931250,0.618750,0.025000,0.025000},{0.931250,0.618750,0.050000,0.050000},{0.943750,0.618750,0.025000,0.025000},{0.943750,0.618750,0.050000,0.050000},{0.956250,0.618750,0.025000,0.025000},{0.956250,0.618750,0.050000,0.050000},{0.968750,0.618750,0.025000,0.025000},{0.968750,0.618750,0.050000,0.050000},{0.981250,0.618750,0.025000,0.025000},{0.981250,0.618750,0.050000,0.050000},{0.993750,0.618750,0.025000,0.025000},{0.993750,0.618750,0.050000,0.050000},{0.006250,0.631250,0.025000,0.025000},{0.006250,0.631250,0.050000,0.050000},{0.018750,0.631250,0.025000,0.025000},{0.018750,0.631250,0.050000,0.050000},{0.031250,0.631250,0.025000,0.025000},{0.031250,0.631250,0.050000,0.050000},{0.043750,0.631250,0.025000,0.025000},{0.043750,0.631250,0.050000,0.050000},{0.056250,0.631250,0.025000,0.025000},{0.056250,0.631250,0.050000,0.050000},{0.068750,0.631250,0.025000,0.025000},{0.068750,0.631250,0.050000,0.050000},{0.081250,0.631250,0.025000,0.025000},{0.081250,0.631250,0.050000,0.050000},{0.093750,0.631250,0.025000,0.025000},{0.093750,0.631250,0.050000,0.050000},{0.106250,0.631250,0.025000,0.025000},{0.106250,0.631250,0.050000,0.050000},{0.118750,0.631250,0.025000,0.025000},{0.118750,0.631250,0.050000,0.050000},{0.131250,0.631250,0.025000,0.025000},{0.131250,0.631250,0.050000,0.050000},{0.143750,0.631250,0.025000,0.025000},{0.143750,0.631250,0.050000,0.050000},{0.156250,0.631250,0.025000,0.025000},{0.156250,0.631250,0.050000,0.050000},{0.168750,0.631250,0.025000,0.025000},{0.168750,0.631250,0.050000,0.050000},{0.181250,0.631250,0.025000,0.025000},{0.181250,0.631250,0.050000,0.050000},{0.193750,0.631250,0.025000,0.025000},{0.193750,0.631250,0.050000,0.050000},{0.206250,0.631250,0.025000,0.025000},{0.206250,0.631250,0.050000,0.050000},{0.218750,0.631250,0.025000,0.025000},{0.218750,0.631250,0.050000,0.050000},{0.231250,0.631250,0.025000,0.025000},{0.231250,0.631250,0.050000,0.050000},{0.243750,0.631250,0.025000,0.025000},{0.243750,0.631250,0.050000,0.050000},{0.256250,0.631250,0.025000,0.025000},{0.256250,0.631250,0.050000,0.050000},{0.268750,0.631250,0.025000,0.025000},{0.268750,0.631250,0.050000,0.050000},{0.281250,0.631250,0.025000,0.025000},{0.281250,0.631250,0.050000,0.050000},{0.293750,0.631250,0.025000,0.025000},{0.293750,0.631250,0.050000,0.050000},{0.306250,0.631250,0.025000,0.025000},{0.306250,0.631250,0.050000,0.050000},{0.318750,0.631250,0.025000,0.025000},{0.318750,0.631250,0.050000,0.050000},{0.331250,0.631250,0.025000,0.025000},{0.331250,0.631250,0.050000,0.050000},{0.343750,0.631250,0.025000,0.025000},{0.343750,0.631250,0.050000,0.050000},{0.356250,0.631250,0.025000,0.025000},{0.356250,0.631250,0.050000,0.050000},{0.368750,0.631250,0.025000,0.025000},{0.368750,0.631250,0.050000,0.050000},{0.381250,0.631250,0.025000,0.025000},{0.381250,0.631250,0.050000,0.050000},{0.393750,0.631250,0.025000,0.025000},{0.393750,0.631250,0.050000,0.050000},{0.406250,0.631250,0.025000,0.025000},{0.406250,0.631250,0.050000,0.050000},{0.418750,0.631250,0.025000,0.025000},{0.418750,0.631250,0.050000,0.050000},{0.431250,0.631250,0.025000,0.025000},{0.431250,0.631250,0.050000,0.050000},{0.443750,0.631250,0.025000,0.025000},{0.443750,0.631250,0.050000,0.050000},{0.456250,0.631250,0.025000,0.025000},{0.456250,0.631250,0.050000,0.050000},{0.468750,0.631250,0.025000,0.025000},{0.468750,0.631250,0.050000,0.050000},{0.481250,0.631250,0.025000,0.025000},{0.481250,0.631250,0.050000,0.050000},{0.493750,0.631250,0.025000,0.025000},{0.493750,0.631250,0.050000,0.050000},{0.506250,0.631250,0.025000,0.025000},{0.506250,0.631250,0.050000,0.050000},{0.518750,0.631250,0.025000,0.025000},{0.518750,0.631250,0.050000,0.050000},{0.531250,0.631250,0.025000,0.025000},{0.531250,0.631250,0.050000,0.050000},{0.543750,0.631250,0.025000,0.025000},{0.543750,0.631250,0.050000,0.050000},{0.556250,0.631250,0.025000,0.025000},{0.556250,0.631250,0.050000,0.050000},{0.568750,0.631250,0.025000,0.025000},{0.568750,0.631250,0.050000,0.050000},{0.581250,0.631250,0.025000,0.025000},{0.581250,0.631250,0.050000,0.050000},{0.593750,0.631250,0.025000,0.025000},{0.593750,0.631250,0.050000,0.050000},{0.606250,0.631250,0.025000,0.025000},{0.606250,0.631250,0.050000,0.050000},{0.618750,0.631250,0.025000,0.025000},{0.618750,0.631250,0.050000,0.050000},{0.631250,0.631250,0.025000,0.025000},{0.631250,0.631250,0.050000,0.050000},{0.643750,0.631250,0.025000,0.025000},{0.643750,0.631250,0.050000,0.050000},{0.656250,0.631250,0.025000,0.025000},{0.656250,0.631250,0.050000,0.050000},{0.668750,0.631250,0.025000,0.025000},{0.668750,0.631250,0.050000,0.050000},{0.681250,0.631250,0.025000,0.025000},{0.681250,0.631250,0.050000,0.050000},{0.693750,0.631250,0.025000,0.025000},{0.693750,0.631250,0.050000,0.050000},{0.706250,0.631250,0.025000,0.025000},{0.706250,0.631250,0.050000,0.050000},{0.718750,0.631250,0.025000,0.025000},{0.718750,0.631250,0.050000,0.050000},{0.731250,0.631250,0.025000,0.025000},{0.731250,0.631250,0.050000,0.050000},{0.743750,0.631250,0.025000,0.025000},{0.743750,0.631250,0.050000,0.050000},{0.756250,0.631250,0.025000,0.025000},{0.756250,0.631250,0.050000,0.050000},{0.768750,0.631250,0.025000,0.025000},{0.768750,0.631250,0.050000,0.050000},{0.781250,0.631250,0.025000,0.025000},{0.781250,0.631250,0.050000,0.050000},{0.793750,0.631250,0.025000,0.025000},{0.793750,0.631250,0.050000,0.050000},{0.806250,0.631250,0.025000,0.025000},{0.806250,0.631250,0.050000,0.050000},{0.818750,0.631250,0.025000,0.025000},{0.818750,0.631250,0.050000,0.050000},{0.831250,0.631250,0.025000,0.025000},{0.831250,0.631250,0.050000,0.050000},{0.843750,0.631250,0.025000,0.025000},{0.843750,0.631250,0.050000,0.050000},{0.856250,0.631250,0.025000,0.025000},{0.856250,0.631250,0.050000,0.050000},{0.868750,0.631250,0.025000,0.025000},{0.868750,0.631250,0.050000,0.050000},{0.881250,0.631250,0.025000,0.025000},{0.881250,0.631250,0.050000,0.050000},{0.893750,0.631250,0.025000,0.025000},{0.893750,0.631250,0.050000,0.050000},{0.906250,0.631250,0.025000,0.025000},{0.906250,0.631250,0.050000,0.050000},{0.918750,0.631250,0.025000,0.025000},{0.918750,0.631250,0.050000,0.050000},{0.931250,0.631250,0.025000,0.025000},{0.931250,0.631250,0.050000,0.050000},{0.943750,0.631250,0.025000,0.025000},{0.943750,0.631250,0.050000,0.050000},{0.956250,0.631250,0.025000,0.025000},{0.956250,0.631250,0.050000,0.050000},{0.968750,0.631250,0.025000,0.025000},{0.968750,0.631250,0.050000,0.050000},{0.981250,0.631250,0.025000,0.025000},{0.981250,0.631250,0.050000,0.050000},{0.993750,0.631250,0.025000,0.025000},{0.993750,0.631250,0.050000,0.050000},{0.006250,0.643750,0.025000,0.025000},{0.006250,0.643750,0.050000,0.050000},{0.018750,0.643750,0.025000,0.025000},{0.018750,0.643750,0.050000,0.050000},{0.031250,0.643750,0.025000,0.025000},{0.031250,0.643750,0.050000,0.050000},{0.043750,0.643750,0.025000,0.025000},{0.043750,0.643750,0.050000,0.050000},{0.056250,0.643750,0.025000,0.025000},{0.056250,0.643750,0.050000,0.050000},{0.068750,0.643750,0.025000,0.025000},{0.068750,0.643750,0.050000,0.050000},{0.081250,0.643750,0.025000,0.025000},{0.081250,0.643750,0.050000,0.050000},{0.093750,0.643750,0.025000,0.025000},{0.093750,0.643750,0.050000,0.050000},{0.106250,0.643750,0.025000,0.025000},{0.106250,0.643750,0.050000,0.050000},{0.118750,0.643750,0.025000,0.025000},{0.118750,0.643750,0.050000,0.050000},{0.131250,0.643750,0.025000,0.025000},{0.131250,0.643750,0.050000,0.050000},{0.143750,0.643750,0.025000,0.025000},{0.143750,0.643750,0.050000,0.050000},{0.156250,0.643750,0.025000,0.025000},{0.156250,0.643750,0.050000,0.050000},{0.168750,0.643750,0.025000,0.025000},{0.168750,0.643750,0.050000,0.050000},{0.181250,0.643750,0.025000,0.025000},{0.181250,0.643750,0.050000,0.050000},{0.193750,0.643750,0.025000,0.025000},{0.193750,0.643750,0.050000,0.050000},{0.206250,0.643750,0.025000,0.025000},{0.206250,0.643750,0.050000,0.050000},{0.218750,0.643750,0.025000,0.025000},{0.218750,0.643750,0.050000,0.050000},{0.231250,0.643750,0.025000,0.025000},{0.231250,0.643750,0.050000,0.050000},{0.243750,0.643750,0.025000,0.025000},{0.243750,0.643750,0.050000,0.050000},{0.256250,0.643750,0.025000,0.025000},{0.256250,0.643750,0.050000,0.050000},{0.268750,0.643750,0.025000,0.025000},{0.268750,0.643750,0.050000,0.050000},{0.281250,0.643750,0.025000,0.025000},{0.281250,0.643750,0.050000,0.050000},{0.293750,0.643750,0.025000,0.025000},{0.293750,0.643750,0.050000,0.050000},{0.306250,0.643750,0.025000,0.025000},{0.306250,0.643750,0.050000,0.050000},{0.318750,0.643750,0.025000,0.025000},{0.318750,0.643750,0.050000,0.050000},{0.331250,0.643750,0.025000,0.025000},{0.331250,0.643750,0.050000,0.050000},{0.343750,0.643750,0.025000,0.025000},{0.343750,0.643750,0.050000,0.050000},{0.356250,0.643750,0.025000,0.025000},{0.356250,0.643750,0.050000,0.050000},{0.368750,0.643750,0.025000,0.025000},{0.368750,0.643750,0.050000,0.050000},{0.381250,0.643750,0.025000,0.025000},{0.381250,0.643750,0.050000,0.050000},{0.393750,0.643750,0.025000,0.025000},{0.393750,0.643750,0.050000,0.050000},{0.406250,0.643750,0.025000,0.025000},{0.406250,0.643750,0.050000,0.050000},{0.418750,0.643750,0.025000,0.025000},{0.418750,0.643750,0.050000,0.050000},{0.431250,0.643750,0.025000,0.025000},{0.431250,0.643750,0.050000,0.050000},{0.443750,0.643750,0.025000,0.025000},{0.443750,0.643750,0.050000,0.050000},{0.456250,0.643750,0.025000,0.025000},{0.456250,0.643750,0.050000,0.050000},{0.468750,0.643750,0.025000,0.025000},{0.468750,0.643750,0.050000,0.050000},{0.481250,0.643750,0.025000,0.025000},{0.481250,0.643750,0.050000,0.050000},{0.493750,0.643750,0.025000,0.025000},{0.493750,0.643750,0.050000,0.050000},{0.506250,0.643750,0.025000,0.025000},{0.506250,0.643750,0.050000,0.050000},{0.518750,0.643750,0.025000,0.025000},{0.518750,0.643750,0.050000,0.050000},{0.531250,0.643750,0.025000,0.025000},{0.531250,0.643750,0.050000,0.050000},{0.543750,0.643750,0.025000,0.025000},{0.543750,0.643750,0.050000,0.050000},{0.556250,0.643750,0.025000,0.025000},{0.556250,0.643750,0.050000,0.050000},{0.568750,0.643750,0.025000,0.025000},{0.568750,0.643750,0.050000,0.050000},{0.581250,0.643750,0.025000,0.025000},{0.581250,0.643750,0.050000,0.050000},{0.593750,0.643750,0.025000,0.025000},{0.593750,0.643750,0.050000,0.050000},{0.606250,0.643750,0.025000,0.025000},{0.606250,0.643750,0.050000,0.050000},{0.618750,0.643750,0.025000,0.025000},{0.618750,0.643750,0.050000,0.050000},{0.631250,0.643750,0.025000,0.025000},{0.631250,0.643750,0.050000,0.050000},{0.643750,0.643750,0.025000,0.025000},{0.643750,0.643750,0.050000,0.050000},{0.656250,0.643750,0.025000,0.025000},{0.656250,0.643750,0.050000,0.050000},{0.668750,0.643750,0.025000,0.025000},{0.668750,0.643750,0.050000,0.050000},{0.681250,0.643750,0.025000,0.025000},{0.681250,0.643750,0.050000,0.050000},{0.693750,0.643750,0.025000,0.025000},{0.693750,0.643750,0.050000,0.050000},{0.706250,0.643750,0.025000,0.025000},{0.706250,0.643750,0.050000,0.050000},{0.718750,0.643750,0.025000,0.025000},{0.718750,0.643750,0.050000,0.050000},{0.731250,0.643750,0.025000,0.025000},{0.731250,0.643750,0.050000,0.050000},{0.743750,0.643750,0.025000,0.025000},{0.743750,0.643750,0.050000,0.050000},{0.756250,0.643750,0.025000,0.025000},{0.756250,0.643750,0.050000,0.050000},{0.768750,0.643750,0.025000,0.025000},{0.768750,0.643750,0.050000,0.050000},{0.781250,0.643750,0.025000,0.025000},{0.781250,0.643750,0.050000,0.050000},{0.793750,0.643750,0.025000,0.025000},{0.793750,0.643750,0.050000,0.050000},{0.806250,0.643750,0.025000,0.025000},{0.806250,0.643750,0.050000,0.050000},{0.818750,0.643750,0.025000,0.025000},{0.818750,0.643750,0.050000,0.050000},{0.831250,0.643750,0.025000,0.025000},{0.831250,0.643750,0.050000,0.050000},{0.843750,0.643750,0.025000,0.025000},{0.843750,0.643750,0.050000,0.050000},{0.856250,0.643750,0.025000,0.025000},{0.856250,0.643750,0.050000,0.050000},{0.868750,0.643750,0.025000,0.025000},{0.868750,0.643750,0.050000,0.050000},{0.881250,0.643750,0.025000,0.025000},{0.881250,0.643750,0.050000,0.050000},{0.893750,0.643750,0.025000,0.025000},{0.893750,0.643750,0.050000,0.050000},{0.906250,0.643750,0.025000,0.025000},{0.906250,0.643750,0.050000,0.050000},{0.918750,0.643750,0.025000,0.025000},{0.918750,0.643750,0.050000,0.050000},{0.931250,0.643750,0.025000,0.025000},{0.931250,0.643750,0.050000,0.050000},{0.943750,0.643750,0.025000,0.025000},{0.943750,0.643750,0.050000,0.050000},{0.956250,0.643750,0.025000,0.025000},{0.956250,0.643750,0.050000,0.050000},{0.968750,0.643750,0.025000,0.025000},{0.968750,0.643750,0.050000,0.050000},{0.981250,0.643750,0.025000,0.025000},{0.981250,0.643750,0.050000,0.050000},{0.993750,0.643750,0.025000,0.025000},{0.993750,0.643750,0.050000,0.050000},{0.006250,0.656250,0.025000,0.025000},{0.006250,0.656250,0.050000,0.050000},{0.018750,0.656250,0.025000,0.025000},{0.018750,0.656250,0.050000,0.050000},{0.031250,0.656250,0.025000,0.025000},{0.031250,0.656250,0.050000,0.050000},{0.043750,0.656250,0.025000,0.025000},{0.043750,0.656250,0.050000,0.050000},{0.056250,0.656250,0.025000,0.025000},{0.056250,0.656250,0.050000,0.050000},{0.068750,0.656250,0.025000,0.025000},{0.068750,0.656250,0.050000,0.050000},{0.081250,0.656250,0.025000,0.025000},{0.081250,0.656250,0.050000,0.050000},{0.093750,0.656250,0.025000,0.025000},{0.093750,0.656250,0.050000,0.050000},{0.106250,0.656250,0.025000,0.025000},{0.106250,0.656250,0.050000,0.050000},{0.118750,0.656250,0.025000,0.025000},{0.118750,0.656250,0.050000,0.050000},{0.131250,0.656250,0.025000,0.025000},{0.131250,0.656250,0.050000,0.050000},{0.143750,0.656250,0.025000,0.025000},{0.143750,0.656250,0.050000,0.050000},{0.156250,0.656250,0.025000,0.025000},{0.156250,0.656250,0.050000,0.050000},{0.168750,0.656250,0.025000,0.025000},{0.168750,0.656250,0.050000,0.050000},{0.181250,0.656250,0.025000,0.025000},{0.181250,0.656250,0.050000,0.050000},{0.193750,0.656250,0.025000,0.025000},{0.193750,0.656250,0.050000,0.050000},{0.206250,0.656250,0.025000,0.025000},{0.206250,0.656250,0.050000,0.050000},{0.218750,0.656250,0.025000,0.025000},{0.218750,0.656250,0.050000,0.050000},{0.231250,0.656250,0.025000,0.025000},{0.231250,0.656250,0.050000,0.050000},{0.243750,0.656250,0.025000,0.025000},{0.243750,0.656250,0.050000,0.050000},{0.256250,0.656250,0.025000,0.025000},{0.256250,0.656250,0.050000,0.050000},{0.268750,0.656250,0.025000,0.025000},{0.268750,0.656250,0.050000,0.050000},{0.281250,0.656250,0.025000,0.025000},{0.281250,0.656250,0.050000,0.050000},{0.293750,0.656250,0.025000,0.025000},{0.293750,0.656250,0.050000,0.050000},{0.306250,0.656250,0.025000,0.025000},{0.306250,0.656250,0.050000,0.050000},{0.318750,0.656250,0.025000,0.025000},{0.318750,0.656250,0.050000,0.050000},{0.331250,0.656250,0.025000,0.025000},{0.331250,0.656250,0.050000,0.050000},{0.343750,0.656250,0.025000,0.025000},{0.343750,0.656250,0.050000,0.050000},{0.356250,0.656250,0.025000,0.025000},{0.356250,0.656250,0.050000,0.050000},{0.368750,0.656250,0.025000,0.025000},{0.368750,0.656250,0.050000,0.050000},{0.381250,0.656250,0.025000,0.025000},{0.381250,0.656250,0.050000,0.050000},{0.393750,0.656250,0.025000,0.025000},{0.393750,0.656250,0.050000,0.050000},{0.406250,0.656250,0.025000,0.025000},{0.406250,0.656250,0.050000,0.050000},{0.418750,0.656250,0.025000,0.025000},{0.418750,0.656250,0.050000,0.050000},{0.431250,0.656250,0.025000,0.025000},{0.431250,0.656250,0.050000,0.050000},{0.443750,0.656250,0.025000,0.025000},{0.443750,0.656250,0.050000,0.050000},{0.456250,0.656250,0.025000,0.025000},{0.456250,0.656250,0.050000,0.050000},{0.468750,0.656250,0.025000,0.025000},{0.468750,0.656250,0.050000,0.050000},{0.481250,0.656250,0.025000,0.025000},{0.481250,0.656250,0.050000,0.050000},{0.493750,0.656250,0.025000,0.025000},{0.493750,0.656250,0.050000,0.050000},{0.506250,0.656250,0.025000,0.025000},{0.506250,0.656250,0.050000,0.050000},{0.518750,0.656250,0.025000,0.025000},{0.518750,0.656250,0.050000,0.050000},{0.531250,0.656250,0.025000,0.025000},{0.531250,0.656250,0.050000,0.050000},{0.543750,0.656250,0.025000,0.025000},{0.543750,0.656250,0.050000,0.050000},{0.556250,0.656250,0.025000,0.025000},{0.556250,0.656250,0.050000,0.050000},{0.568750,0.656250,0.025000,0.025000},{0.568750,0.656250,0.050000,0.050000},{0.581250,0.656250,0.025000,0.025000},{0.581250,0.656250,0.050000,0.050000},{0.593750,0.656250,0.025000,0.025000},{0.593750,0.656250,0.050000,0.050000},{0.606250,0.656250,0.025000,0.025000},{0.606250,0.656250,0.050000,0.050000},{0.618750,0.656250,0.025000,0.025000},{0.618750,0.656250,0.050000,0.050000},{0.631250,0.656250,0.025000,0.025000},{0.631250,0.656250,0.050000,0.050000},{0.643750,0.656250,0.025000,0.025000},{0.643750,0.656250,0.050000,0.050000},{0.656250,0.656250,0.025000,0.025000},{0.656250,0.656250,0.050000,0.050000},{0.668750,0.656250,0.025000,0.025000},{0.668750,0.656250,0.050000,0.050000},{0.681250,0.656250,0.025000,0.025000},{0.681250,0.656250,0.050000,0.050000},{0.693750,0.656250,0.025000,0.025000},{0.693750,0.656250,0.050000,0.050000},{0.706250,0.656250,0.025000,0.025000},{0.706250,0.656250,0.050000,0.050000},{0.718750,0.656250,0.025000,0.025000},{0.718750,0.656250,0.050000,0.050000},{0.731250,0.656250,0.025000,0.025000},{0.731250,0.656250,0.050000,0.050000},{0.743750,0.656250,0.025000,0.025000},{0.743750,0.656250,0.050000,0.050000},{0.756250,0.656250,0.025000,0.025000},{0.756250,0.656250,0.050000,0.050000},{0.768750,0.656250,0.025000,0.025000},{0.768750,0.656250,0.050000,0.050000},{0.781250,0.656250,0.025000,0.025000},{0.781250,0.656250,0.050000,0.050000},{0.793750,0.656250,0.025000,0.025000},{0.793750,0.656250,0.050000,0.050000},{0.806250,0.656250,0.025000,0.025000},{0.806250,0.656250,0.050000,0.050000},{0.818750,0.656250,0.025000,0.025000},{0.818750,0.656250,0.050000,0.050000},{0.831250,0.656250,0.025000,0.025000},{0.831250,0.656250,0.050000,0.050000},{0.843750,0.656250,0.025000,0.025000},{0.843750,0.656250,0.050000,0.050000},{0.856250,0.656250,0.025000,0.025000},{0.856250,0.656250,0.050000,0.050000},{0.868750,0.656250,0.025000,0.025000},{0.868750,0.656250,0.050000,0.050000},{0.881250,0.656250,0.025000,0.025000},{0.881250,0.656250,0.050000,0.050000},{0.893750,0.656250,0.025000,0.025000},{0.893750,0.656250,0.050000,0.050000},{0.906250,0.656250,0.025000,0.025000},{0.906250,0.656250,0.050000,0.050000},{0.918750,0.656250,0.025000,0.025000},{0.918750,0.656250,0.050000,0.050000},{0.931250,0.656250,0.025000,0.025000},{0.931250,0.656250,0.050000,0.050000},{0.943750,0.656250,0.025000,0.025000},{0.943750,0.656250,0.050000,0.050000},{0.956250,0.656250,0.025000,0.025000},{0.956250,0.656250,0.050000,0.050000},{0.968750,0.656250,0.025000,0.025000},{0.968750,0.656250,0.050000,0.050000},{0.981250,0.656250,0.025000,0.025000},{0.981250,0.656250,0.050000,0.050000},{0.993750,0.656250,0.025000,0.025000},{0.993750,0.656250,0.050000,0.050000},{0.006250,0.668750,0.025000,0.025000},{0.006250,0.668750,0.050000,0.050000},{0.018750,0.668750,0.025000,0.025000},{0.018750,0.668750,0.050000,0.050000},{0.031250,0.668750,0.025000,0.025000},{0.031250,0.668750,0.050000,0.050000},{0.043750,0.668750,0.025000,0.025000},{0.043750,0.668750,0.050000,0.050000},{0.056250,0.668750,0.025000,0.025000},{0.056250,0.668750,0.050000,0.050000},{0.068750,0.668750,0.025000,0.025000},{0.068750,0.668750,0.050000,0.050000},{0.081250,0.668750,0.025000,0.025000},{0.081250,0.668750,0.050000,0.050000},{0.093750,0.668750,0.025000,0.025000},{0.093750,0.668750,0.050000,0.050000},{0.106250,0.668750,0.025000,0.025000},{0.106250,0.668750,0.050000,0.050000},{0.118750,0.668750,0.025000,0.025000},{0.118750,0.668750,0.050000,0.050000},{0.131250,0.668750,0.025000,0.025000},{0.131250,0.668750,0.050000,0.050000},{0.143750,0.668750,0.025000,0.025000},{0.143750,0.668750,0.050000,0.050000},{0.156250,0.668750,0.025000,0.025000},{0.156250,0.668750,0.050000,0.050000},{0.168750,0.668750,0.025000,0.025000},{0.168750,0.668750,0.050000,0.050000},{0.181250,0.668750,0.025000,0.025000},{0.181250,0.668750,0.050000,0.050000},{0.193750,0.668750,0.025000,0.025000},{0.193750,0.668750,0.050000,0.050000},{0.206250,0.668750,0.025000,0.025000},{0.206250,0.668750,0.050000,0.050000},{0.218750,0.668750,0.025000,0.025000},{0.218750,0.668750,0.050000,0.050000},{0.231250,0.668750,0.025000,0.025000},{0.231250,0.668750,0.050000,0.050000},{0.243750,0.668750,0.025000,0.025000},{0.243750,0.668750,0.050000,0.050000},{0.256250,0.668750,0.025000,0.025000},{0.256250,0.668750,0.050000,0.050000},{0.268750,0.668750,0.025000,0.025000},{0.268750,0.668750,0.050000,0.050000},{0.281250,0.668750,0.025000,0.025000},{0.281250,0.668750,0.050000,0.050000},{0.293750,0.668750,0.025000,0.025000},{0.293750,0.668750,0.050000,0.050000},{0.306250,0.668750,0.025000,0.025000},{0.306250,0.668750,0.050000,0.050000},{0.318750,0.668750,0.025000,0.025000},{0.318750,0.668750,0.050000,0.050000},{0.331250,0.668750,0.025000,0.025000},{0.331250,0.668750,0.050000,0.050000},{0.343750,0.668750,0.025000,0.025000},{0.343750,0.668750,0.050000,0.050000},{0.356250,0.668750,0.025000,0.025000},{0.356250,0.668750,0.050000,0.050000},{0.368750,0.668750,0.025000,0.025000},{0.368750,0.668750,0.050000,0.050000},{0.381250,0.668750,0.025000,0.025000},{0.381250,0.668750,0.050000,0.050000},{0.393750,0.668750,0.025000,0.025000},{0.393750,0.668750,0.050000,0.050000},{0.406250,0.668750,0.025000,0.025000},{0.406250,0.668750,0.050000,0.050000},{0.418750,0.668750,0.025000,0.025000},{0.418750,0.668750,0.050000,0.050000},{0.431250,0.668750,0.025000,0.025000},{0.431250,0.668750,0.050000,0.050000},{0.443750,0.668750,0.025000,0.025000},{0.443750,0.668750,0.050000,0.050000},{0.456250,0.668750,0.025000,0.025000},{0.456250,0.668750,0.050000,0.050000},{0.468750,0.668750,0.025000,0.025000},{0.468750,0.668750,0.050000,0.050000},{0.481250,0.668750,0.025000,0.025000},{0.481250,0.668750,0.050000,0.050000},{0.493750,0.668750,0.025000,0.025000},{0.493750,0.668750,0.050000,0.050000},{0.506250,0.668750,0.025000,0.025000},{0.506250,0.668750,0.050000,0.050000},{0.518750,0.668750,0.025000,0.025000},{0.518750,0.668750,0.050000,0.050000},{0.531250,0.668750,0.025000,0.025000},{0.531250,0.668750,0.050000,0.050000},{0.543750,0.668750,0.025000,0.025000},{0.543750,0.668750,0.050000,0.050000},{0.556250,0.668750,0.025000,0.025000},{0.556250,0.668750,0.050000,0.050000},{0.568750,0.668750,0.025000,0.025000},{0.568750,0.668750,0.050000,0.050000},{0.581250,0.668750,0.025000,0.025000},{0.581250,0.668750,0.050000,0.050000},{0.593750,0.668750,0.025000,0.025000},{0.593750,0.668750,0.050000,0.050000},{0.606250,0.668750,0.025000,0.025000},{0.606250,0.668750,0.050000,0.050000},{0.618750,0.668750,0.025000,0.025000},{0.618750,0.668750,0.050000,0.050000},{0.631250,0.668750,0.025000,0.025000},{0.631250,0.668750,0.050000,0.050000},{0.643750,0.668750,0.025000,0.025000},{0.643750,0.668750,0.050000,0.050000},{0.656250,0.668750,0.025000,0.025000},{0.656250,0.668750,0.050000,0.050000},{0.668750,0.668750,0.025000,0.025000},{0.668750,0.668750,0.050000,0.050000},{0.681250,0.668750,0.025000,0.025000},{0.681250,0.668750,0.050000,0.050000},{0.693750,0.668750,0.025000,0.025000},{0.693750,0.668750,0.050000,0.050000},{0.706250,0.668750,0.025000,0.025000},{0.706250,0.668750,0.050000,0.050000},{0.718750,0.668750,0.025000,0.025000},{0.718750,0.668750,0.050000,0.050000},{0.731250,0.668750,0.025000,0.025000},{0.731250,0.668750,0.050000,0.050000},{0.743750,0.668750,0.025000,0.025000},{0.743750,0.668750,0.050000,0.050000},{0.756250,0.668750,0.025000,0.025000},{0.756250,0.668750,0.050000,0.050000},{0.768750,0.668750,0.025000,0.025000},{0.768750,0.668750,0.050000,0.050000},{0.781250,0.668750,0.025000,0.025000},{0.781250,0.668750,0.050000,0.050000},{0.793750,0.668750,0.025000,0.025000},{0.793750,0.668750,0.050000,0.050000},{0.806250,0.668750,0.025000,0.025000},{0.806250,0.668750,0.050000,0.050000},{0.818750,0.668750,0.025000,0.025000},{0.818750,0.668750,0.050000,0.050000},{0.831250,0.668750,0.025000,0.025000},{0.831250,0.668750,0.050000,0.050000},{0.843750,0.668750,0.025000,0.025000},{0.843750,0.668750,0.050000,0.050000},{0.856250,0.668750,0.025000,0.025000},{0.856250,0.668750,0.050000,0.050000},{0.868750,0.668750,0.025000,0.025000},{0.868750,0.668750,0.050000,0.050000},{0.881250,0.668750,0.025000,0.025000},{0.881250,0.668750,0.050000,0.050000},{0.893750,0.668750,0.025000,0.025000},{0.893750,0.668750,0.050000,0.050000},{0.906250,0.668750,0.025000,0.025000},{0.906250,0.668750,0.050000,0.050000},{0.918750,0.668750,0.025000,0.025000},{0.918750,0.668750,0.050000,0.050000},{0.931250,0.668750,0.025000,0.025000},{0.931250,0.668750,0.050000,0.050000},{0.943750,0.668750,0.025000,0.025000},{0.943750,0.668750,0.050000,0.050000},{0.956250,0.668750,0.025000,0.025000},{0.956250,0.668750,0.050000,0.050000},{0.968750,0.668750,0.025000,0.025000},{0.968750,0.668750,0.050000,0.050000},{0.981250,0.668750,0.025000,0.025000},{0.981250,0.668750,0.050000,0.050000},{0.993750,0.668750,0.025000,0.025000},{0.993750,0.668750,0.050000,0.050000},{0.006250,0.681250,0.025000,0.025000},{0.006250,0.681250,0.050000,0.050000},{0.018750,0.681250,0.025000,0.025000},{0.018750,0.681250,0.050000,0.050000},{0.031250,0.681250,0.025000,0.025000},{0.031250,0.681250,0.050000,0.050000},{0.043750,0.681250,0.025000,0.025000},{0.043750,0.681250,0.050000,0.050000},{0.056250,0.681250,0.025000,0.025000},{0.056250,0.681250,0.050000,0.050000},{0.068750,0.681250,0.025000,0.025000},{0.068750,0.681250,0.050000,0.050000},{0.081250,0.681250,0.025000,0.025000},{0.081250,0.681250,0.050000,0.050000},{0.093750,0.681250,0.025000,0.025000},{0.093750,0.681250,0.050000,0.050000},{0.106250,0.681250,0.025000,0.025000},{0.106250,0.681250,0.050000,0.050000},{0.118750,0.681250,0.025000,0.025000},{0.118750,0.681250,0.050000,0.050000},{0.131250,0.681250,0.025000,0.025000},{0.131250,0.681250,0.050000,0.050000},{0.143750,0.681250,0.025000,0.025000},{0.143750,0.681250,0.050000,0.050000},{0.156250,0.681250,0.025000,0.025000},{0.156250,0.681250,0.050000,0.050000},{0.168750,0.681250,0.025000,0.025000},{0.168750,0.681250,0.050000,0.050000},{0.181250,0.681250,0.025000,0.025000},{0.181250,0.681250,0.050000,0.050000},{0.193750,0.681250,0.025000,0.025000},{0.193750,0.681250,0.050000,0.050000},{0.206250,0.681250,0.025000,0.025000},{0.206250,0.681250,0.050000,0.050000},{0.218750,0.681250,0.025000,0.025000},{0.218750,0.681250,0.050000,0.050000},{0.231250,0.681250,0.025000,0.025000},{0.231250,0.681250,0.050000,0.050000},{0.243750,0.681250,0.025000,0.025000},{0.243750,0.681250,0.050000,0.050000},{0.256250,0.681250,0.025000,0.025000},{0.256250,0.681250,0.050000,0.050000},{0.268750,0.681250,0.025000,0.025000},{0.268750,0.681250,0.050000,0.050000},{0.281250,0.681250,0.025000,0.025000},{0.281250,0.681250,0.050000,0.050000},{0.293750,0.681250,0.025000,0.025000},{0.293750,0.681250,0.050000,0.050000},{0.306250,0.681250,0.025000,0.025000},{0.306250,0.681250,0.050000,0.050000},{0.318750,0.681250,0.025000,0.025000},{0.318750,0.681250,0.050000,0.050000},{0.331250,0.681250,0.025000,0.025000},{0.331250,0.681250,0.050000,0.050000},{0.343750,0.681250,0.025000,0.025000},{0.343750,0.681250,0.050000,0.050000},{0.356250,0.681250,0.025000,0.025000},{0.356250,0.681250,0.050000,0.050000},{0.368750,0.681250,0.025000,0.025000},{0.368750,0.681250,0.050000,0.050000},{0.381250,0.681250,0.025000,0.025000},{0.381250,0.681250,0.050000,0.050000},{0.393750,0.681250,0.025000,0.025000},{0.393750,0.681250,0.050000,0.050000},{0.406250,0.681250,0.025000,0.025000},{0.406250,0.681250,0.050000,0.050000},{0.418750,0.681250,0.025000,0.025000},{0.418750,0.681250,0.050000,0.050000},{0.431250,0.681250,0.025000,0.025000},{0.431250,0.681250,0.050000,0.050000},{0.443750,0.681250,0.025000,0.025000},{0.443750,0.681250,0.050000,0.050000},{0.456250,0.681250,0.025000,0.025000},{0.456250,0.681250,0.050000,0.050000},{0.468750,0.681250,0.025000,0.025000},{0.468750,0.681250,0.050000,0.050000},{0.481250,0.681250,0.025000,0.025000},{0.481250,0.681250,0.050000,0.050000},{0.493750,0.681250,0.025000,0.025000},{0.493750,0.681250,0.050000,0.050000},{0.506250,0.681250,0.025000,0.025000},{0.506250,0.681250,0.050000,0.050000},{0.518750,0.681250,0.025000,0.025000},{0.518750,0.681250,0.050000,0.050000},{0.531250,0.681250,0.025000,0.025000},{0.531250,0.681250,0.050000,0.050000},{0.543750,0.681250,0.025000,0.025000},{0.543750,0.681250,0.050000,0.050000},{0.556250,0.681250,0.025000,0.025000},{0.556250,0.681250,0.050000,0.050000},{0.568750,0.681250,0.025000,0.025000},{0.568750,0.681250,0.050000,0.050000},{0.581250,0.681250,0.025000,0.025000},{0.581250,0.681250,0.050000,0.050000},{0.593750,0.681250,0.025000,0.025000},{0.593750,0.681250,0.050000,0.050000},{0.606250,0.681250,0.025000,0.025000},{0.606250,0.681250,0.050000,0.050000},{0.618750,0.681250,0.025000,0.025000},{0.618750,0.681250,0.050000,0.050000},{0.631250,0.681250,0.025000,0.025000},{0.631250,0.681250,0.050000,0.050000},{0.643750,0.681250,0.025000,0.025000},{0.643750,0.681250,0.050000,0.050000},{0.656250,0.681250,0.025000,0.025000},{0.656250,0.681250,0.050000,0.050000},{0.668750,0.681250,0.025000,0.025000},{0.668750,0.681250,0.050000,0.050000},{0.681250,0.681250,0.025000,0.025000},{0.681250,0.681250,0.050000,0.050000},{0.693750,0.681250,0.025000,0.025000},{0.693750,0.681250,0.050000,0.050000},{0.706250,0.681250,0.025000,0.025000},{0.706250,0.681250,0.050000,0.050000},{0.718750,0.681250,0.025000,0.025000},{0.718750,0.681250,0.050000,0.050000},{0.731250,0.681250,0.025000,0.025000},{0.731250,0.681250,0.050000,0.050000},{0.743750,0.681250,0.025000,0.025000},{0.743750,0.681250,0.050000,0.050000},{0.756250,0.681250,0.025000,0.025000},{0.756250,0.681250,0.050000,0.050000},{0.768750,0.681250,0.025000,0.025000},{0.768750,0.681250,0.050000,0.050000},{0.781250,0.681250,0.025000,0.025000},{0.781250,0.681250,0.050000,0.050000},{0.793750,0.681250,0.025000,0.025000},{0.793750,0.681250,0.050000,0.050000},{0.806250,0.681250,0.025000,0.025000},{0.806250,0.681250,0.050000,0.050000},{0.818750,0.681250,0.025000,0.025000},{0.818750,0.681250,0.050000,0.050000},{0.831250,0.681250,0.025000,0.025000},{0.831250,0.681250,0.050000,0.050000},{0.843750,0.681250,0.025000,0.025000},{0.843750,0.681250,0.050000,0.050000},{0.856250,0.681250,0.025000,0.025000},{0.856250,0.681250,0.050000,0.050000},{0.868750,0.681250,0.025000,0.025000},{0.868750,0.681250,0.050000,0.050000},{0.881250,0.681250,0.025000,0.025000},{0.881250,0.681250,0.050000,0.050000},{0.893750,0.681250,0.025000,0.025000},{0.893750,0.681250,0.050000,0.050000},{0.906250,0.681250,0.025000,0.025000},{0.906250,0.681250,0.050000,0.050000},{0.918750,0.681250,0.025000,0.025000},{0.918750,0.681250,0.050000,0.050000},{0.931250,0.681250,0.025000,0.025000},{0.931250,0.681250,0.050000,0.050000},{0.943750,0.681250,0.025000,0.025000},{0.943750,0.681250,0.050000,0.050000},{0.956250,0.681250,0.025000,0.025000},{0.956250,0.681250,0.050000,0.050000},{0.968750,0.681250,0.025000,0.025000},{0.968750,0.681250,0.050000,0.050000},{0.981250,0.681250,0.025000,0.025000},{0.981250,0.681250,0.050000,0.050000},{0.993750,0.681250,0.025000,0.025000},{0.993750,0.681250,0.050000,0.050000},{0.006250,0.693750,0.025000,0.025000},{0.006250,0.693750,0.050000,0.050000},{0.018750,0.693750,0.025000,0.025000},{0.018750,0.693750,0.050000,0.050000},{0.031250,0.693750,0.025000,0.025000},{0.031250,0.693750,0.050000,0.050000},{0.043750,0.693750,0.025000,0.025000},{0.043750,0.693750,0.050000,0.050000},{0.056250,0.693750,0.025000,0.025000},{0.056250,0.693750,0.050000,0.050000},{0.068750,0.693750,0.025000,0.025000},{0.068750,0.693750,0.050000,0.050000},{0.081250,0.693750,0.025000,0.025000},{0.081250,0.693750,0.050000,0.050000},{0.093750,0.693750,0.025000,0.025000},{0.093750,0.693750,0.050000,0.050000},{0.106250,0.693750,0.025000,0.025000},{0.106250,0.693750,0.050000,0.050000},{0.118750,0.693750,0.025000,0.025000},{0.118750,0.693750,0.050000,0.050000},{0.131250,0.693750,0.025000,0.025000},{0.131250,0.693750,0.050000,0.050000},{0.143750,0.693750,0.025000,0.025000},{0.143750,0.693750,0.050000,0.050000},{0.156250,0.693750,0.025000,0.025000},{0.156250,0.693750,0.050000,0.050000},{0.168750,0.693750,0.025000,0.025000},{0.168750,0.693750,0.050000,0.050000},{0.181250,0.693750,0.025000,0.025000},{0.181250,0.693750,0.050000,0.050000},{0.193750,0.693750,0.025000,0.025000},{0.193750,0.693750,0.050000,0.050000},{0.206250,0.693750,0.025000,0.025000},{0.206250,0.693750,0.050000,0.050000},{0.218750,0.693750,0.025000,0.025000},{0.218750,0.693750,0.050000,0.050000},{0.231250,0.693750,0.025000,0.025000},{0.231250,0.693750,0.050000,0.050000},{0.243750,0.693750,0.025000,0.025000},{0.243750,0.693750,0.050000,0.050000},{0.256250,0.693750,0.025000,0.025000},{0.256250,0.693750,0.050000,0.050000},{0.268750,0.693750,0.025000,0.025000},{0.268750,0.693750,0.050000,0.050000},{0.281250,0.693750,0.025000,0.025000},{0.281250,0.693750,0.050000,0.050000},{0.293750,0.693750,0.025000,0.025000},{0.293750,0.693750,0.050000,0.050000},{0.306250,0.693750,0.025000,0.025000},{0.306250,0.693750,0.050000,0.050000},{0.318750,0.693750,0.025000,0.025000},{0.318750,0.693750,0.050000,0.050000},{0.331250,0.693750,0.025000,0.025000},{0.331250,0.693750,0.050000,0.050000},{0.343750,0.693750,0.025000,0.025000},{0.343750,0.693750,0.050000,0.050000},{0.356250,0.693750,0.025000,0.025000},{0.356250,0.693750,0.050000,0.050000},{0.368750,0.693750,0.025000,0.025000},{0.368750,0.693750,0.050000,0.050000},{0.381250,0.693750,0.025000,0.025000},{0.381250,0.693750,0.050000,0.050000},{0.393750,0.693750,0.025000,0.025000},{0.393750,0.693750,0.050000,0.050000},{0.406250,0.693750,0.025000,0.025000},{0.406250,0.693750,0.050000,0.050000},{0.418750,0.693750,0.025000,0.025000},{0.418750,0.693750,0.050000,0.050000},{0.431250,0.693750,0.025000,0.025000},{0.431250,0.693750,0.050000,0.050000},{0.443750,0.693750,0.025000,0.025000},{0.443750,0.693750,0.050000,0.050000},{0.456250,0.693750,0.025000,0.025000},{0.456250,0.693750,0.050000,0.050000},{0.468750,0.693750,0.025000,0.025000},{0.468750,0.693750,0.050000,0.050000},{0.481250,0.693750,0.025000,0.025000},{0.481250,0.693750,0.050000,0.050000},{0.493750,0.693750,0.025000,0.025000},{0.493750,0.693750,0.050000,0.050000},{0.506250,0.693750,0.025000,0.025000},{0.506250,0.693750,0.050000,0.050000},{0.518750,0.693750,0.025000,0.025000},{0.518750,0.693750,0.050000,0.050000},{0.531250,0.693750,0.025000,0.025000},{0.531250,0.693750,0.050000,0.050000},{0.543750,0.693750,0.025000,0.025000},{0.543750,0.693750,0.050000,0.050000},{0.556250,0.693750,0.025000,0.025000},{0.556250,0.693750,0.050000,0.050000},{0.568750,0.693750,0.025000,0.025000},{0.568750,0.693750,0.050000,0.050000},{0.581250,0.693750,0.025000,0.025000},{0.581250,0.693750,0.050000,0.050000},{0.593750,0.693750,0.025000,0.025000},{0.593750,0.693750,0.050000,0.050000},{0.606250,0.693750,0.025000,0.025000},{0.606250,0.693750,0.050000,0.050000},{0.618750,0.693750,0.025000,0.025000},{0.618750,0.693750,0.050000,0.050000},{0.631250,0.693750,0.025000,0.025000},{0.631250,0.693750,0.050000,0.050000},{0.643750,0.693750,0.025000,0.025000},{0.643750,0.693750,0.050000,0.050000},{0.656250,0.693750,0.025000,0.025000},{0.656250,0.693750,0.050000,0.050000},{0.668750,0.693750,0.025000,0.025000},{0.668750,0.693750,0.050000,0.050000},{0.681250,0.693750,0.025000,0.025000},{0.681250,0.693750,0.050000,0.050000},{0.693750,0.693750,0.025000,0.025000},{0.693750,0.693750,0.050000,0.050000},{0.706250,0.693750,0.025000,0.025000},{0.706250,0.693750,0.050000,0.050000},{0.718750,0.693750,0.025000,0.025000},{0.718750,0.693750,0.050000,0.050000},{0.731250,0.693750,0.025000,0.025000},{0.731250,0.693750,0.050000,0.050000},{0.743750,0.693750,0.025000,0.025000},{0.743750,0.693750,0.050000,0.050000},{0.756250,0.693750,0.025000,0.025000},{0.756250,0.693750,0.050000,0.050000},{0.768750,0.693750,0.025000,0.025000},{0.768750,0.693750,0.050000,0.050000},{0.781250,0.693750,0.025000,0.025000},{0.781250,0.693750,0.050000,0.050000},{0.793750,0.693750,0.025000,0.025000},{0.793750,0.693750,0.050000,0.050000},{0.806250,0.693750,0.025000,0.025000},{0.806250,0.693750,0.050000,0.050000},{0.818750,0.693750,0.025000,0.025000},{0.818750,0.693750,0.050000,0.050000},{0.831250,0.693750,0.025000,0.025000},{0.831250,0.693750,0.050000,0.050000},{0.843750,0.693750,0.025000,0.025000},{0.843750,0.693750,0.050000,0.050000},{0.856250,0.693750,0.025000,0.025000},{0.856250,0.693750,0.050000,0.050000},{0.868750,0.693750,0.025000,0.025000},{0.868750,0.693750,0.050000,0.050000},{0.881250,0.693750,0.025000,0.025000},{0.881250,0.693750,0.050000,0.050000},{0.893750,0.693750,0.025000,0.025000},{0.893750,0.693750,0.050000,0.050000},{0.906250,0.693750,0.025000,0.025000},{0.906250,0.693750,0.050000,0.050000},{0.918750,0.693750,0.025000,0.025000},{0.918750,0.693750,0.050000,0.050000},{0.931250,0.693750,0.025000,0.025000},{0.931250,0.693750,0.050000,0.050000},{0.943750,0.693750,0.025000,0.025000},{0.943750,0.693750,0.050000,0.050000},{0.956250,0.693750,0.025000,0.025000},{0.956250,0.693750,0.050000,0.050000},{0.968750,0.693750,0.025000,0.025000},{0.968750,0.693750,0.050000,0.050000},{0.981250,0.693750,0.025000,0.025000},{0.981250,0.693750,0.050000,0.050000},{0.993750,0.693750,0.025000,0.025000},{0.993750,0.693750,0.050000,0.050000},{0.006250,0.706250,0.025000,0.025000},{0.006250,0.706250,0.050000,0.050000},{0.018750,0.706250,0.025000,0.025000},{0.018750,0.706250,0.050000,0.050000},{0.031250,0.706250,0.025000,0.025000},{0.031250,0.706250,0.050000,0.050000},{0.043750,0.706250,0.025000,0.025000},{0.043750,0.706250,0.050000,0.050000},{0.056250,0.706250,0.025000,0.025000},{0.056250,0.706250,0.050000,0.050000},{0.068750,0.706250,0.025000,0.025000},{0.068750,0.706250,0.050000,0.050000},{0.081250,0.706250,0.025000,0.025000},{0.081250,0.706250,0.050000,0.050000},{0.093750,0.706250,0.025000,0.025000},{0.093750,0.706250,0.050000,0.050000},{0.106250,0.706250,0.025000,0.025000},{0.106250,0.706250,0.050000,0.050000},{0.118750,0.706250,0.025000,0.025000},{0.118750,0.706250,0.050000,0.050000},{0.131250,0.706250,0.025000,0.025000},{0.131250,0.706250,0.050000,0.050000},{0.143750,0.706250,0.025000,0.025000},{0.143750,0.706250,0.050000,0.050000},{0.156250,0.706250,0.025000,0.025000},{0.156250,0.706250,0.050000,0.050000},{0.168750,0.706250,0.025000,0.025000},{0.168750,0.706250,0.050000,0.050000},{0.181250,0.706250,0.025000,0.025000},{0.181250,0.706250,0.050000,0.050000},{0.193750,0.706250,0.025000,0.025000},{0.193750,0.706250,0.050000,0.050000},{0.206250,0.706250,0.025000,0.025000},{0.206250,0.706250,0.050000,0.050000},{0.218750,0.706250,0.025000,0.025000},{0.218750,0.706250,0.050000,0.050000},{0.231250,0.706250,0.025000,0.025000},{0.231250,0.706250,0.050000,0.050000},{0.243750,0.706250,0.025000,0.025000},{0.243750,0.706250,0.050000,0.050000},{0.256250,0.706250,0.025000,0.025000},{0.256250,0.706250,0.050000,0.050000},{0.268750,0.706250,0.025000,0.025000},{0.268750,0.706250,0.050000,0.050000},{0.281250,0.706250,0.025000,0.025000},{0.281250,0.706250,0.050000,0.050000},{0.293750,0.706250,0.025000,0.025000},{0.293750,0.706250,0.050000,0.050000},{0.306250,0.706250,0.025000,0.025000},{0.306250,0.706250,0.050000,0.050000},{0.318750,0.706250,0.025000,0.025000},{0.318750,0.706250,0.050000,0.050000},{0.331250,0.706250,0.025000,0.025000},{0.331250,0.706250,0.050000,0.050000},{0.343750,0.706250,0.025000,0.025000},{0.343750,0.706250,0.050000,0.050000},{0.356250,0.706250,0.025000,0.025000},{0.356250,0.706250,0.050000,0.050000},{0.368750,0.706250,0.025000,0.025000},{0.368750,0.706250,0.050000,0.050000},{0.381250,0.706250,0.025000,0.025000},{0.381250,0.706250,0.050000,0.050000},{0.393750,0.706250,0.025000,0.025000},{0.393750,0.706250,0.050000,0.050000},{0.406250,0.706250,0.025000,0.025000},{0.406250,0.706250,0.050000,0.050000},{0.418750,0.706250,0.025000,0.025000},{0.418750,0.706250,0.050000,0.050000},{0.431250,0.706250,0.025000,0.025000},{0.431250,0.706250,0.050000,0.050000},{0.443750,0.706250,0.025000,0.025000},{0.443750,0.706250,0.050000,0.050000},{0.456250,0.706250,0.025000,0.025000},{0.456250,0.706250,0.050000,0.050000},{0.468750,0.706250,0.025000,0.025000},{0.468750,0.706250,0.050000,0.050000},{0.481250,0.706250,0.025000,0.025000},{0.481250,0.706250,0.050000,0.050000},{0.493750,0.706250,0.025000,0.025000},{0.493750,0.706250,0.050000,0.050000},{0.506250,0.706250,0.025000,0.025000},{0.506250,0.706250,0.050000,0.050000},{0.518750,0.706250,0.025000,0.025000},{0.518750,0.706250,0.050000,0.050000},{0.531250,0.706250,0.025000,0.025000},{0.531250,0.706250,0.050000,0.050000},{0.543750,0.706250,0.025000,0.025000},{0.543750,0.706250,0.050000,0.050000},{0.556250,0.706250,0.025000,0.025000},{0.556250,0.706250,0.050000,0.050000},{0.568750,0.706250,0.025000,0.025000},{0.568750,0.706250,0.050000,0.050000},{0.581250,0.706250,0.025000,0.025000},{0.581250,0.706250,0.050000,0.050000},{0.593750,0.706250,0.025000,0.025000},{0.593750,0.706250,0.050000,0.050000},{0.606250,0.706250,0.025000,0.025000},{0.606250,0.706250,0.050000,0.050000},{0.618750,0.706250,0.025000,0.025000},{0.618750,0.706250,0.050000,0.050000},{0.631250,0.706250,0.025000,0.025000},{0.631250,0.706250,0.050000,0.050000},{0.643750,0.706250,0.025000,0.025000},{0.643750,0.706250,0.050000,0.050000},{0.656250,0.706250,0.025000,0.025000},{0.656250,0.706250,0.050000,0.050000},{0.668750,0.706250,0.025000,0.025000},{0.668750,0.706250,0.050000,0.050000},{0.681250,0.706250,0.025000,0.025000},{0.681250,0.706250,0.050000,0.050000},{0.693750,0.706250,0.025000,0.025000},{0.693750,0.706250,0.050000,0.050000},{0.706250,0.706250,0.025000,0.025000},{0.706250,0.706250,0.050000,0.050000},{0.718750,0.706250,0.025000,0.025000},{0.718750,0.706250,0.050000,0.050000},{0.731250,0.706250,0.025000,0.025000},{0.731250,0.706250,0.050000,0.050000},{0.743750,0.706250,0.025000,0.025000},{0.743750,0.706250,0.050000,0.050000},{0.756250,0.706250,0.025000,0.025000},{0.756250,0.706250,0.050000,0.050000},{0.768750,0.706250,0.025000,0.025000},{0.768750,0.706250,0.050000,0.050000},{0.781250,0.706250,0.025000,0.025000},{0.781250,0.706250,0.050000,0.050000},{0.793750,0.706250,0.025000,0.025000},{0.793750,0.706250,0.050000,0.050000},{0.806250,0.706250,0.025000,0.025000},{0.806250,0.706250,0.050000,0.050000},{0.818750,0.706250,0.025000,0.025000},{0.818750,0.706250,0.050000,0.050000},{0.831250,0.706250,0.025000,0.025000},{0.831250,0.706250,0.050000,0.050000},{0.843750,0.706250,0.025000,0.025000},{0.843750,0.706250,0.050000,0.050000},{0.856250,0.706250,0.025000,0.025000},{0.856250,0.706250,0.050000,0.050000},{0.868750,0.706250,0.025000,0.025000},{0.868750,0.706250,0.050000,0.050000},{0.881250,0.706250,0.025000,0.025000},{0.881250,0.706250,0.050000,0.050000},{0.893750,0.706250,0.025000,0.025000},{0.893750,0.706250,0.050000,0.050000},{0.906250,0.706250,0.025000,0.025000},{0.906250,0.706250,0.050000,0.050000},{0.918750,0.706250,0.025000,0.025000},{0.918750,0.706250,0.050000,0.050000},{0.931250,0.706250,0.025000,0.025000},{0.931250,0.706250,0.050000,0.050000},{0.943750,0.706250,0.025000,0.025000},{0.943750,0.706250,0.050000,0.050000},{0.956250,0.706250,0.025000,0.025000},{0.956250,0.706250,0.050000,0.050000},{0.968750,0.706250,0.025000,0.025000},{0.968750,0.706250,0.050000,0.050000},{0.981250,0.706250,0.025000,0.025000},{0.981250,0.706250,0.050000,0.050000},{0.993750,0.706250,0.025000,0.025000},{0.993750,0.706250,0.050000,0.050000},{0.006250,0.718750,0.025000,0.025000},{0.006250,0.718750,0.050000,0.050000},{0.018750,0.718750,0.025000,0.025000},{0.018750,0.718750,0.050000,0.050000},{0.031250,0.718750,0.025000,0.025000},{0.031250,0.718750,0.050000,0.050000},{0.043750,0.718750,0.025000,0.025000},{0.043750,0.718750,0.050000,0.050000},{0.056250,0.718750,0.025000,0.025000},{0.056250,0.718750,0.050000,0.050000},{0.068750,0.718750,0.025000,0.025000},{0.068750,0.718750,0.050000,0.050000},{0.081250,0.718750,0.025000,0.025000},{0.081250,0.718750,0.050000,0.050000},{0.093750,0.718750,0.025000,0.025000},{0.093750,0.718750,0.050000,0.050000},{0.106250,0.718750,0.025000,0.025000},{0.106250,0.718750,0.050000,0.050000},{0.118750,0.718750,0.025000,0.025000},{0.118750,0.718750,0.050000,0.050000},{0.131250,0.718750,0.025000,0.025000},{0.131250,0.718750,0.050000,0.050000},{0.143750,0.718750,0.025000,0.025000},{0.143750,0.718750,0.050000,0.050000},{0.156250,0.718750,0.025000,0.025000},{0.156250,0.718750,0.050000,0.050000},{0.168750,0.718750,0.025000,0.025000},{0.168750,0.718750,0.050000,0.050000},{0.181250,0.718750,0.025000,0.025000},{0.181250,0.718750,0.050000,0.050000},{0.193750,0.718750,0.025000,0.025000},{0.193750,0.718750,0.050000,0.050000},{0.206250,0.718750,0.025000,0.025000},{0.206250,0.718750,0.050000,0.050000},{0.218750,0.718750,0.025000,0.025000},{0.218750,0.718750,0.050000,0.050000},{0.231250,0.718750,0.025000,0.025000},{0.231250,0.718750,0.050000,0.050000},{0.243750,0.718750,0.025000,0.025000},{0.243750,0.718750,0.050000,0.050000},{0.256250,0.718750,0.025000,0.025000},{0.256250,0.718750,0.050000,0.050000},{0.268750,0.718750,0.025000,0.025000},{0.268750,0.718750,0.050000,0.050000},{0.281250,0.718750,0.025000,0.025000},{0.281250,0.718750,0.050000,0.050000},{0.293750,0.718750,0.025000,0.025000},{0.293750,0.718750,0.050000,0.050000},{0.306250,0.718750,0.025000,0.025000},{0.306250,0.718750,0.050000,0.050000},{0.318750,0.718750,0.025000,0.025000},{0.318750,0.718750,0.050000,0.050000},{0.331250,0.718750,0.025000,0.025000},{0.331250,0.718750,0.050000,0.050000},{0.343750,0.718750,0.025000,0.025000},{0.343750,0.718750,0.050000,0.050000},{0.356250,0.718750,0.025000,0.025000},{0.356250,0.718750,0.050000,0.050000},{0.368750,0.718750,0.025000,0.025000},{0.368750,0.718750,0.050000,0.050000},{0.381250,0.718750,0.025000,0.025000},{0.381250,0.718750,0.050000,0.050000},{0.393750,0.718750,0.025000,0.025000},{0.393750,0.718750,0.050000,0.050000},{0.406250,0.718750,0.025000,0.025000},{0.406250,0.718750,0.050000,0.050000},{0.418750,0.718750,0.025000,0.025000},{0.418750,0.718750,0.050000,0.050000},{0.431250,0.718750,0.025000,0.025000},{0.431250,0.718750,0.050000,0.050000},{0.443750,0.718750,0.025000,0.025000},{0.443750,0.718750,0.050000,0.050000},{0.456250,0.718750,0.025000,0.025000},{0.456250,0.718750,0.050000,0.050000},{0.468750,0.718750,0.025000,0.025000},{0.468750,0.718750,0.050000,0.050000},{0.481250,0.718750,0.025000,0.025000},{0.481250,0.718750,0.050000,0.050000},{0.493750,0.718750,0.025000,0.025000},{0.493750,0.718750,0.050000,0.050000},{0.506250,0.718750,0.025000,0.025000},{0.506250,0.718750,0.050000,0.050000},{0.518750,0.718750,0.025000,0.025000},{0.518750,0.718750,0.050000,0.050000},{0.531250,0.718750,0.025000,0.025000},{0.531250,0.718750,0.050000,0.050000},{0.543750,0.718750,0.025000,0.025000},{0.543750,0.718750,0.050000,0.050000},{0.556250,0.718750,0.025000,0.025000},{0.556250,0.718750,0.050000,0.050000},{0.568750,0.718750,0.025000,0.025000},{0.568750,0.718750,0.050000,0.050000},{0.581250,0.718750,0.025000,0.025000},{0.581250,0.718750,0.050000,0.050000},{0.593750,0.718750,0.025000,0.025000},{0.593750,0.718750,0.050000,0.050000},{0.606250,0.718750,0.025000,0.025000},{0.606250,0.718750,0.050000,0.050000},{0.618750,0.718750,0.025000,0.025000},{0.618750,0.718750,0.050000,0.050000},{0.631250,0.718750,0.025000,0.025000},{0.631250,0.718750,0.050000,0.050000},{0.643750,0.718750,0.025000,0.025000},{0.643750,0.718750,0.050000,0.050000},{0.656250,0.718750,0.025000,0.025000},{0.656250,0.718750,0.050000,0.050000},{0.668750,0.718750,0.025000,0.025000},{0.668750,0.718750,0.050000,0.050000},{0.681250,0.718750,0.025000,0.025000},{0.681250,0.718750,0.050000,0.050000},{0.693750,0.718750,0.025000,0.025000},{0.693750,0.718750,0.050000,0.050000},{0.706250,0.718750,0.025000,0.025000},{0.706250,0.718750,0.050000,0.050000},{0.718750,0.718750,0.025000,0.025000},{0.718750,0.718750,0.050000,0.050000},{0.731250,0.718750,0.025000,0.025000},{0.731250,0.718750,0.050000,0.050000},{0.743750,0.718750,0.025000,0.025000},{0.743750,0.718750,0.050000,0.050000},{0.756250,0.718750,0.025000,0.025000},{0.756250,0.718750,0.050000,0.050000},{0.768750,0.718750,0.025000,0.025000},{0.768750,0.718750,0.050000,0.050000},{0.781250,0.718750,0.025000,0.025000},{0.781250,0.718750,0.050000,0.050000},{0.793750,0.718750,0.025000,0.025000},{0.793750,0.718750,0.050000,0.050000},{0.806250,0.718750,0.025000,0.025000},{0.806250,0.718750,0.050000,0.050000},{0.818750,0.718750,0.025000,0.025000},{0.818750,0.718750,0.050000,0.050000},{0.831250,0.718750,0.025000,0.025000},{0.831250,0.718750,0.050000,0.050000},{0.843750,0.718750,0.025000,0.025000},{0.843750,0.718750,0.050000,0.050000},{0.856250,0.718750,0.025000,0.025000},{0.856250,0.718750,0.050000,0.050000},{0.868750,0.718750,0.025000,0.025000},{0.868750,0.718750,0.050000,0.050000},{0.881250,0.718750,0.025000,0.025000},{0.881250,0.718750,0.050000,0.050000},{0.893750,0.718750,0.025000,0.025000},{0.893750,0.718750,0.050000,0.050000},{0.906250,0.718750,0.025000,0.025000},{0.906250,0.718750,0.050000,0.050000},{0.918750,0.718750,0.025000,0.025000},{0.918750,0.718750,0.050000,0.050000},{0.931250,0.718750,0.025000,0.025000},{0.931250,0.718750,0.050000,0.050000},{0.943750,0.718750,0.025000,0.025000},{0.943750,0.718750,0.050000,0.050000},{0.956250,0.718750,0.025000,0.025000},{0.956250,0.718750,0.050000,0.050000},{0.968750,0.718750,0.025000,0.025000},{0.968750,0.718750,0.050000,0.050000},{0.981250,0.718750,0.025000,0.025000},{0.981250,0.718750,0.050000,0.050000},{0.993750,0.718750,0.025000,0.025000},{0.993750,0.718750,0.050000,0.050000},{0.006250,0.731250,0.025000,0.025000},{0.006250,0.731250,0.050000,0.050000},{0.018750,0.731250,0.025000,0.025000},{0.018750,0.731250,0.050000,0.050000},{0.031250,0.731250,0.025000,0.025000},{0.031250,0.731250,0.050000,0.050000},{0.043750,0.731250,0.025000,0.025000},{0.043750,0.731250,0.050000,0.050000},{0.056250,0.731250,0.025000,0.025000},{0.056250,0.731250,0.050000,0.050000},{0.068750,0.731250,0.025000,0.025000},{0.068750,0.731250,0.050000,0.050000},{0.081250,0.731250,0.025000,0.025000},{0.081250,0.731250,0.050000,0.050000},{0.093750,0.731250,0.025000,0.025000},{0.093750,0.731250,0.050000,0.050000},{0.106250,0.731250,0.025000,0.025000},{0.106250,0.731250,0.050000,0.050000},{0.118750,0.731250,0.025000,0.025000},{0.118750,0.731250,0.050000,0.050000},{0.131250,0.731250,0.025000,0.025000},{0.131250,0.731250,0.050000,0.050000},{0.143750,0.731250,0.025000,0.025000},{0.143750,0.731250,0.050000,0.050000},{0.156250,0.731250,0.025000,0.025000},{0.156250,0.731250,0.050000,0.050000},{0.168750,0.731250,0.025000,0.025000},{0.168750,0.731250,0.050000,0.050000},{0.181250,0.731250,0.025000,0.025000},{0.181250,0.731250,0.050000,0.050000},{0.193750,0.731250,0.025000,0.025000},{0.193750,0.731250,0.050000,0.050000},{0.206250,0.731250,0.025000,0.025000},{0.206250,0.731250,0.050000,0.050000},{0.218750,0.731250,0.025000,0.025000},{0.218750,0.731250,0.050000,0.050000},{0.231250,0.731250,0.025000,0.025000},{0.231250,0.731250,0.050000,0.050000},{0.243750,0.731250,0.025000,0.025000},{0.243750,0.731250,0.050000,0.050000},{0.256250,0.731250,0.025000,0.025000},{0.256250,0.731250,0.050000,0.050000},{0.268750,0.731250,0.025000,0.025000},{0.268750,0.731250,0.050000,0.050000},{0.281250,0.731250,0.025000,0.025000},{0.281250,0.731250,0.050000,0.050000},{0.293750,0.731250,0.025000,0.025000},{0.293750,0.731250,0.050000,0.050000},{0.306250,0.731250,0.025000,0.025000},{0.306250,0.731250,0.050000,0.050000},{0.318750,0.731250,0.025000,0.025000},{0.318750,0.731250,0.050000,0.050000},{0.331250,0.731250,0.025000,0.025000},{0.331250,0.731250,0.050000,0.050000},{0.343750,0.731250,0.025000,0.025000},{0.343750,0.731250,0.050000,0.050000},{0.356250,0.731250,0.025000,0.025000},{0.356250,0.731250,0.050000,0.050000},{0.368750,0.731250,0.025000,0.025000},{0.368750,0.731250,0.050000,0.050000},{0.381250,0.731250,0.025000,0.025000},{0.381250,0.731250,0.050000,0.050000},{0.393750,0.731250,0.025000,0.025000},{0.393750,0.731250,0.050000,0.050000},{0.406250,0.731250,0.025000,0.025000},{0.406250,0.731250,0.050000,0.050000},{0.418750,0.731250,0.025000,0.025000},{0.418750,0.731250,0.050000,0.050000},{0.431250,0.731250,0.025000,0.025000},{0.431250,0.731250,0.050000,0.050000},{0.443750,0.731250,0.025000,0.025000},{0.443750,0.731250,0.050000,0.050000},{0.456250,0.731250,0.025000,0.025000},{0.456250,0.731250,0.050000,0.050000},{0.468750,0.731250,0.025000,0.025000},{0.468750,0.731250,0.050000,0.050000},{0.481250,0.731250,0.025000,0.025000},{0.481250,0.731250,0.050000,0.050000},{0.493750,0.731250,0.025000,0.025000},{0.493750,0.731250,0.050000,0.050000},{0.506250,0.731250,0.025000,0.025000},{0.506250,0.731250,0.050000,0.050000},{0.518750,0.731250,0.025000,0.025000},{0.518750,0.731250,0.050000,0.050000},{0.531250,0.731250,0.025000,0.025000},{0.531250,0.731250,0.050000,0.050000},{0.543750,0.731250,0.025000,0.025000},{0.543750,0.731250,0.050000,0.050000},{0.556250,0.731250,0.025000,0.025000},{0.556250,0.731250,0.050000,0.050000},{0.568750,0.731250,0.025000,0.025000},{0.568750,0.731250,0.050000,0.050000},{0.581250,0.731250,0.025000,0.025000},{0.581250,0.731250,0.050000,0.050000},{0.593750,0.731250,0.025000,0.025000},{0.593750,0.731250,0.050000,0.050000},{0.606250,0.731250,0.025000,0.025000},{0.606250,0.731250,0.050000,0.050000},{0.618750,0.731250,0.025000,0.025000},{0.618750,0.731250,0.050000,0.050000},{0.631250,0.731250,0.025000,0.025000},{0.631250,0.731250,0.050000,0.050000},{0.643750,0.731250,0.025000,0.025000},{0.643750,0.731250,0.050000,0.050000},{0.656250,0.731250,0.025000,0.025000},{0.656250,0.731250,0.050000,0.050000},{0.668750,0.731250,0.025000,0.025000},{0.668750,0.731250,0.050000,0.050000},{0.681250,0.731250,0.025000,0.025000},{0.681250,0.731250,0.050000,0.050000},{0.693750,0.731250,0.025000,0.025000},{0.693750,0.731250,0.050000,0.050000},{0.706250,0.731250,0.025000,0.025000},{0.706250,0.731250,0.050000,0.050000},{0.718750,0.731250,0.025000,0.025000},{0.718750,0.731250,0.050000,0.050000},{0.731250,0.731250,0.025000,0.025000},{0.731250,0.731250,0.050000,0.050000},{0.743750,0.731250,0.025000,0.025000},{0.743750,0.731250,0.050000,0.050000},{0.756250,0.731250,0.025000,0.025000},{0.756250,0.731250,0.050000,0.050000},{0.768750,0.731250,0.025000,0.025000},{0.768750,0.731250,0.050000,0.050000},{0.781250,0.731250,0.025000,0.025000},{0.781250,0.731250,0.050000,0.050000},{0.793750,0.731250,0.025000,0.025000},{0.793750,0.731250,0.050000,0.050000},{0.806250,0.731250,0.025000,0.025000},{0.806250,0.731250,0.050000,0.050000},{0.818750,0.731250,0.025000,0.025000},{0.818750,0.731250,0.050000,0.050000},{0.831250,0.731250,0.025000,0.025000},{0.831250,0.731250,0.050000,0.050000},{0.843750,0.731250,0.025000,0.025000},{0.843750,0.731250,0.050000,0.050000},{0.856250,0.731250,0.025000,0.025000},{0.856250,0.731250,0.050000,0.050000},{0.868750,0.731250,0.025000,0.025000},{0.868750,0.731250,0.050000,0.050000},{0.881250,0.731250,0.025000,0.025000},{0.881250,0.731250,0.050000,0.050000},{0.893750,0.731250,0.025000,0.025000},{0.893750,0.731250,0.050000,0.050000},{0.906250,0.731250,0.025000,0.025000},{0.906250,0.731250,0.050000,0.050000},{0.918750,0.731250,0.025000,0.025000},{0.918750,0.731250,0.050000,0.050000},{0.931250,0.731250,0.025000,0.025000},{0.931250,0.731250,0.050000,0.050000},{0.943750,0.731250,0.025000,0.025000},{0.943750,0.731250,0.050000,0.050000},{0.956250,0.731250,0.025000,0.025000},{0.956250,0.731250,0.050000,0.050000},{0.968750,0.731250,0.025000,0.025000},{0.968750,0.731250,0.050000,0.050000},{0.981250,0.731250,0.025000,0.025000},{0.981250,0.731250,0.050000,0.050000},{0.993750,0.731250,0.025000,0.025000},{0.993750,0.731250,0.050000,0.050000},{0.006250,0.743750,0.025000,0.025000},{0.006250,0.743750,0.050000,0.050000},{0.018750,0.743750,0.025000,0.025000},{0.018750,0.743750,0.050000,0.050000},{0.031250,0.743750,0.025000,0.025000},{0.031250,0.743750,0.050000,0.050000},{0.043750,0.743750,0.025000,0.025000},{0.043750,0.743750,0.050000,0.050000},{0.056250,0.743750,0.025000,0.025000},{0.056250,0.743750,0.050000,0.050000},{0.068750,0.743750,0.025000,0.025000},{0.068750,0.743750,0.050000,0.050000},{0.081250,0.743750,0.025000,0.025000},{0.081250,0.743750,0.050000,0.050000},{0.093750,0.743750,0.025000,0.025000},{0.093750,0.743750,0.050000,0.050000},{0.106250,0.743750,0.025000,0.025000},{0.106250,0.743750,0.050000,0.050000},{0.118750,0.743750,0.025000,0.025000},{0.118750,0.743750,0.050000,0.050000},{0.131250,0.743750,0.025000,0.025000},{0.131250,0.743750,0.050000,0.050000},{0.143750,0.743750,0.025000,0.025000},{0.143750,0.743750,0.050000,0.050000},{0.156250,0.743750,0.025000,0.025000},{0.156250,0.743750,0.050000,0.050000},{0.168750,0.743750,0.025000,0.025000},{0.168750,0.743750,0.050000,0.050000},{0.181250,0.743750,0.025000,0.025000},{0.181250,0.743750,0.050000,0.050000},{0.193750,0.743750,0.025000,0.025000},{0.193750,0.743750,0.050000,0.050000},{0.206250,0.743750,0.025000,0.025000},{0.206250,0.743750,0.050000,0.050000},{0.218750,0.743750,0.025000,0.025000},{0.218750,0.743750,0.050000,0.050000},{0.231250,0.743750,0.025000,0.025000},{0.231250,0.743750,0.050000,0.050000},{0.243750,0.743750,0.025000,0.025000},{0.243750,0.743750,0.050000,0.050000},{0.256250,0.743750,0.025000,0.025000},{0.256250,0.743750,0.050000,0.050000},{0.268750,0.743750,0.025000,0.025000},{0.268750,0.743750,0.050000,0.050000},{0.281250,0.743750,0.025000,0.025000},{0.281250,0.743750,0.050000,0.050000},{0.293750,0.743750,0.025000,0.025000},{0.293750,0.743750,0.050000,0.050000},{0.306250,0.743750,0.025000,0.025000},{0.306250,0.743750,0.050000,0.050000},{0.318750,0.743750,0.025000,0.025000},{0.318750,0.743750,0.050000,0.050000},{0.331250,0.743750,0.025000,0.025000},{0.331250,0.743750,0.050000,0.050000},{0.343750,0.743750,0.025000,0.025000},{0.343750,0.743750,0.050000,0.050000},{0.356250,0.743750,0.025000,0.025000},{0.356250,0.743750,0.050000,0.050000},{0.368750,0.743750,0.025000,0.025000},{0.368750,0.743750,0.050000,0.050000},{0.381250,0.743750,0.025000,0.025000},{0.381250,0.743750,0.050000,0.050000},{0.393750,0.743750,0.025000,0.025000},{0.393750,0.743750,0.050000,0.050000},{0.406250,0.743750,0.025000,0.025000},{0.406250,0.743750,0.050000,0.050000},{0.418750,0.743750,0.025000,0.025000},{0.418750,0.743750,0.050000,0.050000},{0.431250,0.743750,0.025000,0.025000},{0.431250,0.743750,0.050000,0.050000},{0.443750,0.743750,0.025000,0.025000},{0.443750,0.743750,0.050000,0.050000},{0.456250,0.743750,0.025000,0.025000},{0.456250,0.743750,0.050000,0.050000},{0.468750,0.743750,0.025000,0.025000},{0.468750,0.743750,0.050000,0.050000},{0.481250,0.743750,0.025000,0.025000},{0.481250,0.743750,0.050000,0.050000},{0.493750,0.743750,0.025000,0.025000},{0.493750,0.743750,0.050000,0.050000},{0.506250,0.743750,0.025000,0.025000},{0.506250,0.743750,0.050000,0.050000},{0.518750,0.743750,0.025000,0.025000},{0.518750,0.743750,0.050000,0.050000},{0.531250,0.743750,0.025000,0.025000},{0.531250,0.743750,0.050000,0.050000},{0.543750,0.743750,0.025000,0.025000},{0.543750,0.743750,0.050000,0.050000},{0.556250,0.743750,0.025000,0.025000},{0.556250,0.743750,0.050000,0.050000},{0.568750,0.743750,0.025000,0.025000},{0.568750,0.743750,0.050000,0.050000},{0.581250,0.743750,0.025000,0.025000},{0.581250,0.743750,0.050000,0.050000},{0.593750,0.743750,0.025000,0.025000},{0.593750,0.743750,0.050000,0.050000},{0.606250,0.743750,0.025000,0.025000},{0.606250,0.743750,0.050000,0.050000},{0.618750,0.743750,0.025000,0.025000},{0.618750,0.743750,0.050000,0.050000},{0.631250,0.743750,0.025000,0.025000},{0.631250,0.743750,0.050000,0.050000},{0.643750,0.743750,0.025000,0.025000},{0.643750,0.743750,0.050000,0.050000},{0.656250,0.743750,0.025000,0.025000},{0.656250,0.743750,0.050000,0.050000},{0.668750,0.743750,0.025000,0.025000},{0.668750,0.743750,0.050000,0.050000},{0.681250,0.743750,0.025000,0.025000},{0.681250,0.743750,0.050000,0.050000},{0.693750,0.743750,0.025000,0.025000},{0.693750,0.743750,0.050000,0.050000},{0.706250,0.743750,0.025000,0.025000},{0.706250,0.743750,0.050000,0.050000},{0.718750,0.743750,0.025000,0.025000},{0.718750,0.743750,0.050000,0.050000},{0.731250,0.743750,0.025000,0.025000},{0.731250,0.743750,0.050000,0.050000},{0.743750,0.743750,0.025000,0.025000},{0.743750,0.743750,0.050000,0.050000},{0.756250,0.743750,0.025000,0.025000},{0.756250,0.743750,0.050000,0.050000},{0.768750,0.743750,0.025000,0.025000},{0.768750,0.743750,0.050000,0.050000},{0.781250,0.743750,0.025000,0.025000},{0.781250,0.743750,0.050000,0.050000},{0.793750,0.743750,0.025000,0.025000},{0.793750,0.743750,0.050000,0.050000},{0.806250,0.743750,0.025000,0.025000},{0.806250,0.743750,0.050000,0.050000},{0.818750,0.743750,0.025000,0.025000},{0.818750,0.743750,0.050000,0.050000},{0.831250,0.743750,0.025000,0.025000},{0.831250,0.743750,0.050000,0.050000},{0.843750,0.743750,0.025000,0.025000},{0.843750,0.743750,0.050000,0.050000},{0.856250,0.743750,0.025000,0.025000},{0.856250,0.743750,0.050000,0.050000},{0.868750,0.743750,0.025000,0.025000},{0.868750,0.743750,0.050000,0.050000},{0.881250,0.743750,0.025000,0.025000},{0.881250,0.743750,0.050000,0.050000},{0.893750,0.743750,0.025000,0.025000},{0.893750,0.743750,0.050000,0.050000},{0.906250,0.743750,0.025000,0.025000},{0.906250,0.743750,0.050000,0.050000},{0.918750,0.743750,0.025000,0.025000},{0.918750,0.743750,0.050000,0.050000},{0.931250,0.743750,0.025000,0.025000},{0.931250,0.743750,0.050000,0.050000},{0.943750,0.743750,0.025000,0.025000},{0.943750,0.743750,0.050000,0.050000},{0.956250,0.743750,0.025000,0.025000},{0.956250,0.743750,0.050000,0.050000},{0.968750,0.743750,0.025000,0.025000},{0.968750,0.743750,0.050000,0.050000},{0.981250,0.743750,0.025000,0.025000},{0.981250,0.743750,0.050000,0.050000},{0.993750,0.743750,0.025000,0.025000},{0.993750,0.743750,0.050000,0.050000},{0.006250,0.756250,0.025000,0.025000},{0.006250,0.756250,0.050000,0.050000},{0.018750,0.756250,0.025000,0.025000},{0.018750,0.756250,0.050000,0.050000},{0.031250,0.756250,0.025000,0.025000},{0.031250,0.756250,0.050000,0.050000},{0.043750,0.756250,0.025000,0.025000},{0.043750,0.756250,0.050000,0.050000},{0.056250,0.756250,0.025000,0.025000},{0.056250,0.756250,0.050000,0.050000},{0.068750,0.756250,0.025000,0.025000},{0.068750,0.756250,0.050000,0.050000},{0.081250,0.756250,0.025000,0.025000},{0.081250,0.756250,0.050000,0.050000},{0.093750,0.756250,0.025000,0.025000},{0.093750,0.756250,0.050000,0.050000},{0.106250,0.756250,0.025000,0.025000},{0.106250,0.756250,0.050000,0.050000},{0.118750,0.756250,0.025000,0.025000},{0.118750,0.756250,0.050000,0.050000},{0.131250,0.756250,0.025000,0.025000},{0.131250,0.756250,0.050000,0.050000},{0.143750,0.756250,0.025000,0.025000},{0.143750,0.756250,0.050000,0.050000},{0.156250,0.756250,0.025000,0.025000},{0.156250,0.756250,0.050000,0.050000},{0.168750,0.756250,0.025000,0.025000},{0.168750,0.756250,0.050000,0.050000},{0.181250,0.756250,0.025000,0.025000},{0.181250,0.756250,0.050000,0.050000},{0.193750,0.756250,0.025000,0.025000},{0.193750,0.756250,0.050000,0.050000},{0.206250,0.756250,0.025000,0.025000},{0.206250,0.756250,0.050000,0.050000},{0.218750,0.756250,0.025000,0.025000},{0.218750,0.756250,0.050000,0.050000},{0.231250,0.756250,0.025000,0.025000},{0.231250,0.756250,0.050000,0.050000},{0.243750,0.756250,0.025000,0.025000},{0.243750,0.756250,0.050000,0.050000},{0.256250,0.756250,0.025000,0.025000},{0.256250,0.756250,0.050000,0.050000},{0.268750,0.756250,0.025000,0.025000},{0.268750,0.756250,0.050000,0.050000},{0.281250,0.756250,0.025000,0.025000},{0.281250,0.756250,0.050000,0.050000},{0.293750,0.756250,0.025000,0.025000},{0.293750,0.756250,0.050000,0.050000},{0.306250,0.756250,0.025000,0.025000},{0.306250,0.756250,0.050000,0.050000},{0.318750,0.756250,0.025000,0.025000},{0.318750,0.756250,0.050000,0.050000},{0.331250,0.756250,0.025000,0.025000},{0.331250,0.756250,0.050000,0.050000},{0.343750,0.756250,0.025000,0.025000},{0.343750,0.756250,0.050000,0.050000},{0.356250,0.756250,0.025000,0.025000},{0.356250,0.756250,0.050000,0.050000},{0.368750,0.756250,0.025000,0.025000},{0.368750,0.756250,0.050000,0.050000},{0.381250,0.756250,0.025000,0.025000},{0.381250,0.756250,0.050000,0.050000},{0.393750,0.756250,0.025000,0.025000},{0.393750,0.756250,0.050000,0.050000},{0.406250,0.756250,0.025000,0.025000},{0.406250,0.756250,0.050000,0.050000},{0.418750,0.756250,0.025000,0.025000},{0.418750,0.756250,0.050000,0.050000},{0.431250,0.756250,0.025000,0.025000},{0.431250,0.756250,0.050000,0.050000},{0.443750,0.756250,0.025000,0.025000},{0.443750,0.756250,0.050000,0.050000},{0.456250,0.756250,0.025000,0.025000},{0.456250,0.756250,0.050000,0.050000},{0.468750,0.756250,0.025000,0.025000},{0.468750,0.756250,0.050000,0.050000},{0.481250,0.756250,0.025000,0.025000},{0.481250,0.756250,0.050000,0.050000},{0.493750,0.756250,0.025000,0.025000},{0.493750,0.756250,0.050000,0.050000},{0.506250,0.756250,0.025000,0.025000},{0.506250,0.756250,0.050000,0.050000},{0.518750,0.756250,0.025000,0.025000},{0.518750,0.756250,0.050000,0.050000},{0.531250,0.756250,0.025000,0.025000},{0.531250,0.756250,0.050000,0.050000},{0.543750,0.756250,0.025000,0.025000},{0.543750,0.756250,0.050000,0.050000},{0.556250,0.756250,0.025000,0.025000},{0.556250,0.756250,0.050000,0.050000},{0.568750,0.756250,0.025000,0.025000},{0.568750,0.756250,0.050000,0.050000},{0.581250,0.756250,0.025000,0.025000},{0.581250,0.756250,0.050000,0.050000},{0.593750,0.756250,0.025000,0.025000},{0.593750,0.756250,0.050000,0.050000},{0.606250,0.756250,0.025000,0.025000},{0.606250,0.756250,0.050000,0.050000},{0.618750,0.756250,0.025000,0.025000},{0.618750,0.756250,0.050000,0.050000},{0.631250,0.756250,0.025000,0.025000},{0.631250,0.756250,0.050000,0.050000},{0.643750,0.756250,0.025000,0.025000},{0.643750,0.756250,0.050000,0.050000},{0.656250,0.756250,0.025000,0.025000},{0.656250,0.756250,0.050000,0.050000},{0.668750,0.756250,0.025000,0.025000},{0.668750,0.756250,0.050000,0.050000},{0.681250,0.756250,0.025000,0.025000},{0.681250,0.756250,0.050000,0.050000},{0.693750,0.756250,0.025000,0.025000},{0.693750,0.756250,0.050000,0.050000},{0.706250,0.756250,0.025000,0.025000},{0.706250,0.756250,0.050000,0.050000},{0.718750,0.756250,0.025000,0.025000},{0.718750,0.756250,0.050000,0.050000},{0.731250,0.756250,0.025000,0.025000},{0.731250,0.756250,0.050000,0.050000},{0.743750,0.756250,0.025000,0.025000},{0.743750,0.756250,0.050000,0.050000},{0.756250,0.756250,0.025000,0.025000},{0.756250,0.756250,0.050000,0.050000},{0.768750,0.756250,0.025000,0.025000},{0.768750,0.756250,0.050000,0.050000},{0.781250,0.756250,0.025000,0.025000},{0.781250,0.756250,0.050000,0.050000},{0.793750,0.756250,0.025000,0.025000},{0.793750,0.756250,0.050000,0.050000},{0.806250,0.756250,0.025000,0.025000},{0.806250,0.756250,0.050000,0.050000},{0.818750,0.756250,0.025000,0.025000},{0.818750,0.756250,0.050000,0.050000},{0.831250,0.756250,0.025000,0.025000},{0.831250,0.756250,0.050000,0.050000},{0.843750,0.756250,0.025000,0.025000},{0.843750,0.756250,0.050000,0.050000},{0.856250,0.756250,0.025000,0.025000},{0.856250,0.756250,0.050000,0.050000},{0.868750,0.756250,0.025000,0.025000},{0.868750,0.756250,0.050000,0.050000},{0.881250,0.756250,0.025000,0.025000},{0.881250,0.756250,0.050000,0.050000},{0.893750,0.756250,0.025000,0.025000},{0.893750,0.756250,0.050000,0.050000},{0.906250,0.756250,0.025000,0.025000},{0.906250,0.756250,0.050000,0.050000},{0.918750,0.756250,0.025000,0.025000},{0.918750,0.756250,0.050000,0.050000},{0.931250,0.756250,0.025000,0.025000},{0.931250,0.756250,0.050000,0.050000},{0.943750,0.756250,0.025000,0.025000},{0.943750,0.756250,0.050000,0.050000},{0.956250,0.756250,0.025000,0.025000},{0.956250,0.756250,0.050000,0.050000},{0.968750,0.756250,0.025000,0.025000},{0.968750,0.756250,0.050000,0.050000},{0.981250,0.756250,0.025000,0.025000},{0.981250,0.756250,0.050000,0.050000},{0.993750,0.756250,0.025000,0.025000},{0.993750,0.756250,0.050000,0.050000},{0.006250,0.768750,0.025000,0.025000},{0.006250,0.768750,0.050000,0.050000},{0.018750,0.768750,0.025000,0.025000},{0.018750,0.768750,0.050000,0.050000},{0.031250,0.768750,0.025000,0.025000},{0.031250,0.768750,0.050000,0.050000},{0.043750,0.768750,0.025000,0.025000},{0.043750,0.768750,0.050000,0.050000},{0.056250,0.768750,0.025000,0.025000},{0.056250,0.768750,0.050000,0.050000},{0.068750,0.768750,0.025000,0.025000},{0.068750,0.768750,0.050000,0.050000},{0.081250,0.768750,0.025000,0.025000},{0.081250,0.768750,0.050000,0.050000},{0.093750,0.768750,0.025000,0.025000},{0.093750,0.768750,0.050000,0.050000},{0.106250,0.768750,0.025000,0.025000},{0.106250,0.768750,0.050000,0.050000},{0.118750,0.768750,0.025000,0.025000},{0.118750,0.768750,0.050000,0.050000},{0.131250,0.768750,0.025000,0.025000},{0.131250,0.768750,0.050000,0.050000},{0.143750,0.768750,0.025000,0.025000},{0.143750,0.768750,0.050000,0.050000},{0.156250,0.768750,0.025000,0.025000},{0.156250,0.768750,0.050000,0.050000},{0.168750,0.768750,0.025000,0.025000},{0.168750,0.768750,0.050000,0.050000},{0.181250,0.768750,0.025000,0.025000},{0.181250,0.768750,0.050000,0.050000},{0.193750,0.768750,0.025000,0.025000},{0.193750,0.768750,0.050000,0.050000},{0.206250,0.768750,0.025000,0.025000},{0.206250,0.768750,0.050000,0.050000},{0.218750,0.768750,0.025000,0.025000},{0.218750,0.768750,0.050000,0.050000},{0.231250,0.768750,0.025000,0.025000},{0.231250,0.768750,0.050000,0.050000},{0.243750,0.768750,0.025000,0.025000},{0.243750,0.768750,0.050000,0.050000},{0.256250,0.768750,0.025000,0.025000},{0.256250,0.768750,0.050000,0.050000},{0.268750,0.768750,0.025000,0.025000},{0.268750,0.768750,0.050000,0.050000},{0.281250,0.768750,0.025000,0.025000},{0.281250,0.768750,0.050000,0.050000},{0.293750,0.768750,0.025000,0.025000},{0.293750,0.768750,0.050000,0.050000},{0.306250,0.768750,0.025000,0.025000},{0.306250,0.768750,0.050000,0.050000},{0.318750,0.768750,0.025000,0.025000},{0.318750,0.768750,0.050000,0.050000},{0.331250,0.768750,0.025000,0.025000},{0.331250,0.768750,0.050000,0.050000},{0.343750,0.768750,0.025000,0.025000},{0.343750,0.768750,0.050000,0.050000},{0.356250,0.768750,0.025000,0.025000},{0.356250,0.768750,0.050000,0.050000},{0.368750,0.768750,0.025000,0.025000},{0.368750,0.768750,0.050000,0.050000},{0.381250,0.768750,0.025000,0.025000},{0.381250,0.768750,0.050000,0.050000},{0.393750,0.768750,0.025000,0.025000},{0.393750,0.768750,0.050000,0.050000},{0.406250,0.768750,0.025000,0.025000},{0.406250,0.768750,0.050000,0.050000},{0.418750,0.768750,0.025000,0.025000},{0.418750,0.768750,0.050000,0.050000},{0.431250,0.768750,0.025000,0.025000},{0.431250,0.768750,0.050000,0.050000},{0.443750,0.768750,0.025000,0.025000},{0.443750,0.768750,0.050000,0.050000},{0.456250,0.768750,0.025000,0.025000},{0.456250,0.768750,0.050000,0.050000},{0.468750,0.768750,0.025000,0.025000},{0.468750,0.768750,0.050000,0.050000},{0.481250,0.768750,0.025000,0.025000},{0.481250,0.768750,0.050000,0.050000},{0.493750,0.768750,0.025000,0.025000},{0.493750,0.768750,0.050000,0.050000},{0.506250,0.768750,0.025000,0.025000},{0.506250,0.768750,0.050000,0.050000},{0.518750,0.768750,0.025000,0.025000},{0.518750,0.768750,0.050000,0.050000},{0.531250,0.768750,0.025000,0.025000},{0.531250,0.768750,0.050000,0.050000},{0.543750,0.768750,0.025000,0.025000},{0.543750,0.768750,0.050000,0.050000},{0.556250,0.768750,0.025000,0.025000},{0.556250,0.768750,0.050000,0.050000},{0.568750,0.768750,0.025000,0.025000},{0.568750,0.768750,0.050000,0.050000},{0.581250,0.768750,0.025000,0.025000},{0.581250,0.768750,0.050000,0.050000},{0.593750,0.768750,0.025000,0.025000},{0.593750,0.768750,0.050000,0.050000},{0.606250,0.768750,0.025000,0.025000},{0.606250,0.768750,0.050000,0.050000},{0.618750,0.768750,0.025000,0.025000},{0.618750,0.768750,0.050000,0.050000},{0.631250,0.768750,0.025000,0.025000},{0.631250,0.768750,0.050000,0.050000},{0.643750,0.768750,0.025000,0.025000},{0.643750,0.768750,0.050000,0.050000},{0.656250,0.768750,0.025000,0.025000},{0.656250,0.768750,0.050000,0.050000},{0.668750,0.768750,0.025000,0.025000},{0.668750,0.768750,0.050000,0.050000},{0.681250,0.768750,0.025000,0.025000},{0.681250,0.768750,0.050000,0.050000},{0.693750,0.768750,0.025000,0.025000},{0.693750,0.768750,0.050000,0.050000},{0.706250,0.768750,0.025000,0.025000},{0.706250,0.768750,0.050000,0.050000},{0.718750,0.768750,0.025000,0.025000},{0.718750,0.768750,0.050000,0.050000},{0.731250,0.768750,0.025000,0.025000},{0.731250,0.768750,0.050000,0.050000},{0.743750,0.768750,0.025000,0.025000},{0.743750,0.768750,0.050000,0.050000},{0.756250,0.768750,0.025000,0.025000},{0.756250,0.768750,0.050000,0.050000},{0.768750,0.768750,0.025000,0.025000},{0.768750,0.768750,0.050000,0.050000},{0.781250,0.768750,0.025000,0.025000},{0.781250,0.768750,0.050000,0.050000},{0.793750,0.768750,0.025000,0.025000},{0.793750,0.768750,0.050000,0.050000},{0.806250,0.768750,0.025000,0.025000},{0.806250,0.768750,0.050000,0.050000},{0.818750,0.768750,0.025000,0.025000},{0.818750,0.768750,0.050000,0.050000},{0.831250,0.768750,0.025000,0.025000},{0.831250,0.768750,0.050000,0.050000},{0.843750,0.768750,0.025000,0.025000},{0.843750,0.768750,0.050000,0.050000},{0.856250,0.768750,0.025000,0.025000},{0.856250,0.768750,0.050000,0.050000},{0.868750,0.768750,0.025000,0.025000},{0.868750,0.768750,0.050000,0.050000},{0.881250,0.768750,0.025000,0.025000},{0.881250,0.768750,0.050000,0.050000},{0.893750,0.768750,0.025000,0.025000},{0.893750,0.768750,0.050000,0.050000},{0.906250,0.768750,0.025000,0.025000},{0.906250,0.768750,0.050000,0.050000},{0.918750,0.768750,0.025000,0.025000},{0.918750,0.768750,0.050000,0.050000},{0.931250,0.768750,0.025000,0.025000},{0.931250,0.768750,0.050000,0.050000},{0.943750,0.768750,0.025000,0.025000},{0.943750,0.768750,0.050000,0.050000},{0.956250,0.768750,0.025000,0.025000},{0.956250,0.768750,0.050000,0.050000},{0.968750,0.768750,0.025000,0.025000},{0.968750,0.768750,0.050000,0.050000},{0.981250,0.768750,0.025000,0.025000},{0.981250,0.768750,0.050000,0.050000},{0.993750,0.768750,0.025000,0.025000},{0.993750,0.768750,0.050000,0.050000},{0.006250,0.781250,0.025000,0.025000},{0.006250,0.781250,0.050000,0.050000},{0.018750,0.781250,0.025000,0.025000},{0.018750,0.781250,0.050000,0.050000},{0.031250,0.781250,0.025000,0.025000},{0.031250,0.781250,0.050000,0.050000},{0.043750,0.781250,0.025000,0.025000},{0.043750,0.781250,0.050000,0.050000},{0.056250,0.781250,0.025000,0.025000},{0.056250,0.781250,0.050000,0.050000},{0.068750,0.781250,0.025000,0.025000},{0.068750,0.781250,0.050000,0.050000},{0.081250,0.781250,0.025000,0.025000},{0.081250,0.781250,0.050000,0.050000},{0.093750,0.781250,0.025000,0.025000},{0.093750,0.781250,0.050000,0.050000},{0.106250,0.781250,0.025000,0.025000},{0.106250,0.781250,0.050000,0.050000},{0.118750,0.781250,0.025000,0.025000},{0.118750,0.781250,0.050000,0.050000},{0.131250,0.781250,0.025000,0.025000},{0.131250,0.781250,0.050000,0.050000},{0.143750,0.781250,0.025000,0.025000},{0.143750,0.781250,0.050000,0.050000},{0.156250,0.781250,0.025000,0.025000},{0.156250,0.781250,0.050000,0.050000},{0.168750,0.781250,0.025000,0.025000},{0.168750,0.781250,0.050000,0.050000},{0.181250,0.781250,0.025000,0.025000},{0.181250,0.781250,0.050000,0.050000},{0.193750,0.781250,0.025000,0.025000},{0.193750,0.781250,0.050000,0.050000},{0.206250,0.781250,0.025000,0.025000},{0.206250,0.781250,0.050000,0.050000},{0.218750,0.781250,0.025000,0.025000},{0.218750,0.781250,0.050000,0.050000},{0.231250,0.781250,0.025000,0.025000},{0.231250,0.781250,0.050000,0.050000},{0.243750,0.781250,0.025000,0.025000},{0.243750,0.781250,0.050000,0.050000},{0.256250,0.781250,0.025000,0.025000},{0.256250,0.781250,0.050000,0.050000},{0.268750,0.781250,0.025000,0.025000},{0.268750,0.781250,0.050000,0.050000},{0.281250,0.781250,0.025000,0.025000},{0.281250,0.781250,0.050000,0.050000},{0.293750,0.781250,0.025000,0.025000},{0.293750,0.781250,0.050000,0.050000},{0.306250,0.781250,0.025000,0.025000},{0.306250,0.781250,0.050000,0.050000},{0.318750,0.781250,0.025000,0.025000},{0.318750,0.781250,0.050000,0.050000},{0.331250,0.781250,0.025000,0.025000},{0.331250,0.781250,0.050000,0.050000},{0.343750,0.781250,0.025000,0.025000},{0.343750,0.781250,0.050000,0.050000},{0.356250,0.781250,0.025000,0.025000},{0.356250,0.781250,0.050000,0.050000},{0.368750,0.781250,0.025000,0.025000},{0.368750,0.781250,0.050000,0.050000},{0.381250,0.781250,0.025000,0.025000},{0.381250,0.781250,0.050000,0.050000},{0.393750,0.781250,0.025000,0.025000},{0.393750,0.781250,0.050000,0.050000},{0.406250,0.781250,0.025000,0.025000},{0.406250,0.781250,0.050000,0.050000},{0.418750,0.781250,0.025000,0.025000},{0.418750,0.781250,0.050000,0.050000},{0.431250,0.781250,0.025000,0.025000},{0.431250,0.781250,0.050000,0.050000},{0.443750,0.781250,0.025000,0.025000},{0.443750,0.781250,0.050000,0.050000},{0.456250,0.781250,0.025000,0.025000},{0.456250,0.781250,0.050000,0.050000},{0.468750,0.781250,0.025000,0.025000},{0.468750,0.781250,0.050000,0.050000},{0.481250,0.781250,0.025000,0.025000},{0.481250,0.781250,0.050000,0.050000},{0.493750,0.781250,0.025000,0.025000},{0.493750,0.781250,0.050000,0.050000},{0.506250,0.781250,0.025000,0.025000},{0.506250,0.781250,0.050000,0.050000},{0.518750,0.781250,0.025000,0.025000},{0.518750,0.781250,0.050000,0.050000},{0.531250,0.781250,0.025000,0.025000},{0.531250,0.781250,0.050000,0.050000},{0.543750,0.781250,0.025000,0.025000},{0.543750,0.781250,0.050000,0.050000},{0.556250,0.781250,0.025000,0.025000},{0.556250,0.781250,0.050000,0.050000},{0.568750,0.781250,0.025000,0.025000},{0.568750,0.781250,0.050000,0.050000},{0.581250,0.781250,0.025000,0.025000},{0.581250,0.781250,0.050000,0.050000},{0.593750,0.781250,0.025000,0.025000},{0.593750,0.781250,0.050000,0.050000},{0.606250,0.781250,0.025000,0.025000},{0.606250,0.781250,0.050000,0.050000},{0.618750,0.781250,0.025000,0.025000},{0.618750,0.781250,0.050000,0.050000},{0.631250,0.781250,0.025000,0.025000},{0.631250,0.781250,0.050000,0.050000},{0.643750,0.781250,0.025000,0.025000},{0.643750,0.781250,0.050000,0.050000},{0.656250,0.781250,0.025000,0.025000},{0.656250,0.781250,0.050000,0.050000},{0.668750,0.781250,0.025000,0.025000},{0.668750,0.781250,0.050000,0.050000},{0.681250,0.781250,0.025000,0.025000},{0.681250,0.781250,0.050000,0.050000},{0.693750,0.781250,0.025000,0.025000},{0.693750,0.781250,0.050000,0.050000},{0.706250,0.781250,0.025000,0.025000},{0.706250,0.781250,0.050000,0.050000},{0.718750,0.781250,0.025000,0.025000},{0.718750,0.781250,0.050000,0.050000},{0.731250,0.781250,0.025000,0.025000},{0.731250,0.781250,0.050000,0.050000},{0.743750,0.781250,0.025000,0.025000},{0.743750,0.781250,0.050000,0.050000},{0.756250,0.781250,0.025000,0.025000},{0.756250,0.781250,0.050000,0.050000},{0.768750,0.781250,0.025000,0.025000},{0.768750,0.781250,0.050000,0.050000},{0.781250,0.781250,0.025000,0.025000},{0.781250,0.781250,0.050000,0.050000},{0.793750,0.781250,0.025000,0.025000},{0.793750,0.781250,0.050000,0.050000},{0.806250,0.781250,0.025000,0.025000},{0.806250,0.781250,0.050000,0.050000},{0.818750,0.781250,0.025000,0.025000},{0.818750,0.781250,0.050000,0.050000},{0.831250,0.781250,0.025000,0.025000},{0.831250,0.781250,0.050000,0.050000},{0.843750,0.781250,0.025000,0.025000},{0.843750,0.781250,0.050000,0.050000},{0.856250,0.781250,0.025000,0.025000},{0.856250,0.781250,0.050000,0.050000},{0.868750,0.781250,0.025000,0.025000},{0.868750,0.781250,0.050000,0.050000},{0.881250,0.781250,0.025000,0.025000},{0.881250,0.781250,0.050000,0.050000},{0.893750,0.781250,0.025000,0.025000},{0.893750,0.781250,0.050000,0.050000},{0.906250,0.781250,0.025000,0.025000},{0.906250,0.781250,0.050000,0.050000},{0.918750,0.781250,0.025000,0.025000},{0.918750,0.781250,0.050000,0.050000},{0.931250,0.781250,0.025000,0.025000},{0.931250,0.781250,0.050000,0.050000},{0.943750,0.781250,0.025000,0.025000},{0.943750,0.781250,0.050000,0.050000},{0.956250,0.781250,0.025000,0.025000},{0.956250,0.781250,0.050000,0.050000},{0.968750,0.781250,0.025000,0.025000},{0.968750,0.781250,0.050000,0.050000},{0.981250,0.781250,0.025000,0.025000},{0.981250,0.781250,0.050000,0.050000},{0.993750,0.781250,0.025000,0.025000},{0.993750,0.781250,0.050000,0.050000},{0.006250,0.793750,0.025000,0.025000},{0.006250,0.793750,0.050000,0.050000},{0.018750,0.793750,0.025000,0.025000},{0.018750,0.793750,0.050000,0.050000},{0.031250,0.793750,0.025000,0.025000},{0.031250,0.793750,0.050000,0.050000},{0.043750,0.793750,0.025000,0.025000},{0.043750,0.793750,0.050000,0.050000},{0.056250,0.793750,0.025000,0.025000},{0.056250,0.793750,0.050000,0.050000},{0.068750,0.793750,0.025000,0.025000},{0.068750,0.793750,0.050000,0.050000},{0.081250,0.793750,0.025000,0.025000},{0.081250,0.793750,0.050000,0.050000},{0.093750,0.793750,0.025000,0.025000},{0.093750,0.793750,0.050000,0.050000},{0.106250,0.793750,0.025000,0.025000},{0.106250,0.793750,0.050000,0.050000},{0.118750,0.793750,0.025000,0.025000},{0.118750,0.793750,0.050000,0.050000},{0.131250,0.793750,0.025000,0.025000},{0.131250,0.793750,0.050000,0.050000},{0.143750,0.793750,0.025000,0.025000},{0.143750,0.793750,0.050000,0.050000},{0.156250,0.793750,0.025000,0.025000},{0.156250,0.793750,0.050000,0.050000},{0.168750,0.793750,0.025000,0.025000},{0.168750,0.793750,0.050000,0.050000},{0.181250,0.793750,0.025000,0.025000},{0.181250,0.793750,0.050000,0.050000},{0.193750,0.793750,0.025000,0.025000},{0.193750,0.793750,0.050000,0.050000},{0.206250,0.793750,0.025000,0.025000},{0.206250,0.793750,0.050000,0.050000},{0.218750,0.793750,0.025000,0.025000},{0.218750,0.793750,0.050000,0.050000},{0.231250,0.793750,0.025000,0.025000},{0.231250,0.793750,0.050000,0.050000},{0.243750,0.793750,0.025000,0.025000},{0.243750,0.793750,0.050000,0.050000},{0.256250,0.793750,0.025000,0.025000},{0.256250,0.793750,0.050000,0.050000},{0.268750,0.793750,0.025000,0.025000},{0.268750,0.793750,0.050000,0.050000},{0.281250,0.793750,0.025000,0.025000},{0.281250,0.793750,0.050000,0.050000},{0.293750,0.793750,0.025000,0.025000},{0.293750,0.793750,0.050000,0.050000},{0.306250,0.793750,0.025000,0.025000},{0.306250,0.793750,0.050000,0.050000},{0.318750,0.793750,0.025000,0.025000},{0.318750,0.793750,0.050000,0.050000},{0.331250,0.793750,0.025000,0.025000},{0.331250,0.793750,0.050000,0.050000},{0.343750,0.793750,0.025000,0.025000},{0.343750,0.793750,0.050000,0.050000},{0.356250,0.793750,0.025000,0.025000},{0.356250,0.793750,0.050000,0.050000},{0.368750,0.793750,0.025000,0.025000},{0.368750,0.793750,0.050000,0.050000},{0.381250,0.793750,0.025000,0.025000},{0.381250,0.793750,0.050000,0.050000},{0.393750,0.793750,0.025000,0.025000},{0.393750,0.793750,0.050000,0.050000},{0.406250,0.793750,0.025000,0.025000},{0.406250,0.793750,0.050000,0.050000},{0.418750,0.793750,0.025000,0.025000},{0.418750,0.793750,0.050000,0.050000},{0.431250,0.793750,0.025000,0.025000},{0.431250,0.793750,0.050000,0.050000},{0.443750,0.793750,0.025000,0.025000},{0.443750,0.793750,0.050000,0.050000},{0.456250,0.793750,0.025000,0.025000},{0.456250,0.793750,0.050000,0.050000},{0.468750,0.793750,0.025000,0.025000},{0.468750,0.793750,0.050000,0.050000},{0.481250,0.793750,0.025000,0.025000},{0.481250,0.793750,0.050000,0.050000},{0.493750,0.793750,0.025000,0.025000},{0.493750,0.793750,0.050000,0.050000},{0.506250,0.793750,0.025000,0.025000},{0.506250,0.793750,0.050000,0.050000},{0.518750,0.793750,0.025000,0.025000},{0.518750,0.793750,0.050000,0.050000},{0.531250,0.793750,0.025000,0.025000},{0.531250,0.793750,0.050000,0.050000},{0.543750,0.793750,0.025000,0.025000},{0.543750,0.793750,0.050000,0.050000},{0.556250,0.793750,0.025000,0.025000},{0.556250,0.793750,0.050000,0.050000},{0.568750,0.793750,0.025000,0.025000},{0.568750,0.793750,0.050000,0.050000},{0.581250,0.793750,0.025000,0.025000},{0.581250,0.793750,0.050000,0.050000},{0.593750,0.793750,0.025000,0.025000},{0.593750,0.793750,0.050000,0.050000},{0.606250,0.793750,0.025000,0.025000},{0.606250,0.793750,0.050000,0.050000},{0.618750,0.793750,0.025000,0.025000},{0.618750,0.793750,0.050000,0.050000},{0.631250,0.793750,0.025000,0.025000},{0.631250,0.793750,0.050000,0.050000},{0.643750,0.793750,0.025000,0.025000},{0.643750,0.793750,0.050000,0.050000},{0.656250,0.793750,0.025000,0.025000},{0.656250,0.793750,0.050000,0.050000},{0.668750,0.793750,0.025000,0.025000},{0.668750,0.793750,0.050000,0.050000},{0.681250,0.793750,0.025000,0.025000},{0.681250,0.793750,0.050000,0.050000},{0.693750,0.793750,0.025000,0.025000},{0.693750,0.793750,0.050000,0.050000},{0.706250,0.793750,0.025000,0.025000},{0.706250,0.793750,0.050000,0.050000},{0.718750,0.793750,0.025000,0.025000},{0.718750,0.793750,0.050000,0.050000},{0.731250,0.793750,0.025000,0.025000},{0.731250,0.793750,0.050000,0.050000},{0.743750,0.793750,0.025000,0.025000},{0.743750,0.793750,0.050000,0.050000},{0.756250,0.793750,0.025000,0.025000},{0.756250,0.793750,0.050000,0.050000},{0.768750,0.793750,0.025000,0.025000},{0.768750,0.793750,0.050000,0.050000},{0.781250,0.793750,0.025000,0.025000},{0.781250,0.793750,0.050000,0.050000},{0.793750,0.793750,0.025000,0.025000},{0.793750,0.793750,0.050000,0.050000},{0.806250,0.793750,0.025000,0.025000},{0.806250,0.793750,0.050000,0.050000},{0.818750,0.793750,0.025000,0.025000},{0.818750,0.793750,0.050000,0.050000},{0.831250,0.793750,0.025000,0.025000},{0.831250,0.793750,0.050000,0.050000},{0.843750,0.793750,0.025000,0.025000},{0.843750,0.793750,0.050000,0.050000},{0.856250,0.793750,0.025000,0.025000},{0.856250,0.793750,0.050000,0.050000},{0.868750,0.793750,0.025000,0.025000},{0.868750,0.793750,0.050000,0.050000},{0.881250,0.793750,0.025000,0.025000},{0.881250,0.793750,0.050000,0.050000},{0.893750,0.793750,0.025000,0.025000},{0.893750,0.793750,0.050000,0.050000},{0.906250,0.793750,0.025000,0.025000},{0.906250,0.793750,0.050000,0.050000},{0.918750,0.793750,0.025000,0.025000},{0.918750,0.793750,0.050000,0.050000},{0.931250,0.793750,0.025000,0.025000},{0.931250,0.793750,0.050000,0.050000},{0.943750,0.793750,0.025000,0.025000},{0.943750,0.793750,0.050000,0.050000},{0.956250,0.793750,0.025000,0.025000},{0.956250,0.793750,0.050000,0.050000},{0.968750,0.793750,0.025000,0.025000},{0.968750,0.793750,0.050000,0.050000},{0.981250,0.793750,0.025000,0.025000},{0.981250,0.793750,0.050000,0.050000},{0.993750,0.793750,0.025000,0.025000},{0.993750,0.793750,0.050000,0.050000},{0.006250,0.806250,0.025000,0.025000},{0.006250,0.806250,0.050000,0.050000},{0.018750,0.806250,0.025000,0.025000},{0.018750,0.806250,0.050000,0.050000},{0.031250,0.806250,0.025000,0.025000},{0.031250,0.806250,0.050000,0.050000},{0.043750,0.806250,0.025000,0.025000},{0.043750,0.806250,0.050000,0.050000},{0.056250,0.806250,0.025000,0.025000},{0.056250,0.806250,0.050000,0.050000},{0.068750,0.806250,0.025000,0.025000},{0.068750,0.806250,0.050000,0.050000},{0.081250,0.806250,0.025000,0.025000},{0.081250,0.806250,0.050000,0.050000},{0.093750,0.806250,0.025000,0.025000},{0.093750,0.806250,0.050000,0.050000},{0.106250,0.806250,0.025000,0.025000},{0.106250,0.806250,0.050000,0.050000},{0.118750,0.806250,0.025000,0.025000},{0.118750,0.806250,0.050000,0.050000},{0.131250,0.806250,0.025000,0.025000},{0.131250,0.806250,0.050000,0.050000},{0.143750,0.806250,0.025000,0.025000},{0.143750,0.806250,0.050000,0.050000},{0.156250,0.806250,0.025000,0.025000},{0.156250,0.806250,0.050000,0.050000},{0.168750,0.806250,0.025000,0.025000},{0.168750,0.806250,0.050000,0.050000},{0.181250,0.806250,0.025000,0.025000},{0.181250,0.806250,0.050000,0.050000},{0.193750,0.806250,0.025000,0.025000},{0.193750,0.806250,0.050000,0.050000},{0.206250,0.806250,0.025000,0.025000},{0.206250,0.806250,0.050000,0.050000},{0.218750,0.806250,0.025000,0.025000},{0.218750,0.806250,0.050000,0.050000},{0.231250,0.806250,0.025000,0.025000},{0.231250,0.806250,0.050000,0.050000},{0.243750,0.806250,0.025000,0.025000},{0.243750,0.806250,0.050000,0.050000},{0.256250,0.806250,0.025000,0.025000},{0.256250,0.806250,0.050000,0.050000},{0.268750,0.806250,0.025000,0.025000},{0.268750,0.806250,0.050000,0.050000},{0.281250,0.806250,0.025000,0.025000},{0.281250,0.806250,0.050000,0.050000},{0.293750,0.806250,0.025000,0.025000},{0.293750,0.806250,0.050000,0.050000},{0.306250,0.806250,0.025000,0.025000},{0.306250,0.806250,0.050000,0.050000},{0.318750,0.806250,0.025000,0.025000},{0.318750,0.806250,0.050000,0.050000},{0.331250,0.806250,0.025000,0.025000},{0.331250,0.806250,0.050000,0.050000},{0.343750,0.806250,0.025000,0.025000},{0.343750,0.806250,0.050000,0.050000},{0.356250,0.806250,0.025000,0.025000},{0.356250,0.806250,0.050000,0.050000},{0.368750,0.806250,0.025000,0.025000},{0.368750,0.806250,0.050000,0.050000},{0.381250,0.806250,0.025000,0.025000},{0.381250,0.806250,0.050000,0.050000},{0.393750,0.806250,0.025000,0.025000},{0.393750,0.806250,0.050000,0.050000},{0.406250,0.806250,0.025000,0.025000},{0.406250,0.806250,0.050000,0.050000},{0.418750,0.806250,0.025000,0.025000},{0.418750,0.806250,0.050000,0.050000},{0.431250,0.806250,0.025000,0.025000},{0.431250,0.806250,0.050000,0.050000},{0.443750,0.806250,0.025000,0.025000},{0.443750,0.806250,0.050000,0.050000},{0.456250,0.806250,0.025000,0.025000},{0.456250,0.806250,0.050000,0.050000},{0.468750,0.806250,0.025000,0.025000},{0.468750,0.806250,0.050000,0.050000},{0.481250,0.806250,0.025000,0.025000},{0.481250,0.806250,0.050000,0.050000},{0.493750,0.806250,0.025000,0.025000},{0.493750,0.806250,0.050000,0.050000},{0.506250,0.806250,0.025000,0.025000},{0.506250,0.806250,0.050000,0.050000},{0.518750,0.806250,0.025000,0.025000},{0.518750,0.806250,0.050000,0.050000},{0.531250,0.806250,0.025000,0.025000},{0.531250,0.806250,0.050000,0.050000},{0.543750,0.806250,0.025000,0.025000},{0.543750,0.806250,0.050000,0.050000},{0.556250,0.806250,0.025000,0.025000},{0.556250,0.806250,0.050000,0.050000},{0.568750,0.806250,0.025000,0.025000},{0.568750,0.806250,0.050000,0.050000},{0.581250,0.806250,0.025000,0.025000},{0.581250,0.806250,0.050000,0.050000},{0.593750,0.806250,0.025000,0.025000},{0.593750,0.806250,0.050000,0.050000},{0.606250,0.806250,0.025000,0.025000},{0.606250,0.806250,0.050000,0.050000},{0.618750,0.806250,0.025000,0.025000},{0.618750,0.806250,0.050000,0.050000},{0.631250,0.806250,0.025000,0.025000},{0.631250,0.806250,0.050000,0.050000},{0.643750,0.806250,0.025000,0.025000},{0.643750,0.806250,0.050000,0.050000},{0.656250,0.806250,0.025000,0.025000},{0.656250,0.806250,0.050000,0.050000},{0.668750,0.806250,0.025000,0.025000},{0.668750,0.806250,0.050000,0.050000},{0.681250,0.806250,0.025000,0.025000},{0.681250,0.806250,0.050000,0.050000},{0.693750,0.806250,0.025000,0.025000},{0.693750,0.806250,0.050000,0.050000},{0.706250,0.806250,0.025000,0.025000},{0.706250,0.806250,0.050000,0.050000},{0.718750,0.806250,0.025000,0.025000},{0.718750,0.806250,0.050000,0.050000},{0.731250,0.806250,0.025000,0.025000},{0.731250,0.806250,0.050000,0.050000},{0.743750,0.806250,0.025000,0.025000},{0.743750,0.806250,0.050000,0.050000},{0.756250,0.806250,0.025000,0.025000},{0.756250,0.806250,0.050000,0.050000},{0.768750,0.806250,0.025000,0.025000},{0.768750,0.806250,0.050000,0.050000},{0.781250,0.806250,0.025000,0.025000},{0.781250,0.806250,0.050000,0.050000},{0.793750,0.806250,0.025000,0.025000},{0.793750,0.806250,0.050000,0.050000},{0.806250,0.806250,0.025000,0.025000},{0.806250,0.806250,0.050000,0.050000},{0.818750,0.806250,0.025000,0.025000},{0.818750,0.806250,0.050000,0.050000},{0.831250,0.806250,0.025000,0.025000},{0.831250,0.806250,0.050000,0.050000},{0.843750,0.806250,0.025000,0.025000},{0.843750,0.806250,0.050000,0.050000},{0.856250,0.806250,0.025000,0.025000},{0.856250,0.806250,0.050000,0.050000},{0.868750,0.806250,0.025000,0.025000},{0.868750,0.806250,0.050000,0.050000},{0.881250,0.806250,0.025000,0.025000},{0.881250,0.806250,0.050000,0.050000},{0.893750,0.806250,0.025000,0.025000},{0.893750,0.806250,0.050000,0.050000},{0.906250,0.806250,0.025000,0.025000},{0.906250,0.806250,0.050000,0.050000},{0.918750,0.806250,0.025000,0.025000},{0.918750,0.806250,0.050000,0.050000},{0.931250,0.806250,0.025000,0.025000},{0.931250,0.806250,0.050000,0.050000},{0.943750,0.806250,0.025000,0.025000},{0.943750,0.806250,0.050000,0.050000},{0.956250,0.806250,0.025000,0.025000},{0.956250,0.806250,0.050000,0.050000},{0.968750,0.806250,0.025000,0.025000},{0.968750,0.806250,0.050000,0.050000},{0.981250,0.806250,0.025000,0.025000},{0.981250,0.806250,0.050000,0.050000},{0.993750,0.806250,0.025000,0.025000},{0.993750,0.806250,0.050000,0.050000},{0.006250,0.818750,0.025000,0.025000},{0.006250,0.818750,0.050000,0.050000},{0.018750,0.818750,0.025000,0.025000},{0.018750,0.818750,0.050000,0.050000},{0.031250,0.818750,0.025000,0.025000},{0.031250,0.818750,0.050000,0.050000},{0.043750,0.818750,0.025000,0.025000},{0.043750,0.818750,0.050000,0.050000},{0.056250,0.818750,0.025000,0.025000},{0.056250,0.818750,0.050000,0.050000},{0.068750,0.818750,0.025000,0.025000},{0.068750,0.818750,0.050000,0.050000},{0.081250,0.818750,0.025000,0.025000},{0.081250,0.818750,0.050000,0.050000},{0.093750,0.818750,0.025000,0.025000},{0.093750,0.818750,0.050000,0.050000},{0.106250,0.818750,0.025000,0.025000},{0.106250,0.818750,0.050000,0.050000},{0.118750,0.818750,0.025000,0.025000},{0.118750,0.818750,0.050000,0.050000},{0.131250,0.818750,0.025000,0.025000},{0.131250,0.818750,0.050000,0.050000},{0.143750,0.818750,0.025000,0.025000},{0.143750,0.818750,0.050000,0.050000},{0.156250,0.818750,0.025000,0.025000},{0.156250,0.818750,0.050000,0.050000},{0.168750,0.818750,0.025000,0.025000},{0.168750,0.818750,0.050000,0.050000},{0.181250,0.818750,0.025000,0.025000},{0.181250,0.818750,0.050000,0.050000},{0.193750,0.818750,0.025000,0.025000},{0.193750,0.818750,0.050000,0.050000},{0.206250,0.818750,0.025000,0.025000},{0.206250,0.818750,0.050000,0.050000},{0.218750,0.818750,0.025000,0.025000},{0.218750,0.818750,0.050000,0.050000},{0.231250,0.818750,0.025000,0.025000},{0.231250,0.818750,0.050000,0.050000},{0.243750,0.818750,0.025000,0.025000},{0.243750,0.818750,0.050000,0.050000},{0.256250,0.818750,0.025000,0.025000},{0.256250,0.818750,0.050000,0.050000},{0.268750,0.818750,0.025000,0.025000},{0.268750,0.818750,0.050000,0.050000},{0.281250,0.818750,0.025000,0.025000},{0.281250,0.818750,0.050000,0.050000},{0.293750,0.818750,0.025000,0.025000},{0.293750,0.818750,0.050000,0.050000},{0.306250,0.818750,0.025000,0.025000},{0.306250,0.818750,0.050000,0.050000},{0.318750,0.818750,0.025000,0.025000},{0.318750,0.818750,0.050000,0.050000},{0.331250,0.818750,0.025000,0.025000},{0.331250,0.818750,0.050000,0.050000},{0.343750,0.818750,0.025000,0.025000},{0.343750,0.818750,0.050000,0.050000},{0.356250,0.818750,0.025000,0.025000},{0.356250,0.818750,0.050000,0.050000},{0.368750,0.818750,0.025000,0.025000},{0.368750,0.818750,0.050000,0.050000},{0.381250,0.818750,0.025000,0.025000},{0.381250,0.818750,0.050000,0.050000},{0.393750,0.818750,0.025000,0.025000},{0.393750,0.818750,0.050000,0.050000},{0.406250,0.818750,0.025000,0.025000},{0.406250,0.818750,0.050000,0.050000},{0.418750,0.818750,0.025000,0.025000},{0.418750,0.818750,0.050000,0.050000},{0.431250,0.818750,0.025000,0.025000},{0.431250,0.818750,0.050000,0.050000},{0.443750,0.818750,0.025000,0.025000},{0.443750,0.818750,0.050000,0.050000},{0.456250,0.818750,0.025000,0.025000},{0.456250,0.818750,0.050000,0.050000},{0.468750,0.818750,0.025000,0.025000},{0.468750,0.818750,0.050000,0.050000},{0.481250,0.818750,0.025000,0.025000},{0.481250,0.818750,0.050000,0.050000},{0.493750,0.818750,0.025000,0.025000},{0.493750,0.818750,0.050000,0.050000},{0.506250,0.818750,0.025000,0.025000},{0.506250,0.818750,0.050000,0.050000},{0.518750,0.818750,0.025000,0.025000},{0.518750,0.818750,0.050000,0.050000},{0.531250,0.818750,0.025000,0.025000},{0.531250,0.818750,0.050000,0.050000},{0.543750,0.818750,0.025000,0.025000},{0.543750,0.818750,0.050000,0.050000},{0.556250,0.818750,0.025000,0.025000},{0.556250,0.818750,0.050000,0.050000},{0.568750,0.818750,0.025000,0.025000},{0.568750,0.818750,0.050000,0.050000},{0.581250,0.818750,0.025000,0.025000},{0.581250,0.818750,0.050000,0.050000},{0.593750,0.818750,0.025000,0.025000},{0.593750,0.818750,0.050000,0.050000},{0.606250,0.818750,0.025000,0.025000},{0.606250,0.818750,0.050000,0.050000},{0.618750,0.818750,0.025000,0.025000},{0.618750,0.818750,0.050000,0.050000},{0.631250,0.818750,0.025000,0.025000},{0.631250,0.818750,0.050000,0.050000},{0.643750,0.818750,0.025000,0.025000},{0.643750,0.818750,0.050000,0.050000},{0.656250,0.818750,0.025000,0.025000},{0.656250,0.818750,0.050000,0.050000},{0.668750,0.818750,0.025000,0.025000},{0.668750,0.818750,0.050000,0.050000},{0.681250,0.818750,0.025000,0.025000},{0.681250,0.818750,0.050000,0.050000},{0.693750,0.818750,0.025000,0.025000},{0.693750,0.818750,0.050000,0.050000},{0.706250,0.818750,0.025000,0.025000},{0.706250,0.818750,0.050000,0.050000},{0.718750,0.818750,0.025000,0.025000},{0.718750,0.818750,0.050000,0.050000},{0.731250,0.818750,0.025000,0.025000},{0.731250,0.818750,0.050000,0.050000},{0.743750,0.818750,0.025000,0.025000},{0.743750,0.818750,0.050000,0.050000},{0.756250,0.818750,0.025000,0.025000},{0.756250,0.818750,0.050000,0.050000},{0.768750,0.818750,0.025000,0.025000},{0.768750,0.818750,0.050000,0.050000},{0.781250,0.818750,0.025000,0.025000},{0.781250,0.818750,0.050000,0.050000},{0.793750,0.818750,0.025000,0.025000},{0.793750,0.818750,0.050000,0.050000},{0.806250,0.818750,0.025000,0.025000},{0.806250,0.818750,0.050000,0.050000},{0.818750,0.818750,0.025000,0.025000},{0.818750,0.818750,0.050000,0.050000},{0.831250,0.818750,0.025000,0.025000},{0.831250,0.818750,0.050000,0.050000},{0.843750,0.818750,0.025000,0.025000},{0.843750,0.818750,0.050000,0.050000},{0.856250,0.818750,0.025000,0.025000},{0.856250,0.818750,0.050000,0.050000},{0.868750,0.818750,0.025000,0.025000},{0.868750,0.818750,0.050000,0.050000},{0.881250,0.818750,0.025000,0.025000},{0.881250,0.818750,0.050000,0.050000},{0.893750,0.818750,0.025000,0.025000},{0.893750,0.818750,0.050000,0.050000},{0.906250,0.818750,0.025000,0.025000},{0.906250,0.818750,0.050000,0.050000},{0.918750,0.818750,0.025000,0.025000},{0.918750,0.818750,0.050000,0.050000},{0.931250,0.818750,0.025000,0.025000},{0.931250,0.818750,0.050000,0.050000},{0.943750,0.818750,0.025000,0.025000},{0.943750,0.818750,0.050000,0.050000},{0.956250,0.818750,0.025000,0.025000},{0.956250,0.818750,0.050000,0.050000},{0.968750,0.818750,0.025000,0.025000},{0.968750,0.818750,0.050000,0.050000},{0.981250,0.818750,0.025000,0.025000},{0.981250,0.818750,0.050000,0.050000},{0.993750,0.818750,0.025000,0.025000},{0.993750,0.818750,0.050000,0.050000},{0.006250,0.831250,0.025000,0.025000},{0.006250,0.831250,0.050000,0.050000},{0.018750,0.831250,0.025000,0.025000},{0.018750,0.831250,0.050000,0.050000},{0.031250,0.831250,0.025000,0.025000},{0.031250,0.831250,0.050000,0.050000},{0.043750,0.831250,0.025000,0.025000},{0.043750,0.831250,0.050000,0.050000},{0.056250,0.831250,0.025000,0.025000},{0.056250,0.831250,0.050000,0.050000},{0.068750,0.831250,0.025000,0.025000},{0.068750,0.831250,0.050000,0.050000},{0.081250,0.831250,0.025000,0.025000},{0.081250,0.831250,0.050000,0.050000},{0.093750,0.831250,0.025000,0.025000},{0.093750,0.831250,0.050000,0.050000},{0.106250,0.831250,0.025000,0.025000},{0.106250,0.831250,0.050000,0.050000},{0.118750,0.831250,0.025000,0.025000},{0.118750,0.831250,0.050000,0.050000},{0.131250,0.831250,0.025000,0.025000},{0.131250,0.831250,0.050000,0.050000},{0.143750,0.831250,0.025000,0.025000},{0.143750,0.831250,0.050000,0.050000},{0.156250,0.831250,0.025000,0.025000},{0.156250,0.831250,0.050000,0.050000},{0.168750,0.831250,0.025000,0.025000},{0.168750,0.831250,0.050000,0.050000},{0.181250,0.831250,0.025000,0.025000},{0.181250,0.831250,0.050000,0.050000},{0.193750,0.831250,0.025000,0.025000},{0.193750,0.831250,0.050000,0.050000},{0.206250,0.831250,0.025000,0.025000},{0.206250,0.831250,0.050000,0.050000},{0.218750,0.831250,0.025000,0.025000},{0.218750,0.831250,0.050000,0.050000},{0.231250,0.831250,0.025000,0.025000},{0.231250,0.831250,0.050000,0.050000},{0.243750,0.831250,0.025000,0.025000},{0.243750,0.831250,0.050000,0.050000},{0.256250,0.831250,0.025000,0.025000},{0.256250,0.831250,0.050000,0.050000},{0.268750,0.831250,0.025000,0.025000},{0.268750,0.831250,0.050000,0.050000},{0.281250,0.831250,0.025000,0.025000},{0.281250,0.831250,0.050000,0.050000},{0.293750,0.831250,0.025000,0.025000},{0.293750,0.831250,0.050000,0.050000},{0.306250,0.831250,0.025000,0.025000},{0.306250,0.831250,0.050000,0.050000},{0.318750,0.831250,0.025000,0.025000},{0.318750,0.831250,0.050000,0.050000},{0.331250,0.831250,0.025000,0.025000},{0.331250,0.831250,0.050000,0.050000},{0.343750,0.831250,0.025000,0.025000},{0.343750,0.831250,0.050000,0.050000},{0.356250,0.831250,0.025000,0.025000},{0.356250,0.831250,0.050000,0.050000},{0.368750,0.831250,0.025000,0.025000},{0.368750,0.831250,0.050000,0.050000},{0.381250,0.831250,0.025000,0.025000},{0.381250,0.831250,0.050000,0.050000},{0.393750,0.831250,0.025000,0.025000},{0.393750,0.831250,0.050000,0.050000},{0.406250,0.831250,0.025000,0.025000},{0.406250,0.831250,0.050000,0.050000},{0.418750,0.831250,0.025000,0.025000},{0.418750,0.831250,0.050000,0.050000},{0.431250,0.831250,0.025000,0.025000},{0.431250,0.831250,0.050000,0.050000},{0.443750,0.831250,0.025000,0.025000},{0.443750,0.831250,0.050000,0.050000},{0.456250,0.831250,0.025000,0.025000},{0.456250,0.831250,0.050000,0.050000},{0.468750,0.831250,0.025000,0.025000},{0.468750,0.831250,0.050000,0.050000},{0.481250,0.831250,0.025000,0.025000},{0.481250,0.831250,0.050000,0.050000},{0.493750,0.831250,0.025000,0.025000},{0.493750,0.831250,0.050000,0.050000},{0.506250,0.831250,0.025000,0.025000},{0.506250,0.831250,0.050000,0.050000},{0.518750,0.831250,0.025000,0.025000},{0.518750,0.831250,0.050000,0.050000},{0.531250,0.831250,0.025000,0.025000},{0.531250,0.831250,0.050000,0.050000},{0.543750,0.831250,0.025000,0.025000},{0.543750,0.831250,0.050000,0.050000},{0.556250,0.831250,0.025000,0.025000},{0.556250,0.831250,0.050000,0.050000},{0.568750,0.831250,0.025000,0.025000},{0.568750,0.831250,0.050000,0.050000},{0.581250,0.831250,0.025000,0.025000},{0.581250,0.831250,0.050000,0.050000},{0.593750,0.831250,0.025000,0.025000},{0.593750,0.831250,0.050000,0.050000},{0.606250,0.831250,0.025000,0.025000},{0.606250,0.831250,0.050000,0.050000},{0.618750,0.831250,0.025000,0.025000},{0.618750,0.831250,0.050000,0.050000},{0.631250,0.831250,0.025000,0.025000},{0.631250,0.831250,0.050000,0.050000},{0.643750,0.831250,0.025000,0.025000},{0.643750,0.831250,0.050000,0.050000},{0.656250,0.831250,0.025000,0.025000},{0.656250,0.831250,0.050000,0.050000},{0.668750,0.831250,0.025000,0.025000},{0.668750,0.831250,0.050000,0.050000},{0.681250,0.831250,0.025000,0.025000},{0.681250,0.831250,0.050000,0.050000},{0.693750,0.831250,0.025000,0.025000},{0.693750,0.831250,0.050000,0.050000},{0.706250,0.831250,0.025000,0.025000},{0.706250,0.831250,0.050000,0.050000},{0.718750,0.831250,0.025000,0.025000},{0.718750,0.831250,0.050000,0.050000},{0.731250,0.831250,0.025000,0.025000},{0.731250,0.831250,0.050000,0.050000},{0.743750,0.831250,0.025000,0.025000},{0.743750,0.831250,0.050000,0.050000},{0.756250,0.831250,0.025000,0.025000},{0.756250,0.831250,0.050000,0.050000},{0.768750,0.831250,0.025000,0.025000},{0.768750,0.831250,0.050000,0.050000},{0.781250,0.831250,0.025000,0.025000},{0.781250,0.831250,0.050000,0.050000},{0.793750,0.831250,0.025000,0.025000},{0.793750,0.831250,0.050000,0.050000},{0.806250,0.831250,0.025000,0.025000},{0.806250,0.831250,0.050000,0.050000},{0.818750,0.831250,0.025000,0.025000},{0.818750,0.831250,0.050000,0.050000},{0.831250,0.831250,0.025000,0.025000},{0.831250,0.831250,0.050000,0.050000},{0.843750,0.831250,0.025000,0.025000},{0.843750,0.831250,0.050000,0.050000},{0.856250,0.831250,0.025000,0.025000},{0.856250,0.831250,0.050000,0.050000},{0.868750,0.831250,0.025000,0.025000},{0.868750,0.831250,0.050000,0.050000},{0.881250,0.831250,0.025000,0.025000},{0.881250,0.831250,0.050000,0.050000},{0.893750,0.831250,0.025000,0.025000},{0.893750,0.831250,0.050000,0.050000},{0.906250,0.831250,0.025000,0.025000},{0.906250,0.831250,0.050000,0.050000},{0.918750,0.831250,0.025000,0.025000},{0.918750,0.831250,0.050000,0.050000},{0.931250,0.831250,0.025000,0.025000},{0.931250,0.831250,0.050000,0.050000},{0.943750,0.831250,0.025000,0.025000},{0.943750,0.831250,0.050000,0.050000},{0.956250,0.831250,0.025000,0.025000},{0.956250,0.831250,0.050000,0.050000},{0.968750,0.831250,0.025000,0.025000},{0.968750,0.831250,0.050000,0.050000},{0.981250,0.831250,0.025000,0.025000},{0.981250,0.831250,0.050000,0.050000},{0.993750,0.831250,0.025000,0.025000},{0.993750,0.831250,0.050000,0.050000},{0.006250,0.843750,0.025000,0.025000},{0.006250,0.843750,0.050000,0.050000},{0.018750,0.843750,0.025000,0.025000},{0.018750,0.843750,0.050000,0.050000},{0.031250,0.843750,0.025000,0.025000},{0.031250,0.843750,0.050000,0.050000},{0.043750,0.843750,0.025000,0.025000},{0.043750,0.843750,0.050000,0.050000},{0.056250,0.843750,0.025000,0.025000},{0.056250,0.843750,0.050000,0.050000},{0.068750,0.843750,0.025000,0.025000},{0.068750,0.843750,0.050000,0.050000},{0.081250,0.843750,0.025000,0.025000},{0.081250,0.843750,0.050000,0.050000},{0.093750,0.843750,0.025000,0.025000},{0.093750,0.843750,0.050000,0.050000},{0.106250,0.843750,0.025000,0.025000},{0.106250,0.843750,0.050000,0.050000},{0.118750,0.843750,0.025000,0.025000},{0.118750,0.843750,0.050000,0.050000},{0.131250,0.843750,0.025000,0.025000},{0.131250,0.843750,0.050000,0.050000},{0.143750,0.843750,0.025000,0.025000},{0.143750,0.843750,0.050000,0.050000},{0.156250,0.843750,0.025000,0.025000},{0.156250,0.843750,0.050000,0.050000},{0.168750,0.843750,0.025000,0.025000},{0.168750,0.843750,0.050000,0.050000},{0.181250,0.843750,0.025000,0.025000},{0.181250,0.843750,0.050000,0.050000},{0.193750,0.843750,0.025000,0.025000},{0.193750,0.843750,0.050000,0.050000},{0.206250,0.843750,0.025000,0.025000},{0.206250,0.843750,0.050000,0.050000},{0.218750,0.843750,0.025000,0.025000},{0.218750,0.843750,0.050000,0.050000},{0.231250,0.843750,0.025000,0.025000},{0.231250,0.843750,0.050000,0.050000},{0.243750,0.843750,0.025000,0.025000},{0.243750,0.843750,0.050000,0.050000},{0.256250,0.843750,0.025000,0.025000},{0.256250,0.843750,0.050000,0.050000},{0.268750,0.843750,0.025000,0.025000},{0.268750,0.843750,0.050000,0.050000},{0.281250,0.843750,0.025000,0.025000},{0.281250,0.843750,0.050000,0.050000},{0.293750,0.843750,0.025000,0.025000},{0.293750,0.843750,0.050000,0.050000},{0.306250,0.843750,0.025000,0.025000},{0.306250,0.843750,0.050000,0.050000},{0.318750,0.843750,0.025000,0.025000},{0.318750,0.843750,0.050000,0.050000},{0.331250,0.843750,0.025000,0.025000},{0.331250,0.843750,0.050000,0.050000},{0.343750,0.843750,0.025000,0.025000},{0.343750,0.843750,0.050000,0.050000},{0.356250,0.843750,0.025000,0.025000},{0.356250,0.843750,0.050000,0.050000},{0.368750,0.843750,0.025000,0.025000},{0.368750,0.843750,0.050000,0.050000},{0.381250,0.843750,0.025000,0.025000},{0.381250,0.843750,0.050000,0.050000},{0.393750,0.843750,0.025000,0.025000},{0.393750,0.843750,0.050000,0.050000},{0.406250,0.843750,0.025000,0.025000},{0.406250,0.843750,0.050000,0.050000},{0.418750,0.843750,0.025000,0.025000},{0.418750,0.843750,0.050000,0.050000},{0.431250,0.843750,0.025000,0.025000},{0.431250,0.843750,0.050000,0.050000},{0.443750,0.843750,0.025000,0.025000},{0.443750,0.843750,0.050000,0.050000},{0.456250,0.843750,0.025000,0.025000},{0.456250,0.843750,0.050000,0.050000},{0.468750,0.843750,0.025000,0.025000},{0.468750,0.843750,0.050000,0.050000},{0.481250,0.843750,0.025000,0.025000},{0.481250,0.843750,0.050000,0.050000},{0.493750,0.843750,0.025000,0.025000},{0.493750,0.843750,0.050000,0.050000},{0.506250,0.843750,0.025000,0.025000},{0.506250,0.843750,0.050000,0.050000},{0.518750,0.843750,0.025000,0.025000},{0.518750,0.843750,0.050000,0.050000},{0.531250,0.843750,0.025000,0.025000},{0.531250,0.843750,0.050000,0.050000},{0.543750,0.843750,0.025000,0.025000},{0.543750,0.843750,0.050000,0.050000},{0.556250,0.843750,0.025000,0.025000},{0.556250,0.843750,0.050000,0.050000},{0.568750,0.843750,0.025000,0.025000},{0.568750,0.843750,0.050000,0.050000},{0.581250,0.843750,0.025000,0.025000},{0.581250,0.843750,0.050000,0.050000},{0.593750,0.843750,0.025000,0.025000},{0.593750,0.843750,0.050000,0.050000},{0.606250,0.843750,0.025000,0.025000},{0.606250,0.843750,0.050000,0.050000},{0.618750,0.843750,0.025000,0.025000},{0.618750,0.843750,0.050000,0.050000},{0.631250,0.843750,0.025000,0.025000},{0.631250,0.843750,0.050000,0.050000},{0.643750,0.843750,0.025000,0.025000},{0.643750,0.843750,0.050000,0.050000},{0.656250,0.843750,0.025000,0.025000},{0.656250,0.843750,0.050000,0.050000},{0.668750,0.843750,0.025000,0.025000},{0.668750,0.843750,0.050000,0.050000},{0.681250,0.843750,0.025000,0.025000},{0.681250,0.843750,0.050000,0.050000},{0.693750,0.843750,0.025000,0.025000},{0.693750,0.843750,0.050000,0.050000},{0.706250,0.843750,0.025000,0.025000},{0.706250,0.843750,0.050000,0.050000},{0.718750,0.843750,0.025000,0.025000},{0.718750,0.843750,0.050000,0.050000},{0.731250,0.843750,0.025000,0.025000},{0.731250,0.843750,0.050000,0.050000},{0.743750,0.843750,0.025000,0.025000},{0.743750,0.843750,0.050000,0.050000},{0.756250,0.843750,0.025000,0.025000},{0.756250,0.843750,0.050000,0.050000},{0.768750,0.843750,0.025000,0.025000},{0.768750,0.843750,0.050000,0.050000},{0.781250,0.843750,0.025000,0.025000},{0.781250,0.843750,0.050000,0.050000},{0.793750,0.843750,0.025000,0.025000},{0.793750,0.843750,0.050000,0.050000},{0.806250,0.843750,0.025000,0.025000},{0.806250,0.843750,0.050000,0.050000},{0.818750,0.843750,0.025000,0.025000},{0.818750,0.843750,0.050000,0.050000},{0.831250,0.843750,0.025000,0.025000},{0.831250,0.843750,0.050000,0.050000},{0.843750,0.843750,0.025000,0.025000},{0.843750,0.843750,0.050000,0.050000},{0.856250,0.843750,0.025000,0.025000},{0.856250,0.843750,0.050000,0.050000},{0.868750,0.843750,0.025000,0.025000},{0.868750,0.843750,0.050000,0.050000},{0.881250,0.843750,0.025000,0.025000},{0.881250,0.843750,0.050000,0.050000},{0.893750,0.843750,0.025000,0.025000},{0.893750,0.843750,0.050000,0.050000},{0.906250,0.843750,0.025000,0.025000},{0.906250,0.843750,0.050000,0.050000},{0.918750,0.843750,0.025000,0.025000},{0.918750,0.843750,0.050000,0.050000},{0.931250,0.843750,0.025000,0.025000},{0.931250,0.843750,0.050000,0.050000},{0.943750,0.843750,0.025000,0.025000},{0.943750,0.843750,0.050000,0.050000},{0.956250,0.843750,0.025000,0.025000},{0.956250,0.843750,0.050000,0.050000},{0.968750,0.843750,0.025000,0.025000},{0.968750,0.843750,0.050000,0.050000},{0.981250,0.843750,0.025000,0.025000},{0.981250,0.843750,0.050000,0.050000},{0.993750,0.843750,0.025000,0.025000},{0.993750,0.843750,0.050000,0.050000},{0.006250,0.856250,0.025000,0.025000},{0.006250,0.856250,0.050000,0.050000},{0.018750,0.856250,0.025000,0.025000},{0.018750,0.856250,0.050000,0.050000},{0.031250,0.856250,0.025000,0.025000},{0.031250,0.856250,0.050000,0.050000},{0.043750,0.856250,0.025000,0.025000},{0.043750,0.856250,0.050000,0.050000},{0.056250,0.856250,0.025000,0.025000},{0.056250,0.856250,0.050000,0.050000},{0.068750,0.856250,0.025000,0.025000},{0.068750,0.856250,0.050000,0.050000},{0.081250,0.856250,0.025000,0.025000},{0.081250,0.856250,0.050000,0.050000},{0.093750,0.856250,0.025000,0.025000},{0.093750,0.856250,0.050000,0.050000},{0.106250,0.856250,0.025000,0.025000},{0.106250,0.856250,0.050000,0.050000},{0.118750,0.856250,0.025000,0.025000},{0.118750,0.856250,0.050000,0.050000},{0.131250,0.856250,0.025000,0.025000},{0.131250,0.856250,0.050000,0.050000},{0.143750,0.856250,0.025000,0.025000},{0.143750,0.856250,0.050000,0.050000},{0.156250,0.856250,0.025000,0.025000},{0.156250,0.856250,0.050000,0.050000},{0.168750,0.856250,0.025000,0.025000},{0.168750,0.856250,0.050000,0.050000},{0.181250,0.856250,0.025000,0.025000},{0.181250,0.856250,0.050000,0.050000},{0.193750,0.856250,0.025000,0.025000},{0.193750,0.856250,0.050000,0.050000},{0.206250,0.856250,0.025000,0.025000},{0.206250,0.856250,0.050000,0.050000},{0.218750,0.856250,0.025000,0.025000},{0.218750,0.856250,0.050000,0.050000},{0.231250,0.856250,0.025000,0.025000},{0.231250,0.856250,0.050000,0.050000},{0.243750,0.856250,0.025000,0.025000},{0.243750,0.856250,0.050000,0.050000},{0.256250,0.856250,0.025000,0.025000},{0.256250,0.856250,0.050000,0.050000},{0.268750,0.856250,0.025000,0.025000},{0.268750,0.856250,0.050000,0.050000},{0.281250,0.856250,0.025000,0.025000},{0.281250,0.856250,0.050000,0.050000},{0.293750,0.856250,0.025000,0.025000},{0.293750,0.856250,0.050000,0.050000},{0.306250,0.856250,0.025000,0.025000},{0.306250,0.856250,0.050000,0.050000},{0.318750,0.856250,0.025000,0.025000},{0.318750,0.856250,0.050000,0.050000},{0.331250,0.856250,0.025000,0.025000},{0.331250,0.856250,0.050000,0.050000},{0.343750,0.856250,0.025000,0.025000},{0.343750,0.856250,0.050000,0.050000},{0.356250,0.856250,0.025000,0.025000},{0.356250,0.856250,0.050000,0.050000},{0.368750,0.856250,0.025000,0.025000},{0.368750,0.856250,0.050000,0.050000},{0.381250,0.856250,0.025000,0.025000},{0.381250,0.856250,0.050000,0.050000},{0.393750,0.856250,0.025000,0.025000},{0.393750,0.856250,0.050000,0.050000},{0.406250,0.856250,0.025000,0.025000},{0.406250,0.856250,0.050000,0.050000},{0.418750,0.856250,0.025000,0.025000},{0.418750,0.856250,0.050000,0.050000},{0.431250,0.856250,0.025000,0.025000},{0.431250,0.856250,0.050000,0.050000},{0.443750,0.856250,0.025000,0.025000},{0.443750,0.856250,0.050000,0.050000},{0.456250,0.856250,0.025000,0.025000},{0.456250,0.856250,0.050000,0.050000},{0.468750,0.856250,0.025000,0.025000},{0.468750,0.856250,0.050000,0.050000},{0.481250,0.856250,0.025000,0.025000},{0.481250,0.856250,0.050000,0.050000},{0.493750,0.856250,0.025000,0.025000},{0.493750,0.856250,0.050000,0.050000},{0.506250,0.856250,0.025000,0.025000},{0.506250,0.856250,0.050000,0.050000},{0.518750,0.856250,0.025000,0.025000},{0.518750,0.856250,0.050000,0.050000},{0.531250,0.856250,0.025000,0.025000},{0.531250,0.856250,0.050000,0.050000},{0.543750,0.856250,0.025000,0.025000},{0.543750,0.856250,0.050000,0.050000},{0.556250,0.856250,0.025000,0.025000},{0.556250,0.856250,0.050000,0.050000},{0.568750,0.856250,0.025000,0.025000},{0.568750,0.856250,0.050000,0.050000},{0.581250,0.856250,0.025000,0.025000},{0.581250,0.856250,0.050000,0.050000},{0.593750,0.856250,0.025000,0.025000},{0.593750,0.856250,0.050000,0.050000},{0.606250,0.856250,0.025000,0.025000},{0.606250,0.856250,0.050000,0.050000},{0.618750,0.856250,0.025000,0.025000},{0.618750,0.856250,0.050000,0.050000},{0.631250,0.856250,0.025000,0.025000},{0.631250,0.856250,0.050000,0.050000},{0.643750,0.856250,0.025000,0.025000},{0.643750,0.856250,0.050000,0.050000},{0.656250,0.856250,0.025000,0.025000},{0.656250,0.856250,0.050000,0.050000},{0.668750,0.856250,0.025000,0.025000},{0.668750,0.856250,0.050000,0.050000},{0.681250,0.856250,0.025000,0.025000},{0.681250,0.856250,0.050000,0.050000},{0.693750,0.856250,0.025000,0.025000},{0.693750,0.856250,0.050000,0.050000},{0.706250,0.856250,0.025000,0.025000},{0.706250,0.856250,0.050000,0.050000},{0.718750,0.856250,0.025000,0.025000},{0.718750,0.856250,0.050000,0.050000},{0.731250,0.856250,0.025000,0.025000},{0.731250,0.856250,0.050000,0.050000},{0.743750,0.856250,0.025000,0.025000},{0.743750,0.856250,0.050000,0.050000},{0.756250,0.856250,0.025000,0.025000},{0.756250,0.856250,0.050000,0.050000},{0.768750,0.856250,0.025000,0.025000},{0.768750,0.856250,0.050000,0.050000},{0.781250,0.856250,0.025000,0.025000},{0.781250,0.856250,0.050000,0.050000},{0.793750,0.856250,0.025000,0.025000},{0.793750,0.856250,0.050000,0.050000},{0.806250,0.856250,0.025000,0.025000},{0.806250,0.856250,0.050000,0.050000},{0.818750,0.856250,0.025000,0.025000},{0.818750,0.856250,0.050000,0.050000},{0.831250,0.856250,0.025000,0.025000},{0.831250,0.856250,0.050000,0.050000},{0.843750,0.856250,0.025000,0.025000},{0.843750,0.856250,0.050000,0.050000},{0.856250,0.856250,0.025000,0.025000},{0.856250,0.856250,0.050000,0.050000},{0.868750,0.856250,0.025000,0.025000},{0.868750,0.856250,0.050000,0.050000},{0.881250,0.856250,0.025000,0.025000},{0.881250,0.856250,0.050000,0.050000},{0.893750,0.856250,0.025000,0.025000},{0.893750,0.856250,0.050000,0.050000},{0.906250,0.856250,0.025000,0.025000},{0.906250,0.856250,0.050000,0.050000},{0.918750,0.856250,0.025000,0.025000},{0.918750,0.856250,0.050000,0.050000},{0.931250,0.856250,0.025000,0.025000},{0.931250,0.856250,0.050000,0.050000},{0.943750,0.856250,0.025000,0.025000},{0.943750,0.856250,0.050000,0.050000},{0.956250,0.856250,0.025000,0.025000},{0.956250,0.856250,0.050000,0.050000},{0.968750,0.856250,0.025000,0.025000},{0.968750,0.856250,0.050000,0.050000},{0.981250,0.856250,0.025000,0.025000},{0.981250,0.856250,0.050000,0.050000},{0.993750,0.856250,0.025000,0.025000},{0.993750,0.856250,0.050000,0.050000},{0.006250,0.868750,0.025000,0.025000},{0.006250,0.868750,0.050000,0.050000},{0.018750,0.868750,0.025000,0.025000},{0.018750,0.868750,0.050000,0.050000},{0.031250,0.868750,0.025000,0.025000},{0.031250,0.868750,0.050000,0.050000},{0.043750,0.868750,0.025000,0.025000},{0.043750,0.868750,0.050000,0.050000},{0.056250,0.868750,0.025000,0.025000},{0.056250,0.868750,0.050000,0.050000},{0.068750,0.868750,0.025000,0.025000},{0.068750,0.868750,0.050000,0.050000},{0.081250,0.868750,0.025000,0.025000},{0.081250,0.868750,0.050000,0.050000},{0.093750,0.868750,0.025000,0.025000},{0.093750,0.868750,0.050000,0.050000},{0.106250,0.868750,0.025000,0.025000},{0.106250,0.868750,0.050000,0.050000},{0.118750,0.868750,0.025000,0.025000},{0.118750,0.868750,0.050000,0.050000},{0.131250,0.868750,0.025000,0.025000},{0.131250,0.868750,0.050000,0.050000},{0.143750,0.868750,0.025000,0.025000},{0.143750,0.868750,0.050000,0.050000},{0.156250,0.868750,0.025000,0.025000},{0.156250,0.868750,0.050000,0.050000},{0.168750,0.868750,0.025000,0.025000},{0.168750,0.868750,0.050000,0.050000},{0.181250,0.868750,0.025000,0.025000},{0.181250,0.868750,0.050000,0.050000},{0.193750,0.868750,0.025000,0.025000},{0.193750,0.868750,0.050000,0.050000},{0.206250,0.868750,0.025000,0.025000},{0.206250,0.868750,0.050000,0.050000},{0.218750,0.868750,0.025000,0.025000},{0.218750,0.868750,0.050000,0.050000},{0.231250,0.868750,0.025000,0.025000},{0.231250,0.868750,0.050000,0.050000},{0.243750,0.868750,0.025000,0.025000},{0.243750,0.868750,0.050000,0.050000},{0.256250,0.868750,0.025000,0.025000},{0.256250,0.868750,0.050000,0.050000},{0.268750,0.868750,0.025000,0.025000},{0.268750,0.868750,0.050000,0.050000},{0.281250,0.868750,0.025000,0.025000},{0.281250,0.868750,0.050000,0.050000},{0.293750,0.868750,0.025000,0.025000},{0.293750,0.868750,0.050000,0.050000},{0.306250,0.868750,0.025000,0.025000},{0.306250,0.868750,0.050000,0.050000},{0.318750,0.868750,0.025000,0.025000},{0.318750,0.868750,0.050000,0.050000},{0.331250,0.868750,0.025000,0.025000},{0.331250,0.868750,0.050000,0.050000},{0.343750,0.868750,0.025000,0.025000},{0.343750,0.868750,0.050000,0.050000},{0.356250,0.868750,0.025000,0.025000},{0.356250,0.868750,0.050000,0.050000},{0.368750,0.868750,0.025000,0.025000},{0.368750,0.868750,0.050000,0.050000},{0.381250,0.868750,0.025000,0.025000},{0.381250,0.868750,0.050000,0.050000},{0.393750,0.868750,0.025000,0.025000},{0.393750,0.868750,0.050000,0.050000},{0.406250,0.868750,0.025000,0.025000},{0.406250,0.868750,0.050000,0.050000},{0.418750,0.868750,0.025000,0.025000},{0.418750,0.868750,0.050000,0.050000},{0.431250,0.868750,0.025000,0.025000},{0.431250,0.868750,0.050000,0.050000},{0.443750,0.868750,0.025000,0.025000},{0.443750,0.868750,0.050000,0.050000},{0.456250,0.868750,0.025000,0.025000},{0.456250,0.868750,0.050000,0.050000},{0.468750,0.868750,0.025000,0.025000},{0.468750,0.868750,0.050000,0.050000},{0.481250,0.868750,0.025000,0.025000},{0.481250,0.868750,0.050000,0.050000},{0.493750,0.868750,0.025000,0.025000},{0.493750,0.868750,0.050000,0.050000},{0.506250,0.868750,0.025000,0.025000},{0.506250,0.868750,0.050000,0.050000},{0.518750,0.868750,0.025000,0.025000},{0.518750,0.868750,0.050000,0.050000},{0.531250,0.868750,0.025000,0.025000},{0.531250,0.868750,0.050000,0.050000},{0.543750,0.868750,0.025000,0.025000},{0.543750,0.868750,0.050000,0.050000},{0.556250,0.868750,0.025000,0.025000},{0.556250,0.868750,0.050000,0.050000},{0.568750,0.868750,0.025000,0.025000},{0.568750,0.868750,0.050000,0.050000},{0.581250,0.868750,0.025000,0.025000},{0.581250,0.868750,0.050000,0.050000},{0.593750,0.868750,0.025000,0.025000},{0.593750,0.868750,0.050000,0.050000},{0.606250,0.868750,0.025000,0.025000},{0.606250,0.868750,0.050000,0.050000},{0.618750,0.868750,0.025000,0.025000},{0.618750,0.868750,0.050000,0.050000},{0.631250,0.868750,0.025000,0.025000},{0.631250,0.868750,0.050000,0.050000},{0.643750,0.868750,0.025000,0.025000},{0.643750,0.868750,0.050000,0.050000},{0.656250,0.868750,0.025000,0.025000},{0.656250,0.868750,0.050000,0.050000},{0.668750,0.868750,0.025000,0.025000},{0.668750,0.868750,0.050000,0.050000},{0.681250,0.868750,0.025000,0.025000},{0.681250,0.868750,0.050000,0.050000},{0.693750,0.868750,0.025000,0.025000},{0.693750,0.868750,0.050000,0.050000},{0.706250,0.868750,0.025000,0.025000},{0.706250,0.868750,0.050000,0.050000},{0.718750,0.868750,0.025000,0.025000},{0.718750,0.868750,0.050000,0.050000},{0.731250,0.868750,0.025000,0.025000},{0.731250,0.868750,0.050000,0.050000},{0.743750,0.868750,0.025000,0.025000},{0.743750,0.868750,0.050000,0.050000},{0.756250,0.868750,0.025000,0.025000},{0.756250,0.868750,0.050000,0.050000},{0.768750,0.868750,0.025000,0.025000},{0.768750,0.868750,0.050000,0.050000},{0.781250,0.868750,0.025000,0.025000},{0.781250,0.868750,0.050000,0.050000},{0.793750,0.868750,0.025000,0.025000},{0.793750,0.868750,0.050000,0.050000},{0.806250,0.868750,0.025000,0.025000},{0.806250,0.868750,0.050000,0.050000},{0.818750,0.868750,0.025000,0.025000},{0.818750,0.868750,0.050000,0.050000},{0.831250,0.868750,0.025000,0.025000},{0.831250,0.868750,0.050000,0.050000},{0.843750,0.868750,0.025000,0.025000},{0.843750,0.868750,0.050000,0.050000},{0.856250,0.868750,0.025000,0.025000},{0.856250,0.868750,0.050000,0.050000},{0.868750,0.868750,0.025000,0.025000},{0.868750,0.868750,0.050000,0.050000},{0.881250,0.868750,0.025000,0.025000},{0.881250,0.868750,0.050000,0.050000},{0.893750,0.868750,0.025000,0.025000},{0.893750,0.868750,0.050000,0.050000},{0.906250,0.868750,0.025000,0.025000},{0.906250,0.868750,0.050000,0.050000},{0.918750,0.868750,0.025000,0.025000},{0.918750,0.868750,0.050000,0.050000},{0.931250,0.868750,0.025000,0.025000},{0.931250,0.868750,0.050000,0.050000},{0.943750,0.868750,0.025000,0.025000},{0.943750,0.868750,0.050000,0.050000},{0.956250,0.868750,0.025000,0.025000},{0.956250,0.868750,0.050000,0.050000},{0.968750,0.868750,0.025000,0.025000},{0.968750,0.868750,0.050000,0.050000},{0.981250,0.868750,0.025000,0.025000},{0.981250,0.868750,0.050000,0.050000},{0.993750,0.868750,0.025000,0.025000},{0.993750,0.868750,0.050000,0.050000},{0.006250,0.881250,0.025000,0.025000},{0.006250,0.881250,0.050000,0.050000},{0.018750,0.881250,0.025000,0.025000},{0.018750,0.881250,0.050000,0.050000},{0.031250,0.881250,0.025000,0.025000},{0.031250,0.881250,0.050000,0.050000},{0.043750,0.881250,0.025000,0.025000},{0.043750,0.881250,0.050000,0.050000},{0.056250,0.881250,0.025000,0.025000},{0.056250,0.881250,0.050000,0.050000},{0.068750,0.881250,0.025000,0.025000},{0.068750,0.881250,0.050000,0.050000},{0.081250,0.881250,0.025000,0.025000},{0.081250,0.881250,0.050000,0.050000},{0.093750,0.881250,0.025000,0.025000},{0.093750,0.881250,0.050000,0.050000},{0.106250,0.881250,0.025000,0.025000},{0.106250,0.881250,0.050000,0.050000},{0.118750,0.881250,0.025000,0.025000},{0.118750,0.881250,0.050000,0.050000},{0.131250,0.881250,0.025000,0.025000},{0.131250,0.881250,0.050000,0.050000},{0.143750,0.881250,0.025000,0.025000},{0.143750,0.881250,0.050000,0.050000},{0.156250,0.881250,0.025000,0.025000},{0.156250,0.881250,0.050000,0.050000},{0.168750,0.881250,0.025000,0.025000},{0.168750,0.881250,0.050000,0.050000},{0.181250,0.881250,0.025000,0.025000},{0.181250,0.881250,0.050000,0.050000},{0.193750,0.881250,0.025000,0.025000},{0.193750,0.881250,0.050000,0.050000},{0.206250,0.881250,0.025000,0.025000},{0.206250,0.881250,0.050000,0.050000},{0.218750,0.881250,0.025000,0.025000},{0.218750,0.881250,0.050000,0.050000},{0.231250,0.881250,0.025000,0.025000},{0.231250,0.881250,0.050000,0.050000},{0.243750,0.881250,0.025000,0.025000},{0.243750,0.881250,0.050000,0.050000},{0.256250,0.881250,0.025000,0.025000},{0.256250,0.881250,0.050000,0.050000},{0.268750,0.881250,0.025000,0.025000},{0.268750,0.881250,0.050000,0.050000},{0.281250,0.881250,0.025000,0.025000},{0.281250,0.881250,0.050000,0.050000},{0.293750,0.881250,0.025000,0.025000},{0.293750,0.881250,0.050000,0.050000},{0.306250,0.881250,0.025000,0.025000},{0.306250,0.881250,0.050000,0.050000},{0.318750,0.881250,0.025000,0.025000},{0.318750,0.881250,0.050000,0.050000},{0.331250,0.881250,0.025000,0.025000},{0.331250,0.881250,0.050000,0.050000},{0.343750,0.881250,0.025000,0.025000},{0.343750,0.881250,0.050000,0.050000},{0.356250,0.881250,0.025000,0.025000},{0.356250,0.881250,0.050000,0.050000},{0.368750,0.881250,0.025000,0.025000},{0.368750,0.881250,0.050000,0.050000},{0.381250,0.881250,0.025000,0.025000},{0.381250,0.881250,0.050000,0.050000},{0.393750,0.881250,0.025000,0.025000},{0.393750,0.881250,0.050000,0.050000},{0.406250,0.881250,0.025000,0.025000},{0.406250,0.881250,0.050000,0.050000},{0.418750,0.881250,0.025000,0.025000},{0.418750,0.881250,0.050000,0.050000},{0.431250,0.881250,0.025000,0.025000},{0.431250,0.881250,0.050000,0.050000},{0.443750,0.881250,0.025000,0.025000},{0.443750,0.881250,0.050000,0.050000},{0.456250,0.881250,0.025000,0.025000},{0.456250,0.881250,0.050000,0.050000},{0.468750,0.881250,0.025000,0.025000},{0.468750,0.881250,0.050000,0.050000},{0.481250,0.881250,0.025000,0.025000},{0.481250,0.881250,0.050000,0.050000},{0.493750,0.881250,0.025000,0.025000},{0.493750,0.881250,0.050000,0.050000},{0.506250,0.881250,0.025000,0.025000},{0.506250,0.881250,0.050000,0.050000},{0.518750,0.881250,0.025000,0.025000},{0.518750,0.881250,0.050000,0.050000},{0.531250,0.881250,0.025000,0.025000},{0.531250,0.881250,0.050000,0.050000},{0.543750,0.881250,0.025000,0.025000},{0.543750,0.881250,0.050000,0.050000},{0.556250,0.881250,0.025000,0.025000},{0.556250,0.881250,0.050000,0.050000},{0.568750,0.881250,0.025000,0.025000},{0.568750,0.881250,0.050000,0.050000},{0.581250,0.881250,0.025000,0.025000},{0.581250,0.881250,0.050000,0.050000},{0.593750,0.881250,0.025000,0.025000},{0.593750,0.881250,0.050000,0.050000},{0.606250,0.881250,0.025000,0.025000},{0.606250,0.881250,0.050000,0.050000},{0.618750,0.881250,0.025000,0.025000},{0.618750,0.881250,0.050000,0.050000},{0.631250,0.881250,0.025000,0.025000},{0.631250,0.881250,0.050000,0.050000},{0.643750,0.881250,0.025000,0.025000},{0.643750,0.881250,0.050000,0.050000},{0.656250,0.881250,0.025000,0.025000},{0.656250,0.881250,0.050000,0.050000},{0.668750,0.881250,0.025000,0.025000},{0.668750,0.881250,0.050000,0.050000},{0.681250,0.881250,0.025000,0.025000},{0.681250,0.881250,0.050000,0.050000},{0.693750,0.881250,0.025000,0.025000},{0.693750,0.881250,0.050000,0.050000},{0.706250,0.881250,0.025000,0.025000},{0.706250,0.881250,0.050000,0.050000},{0.718750,0.881250,0.025000,0.025000},{0.718750,0.881250,0.050000,0.050000},{0.731250,0.881250,0.025000,0.025000},{0.731250,0.881250,0.050000,0.050000},{0.743750,0.881250,0.025000,0.025000},{0.743750,0.881250,0.050000,0.050000},{0.756250,0.881250,0.025000,0.025000},{0.756250,0.881250,0.050000,0.050000},{0.768750,0.881250,0.025000,0.025000},{0.768750,0.881250,0.050000,0.050000},{0.781250,0.881250,0.025000,0.025000},{0.781250,0.881250,0.050000,0.050000},{0.793750,0.881250,0.025000,0.025000},{0.793750,0.881250,0.050000,0.050000},{0.806250,0.881250,0.025000,0.025000},{0.806250,0.881250,0.050000,0.050000},{0.818750,0.881250,0.025000,0.025000},{0.818750,0.881250,0.050000,0.050000},{0.831250,0.881250,0.025000,0.025000},{0.831250,0.881250,0.050000,0.050000},{0.843750,0.881250,0.025000,0.025000},{0.843750,0.881250,0.050000,0.050000},{0.856250,0.881250,0.025000,0.025000},{0.856250,0.881250,0.050000,0.050000},{0.868750,0.881250,0.025000,0.025000},{0.868750,0.881250,0.050000,0.050000},{0.881250,0.881250,0.025000,0.025000},{0.881250,0.881250,0.050000,0.050000},{0.893750,0.881250,0.025000,0.025000},{0.893750,0.881250,0.050000,0.050000},{0.906250,0.881250,0.025000,0.025000},{0.906250,0.881250,0.050000,0.050000},{0.918750,0.881250,0.025000,0.025000},{0.918750,0.881250,0.050000,0.050000},{0.931250,0.881250,0.025000,0.025000},{0.931250,0.881250,0.050000,0.050000},{0.943750,0.881250,0.025000,0.025000},{0.943750,0.881250,0.050000,0.050000},{0.956250,0.881250,0.025000,0.025000},{0.956250,0.881250,0.050000,0.050000},{0.968750,0.881250,0.025000,0.025000},{0.968750,0.881250,0.050000,0.050000},{0.981250,0.881250,0.025000,0.025000},{0.981250,0.881250,0.050000,0.050000},{0.993750,0.881250,0.025000,0.025000},{0.993750,0.881250,0.050000,0.050000},{0.006250,0.893750,0.025000,0.025000},{0.006250,0.893750,0.050000,0.050000},{0.018750,0.893750,0.025000,0.025000},{0.018750,0.893750,0.050000,0.050000},{0.031250,0.893750,0.025000,0.025000},{0.031250,0.893750,0.050000,0.050000},{0.043750,0.893750,0.025000,0.025000},{0.043750,0.893750,0.050000,0.050000},{0.056250,0.893750,0.025000,0.025000},{0.056250,0.893750,0.050000,0.050000},{0.068750,0.893750,0.025000,0.025000},{0.068750,0.893750,0.050000,0.050000},{0.081250,0.893750,0.025000,0.025000},{0.081250,0.893750,0.050000,0.050000},{0.093750,0.893750,0.025000,0.025000},{0.093750,0.893750,0.050000,0.050000},{0.106250,0.893750,0.025000,0.025000},{0.106250,0.893750,0.050000,0.050000},{0.118750,0.893750,0.025000,0.025000},{0.118750,0.893750,0.050000,0.050000},{0.131250,0.893750,0.025000,0.025000},{0.131250,0.893750,0.050000,0.050000},{0.143750,0.893750,0.025000,0.025000},{0.143750,0.893750,0.050000,0.050000},{0.156250,0.893750,0.025000,0.025000},{0.156250,0.893750,0.050000,0.050000},{0.168750,0.893750,0.025000,0.025000},{0.168750,0.893750,0.050000,0.050000},{0.181250,0.893750,0.025000,0.025000},{0.181250,0.893750,0.050000,0.050000},{0.193750,0.893750,0.025000,0.025000},{0.193750,0.893750,0.050000,0.050000},{0.206250,0.893750,0.025000,0.025000},{0.206250,0.893750,0.050000,0.050000},{0.218750,0.893750,0.025000,0.025000},{0.218750,0.893750,0.050000,0.050000},{0.231250,0.893750,0.025000,0.025000},{0.231250,0.893750,0.050000,0.050000},{0.243750,0.893750,0.025000,0.025000},{0.243750,0.893750,0.050000,0.050000},{0.256250,0.893750,0.025000,0.025000},{0.256250,0.893750,0.050000,0.050000},{0.268750,0.893750,0.025000,0.025000},{0.268750,0.893750,0.050000,0.050000},{0.281250,0.893750,0.025000,0.025000},{0.281250,0.893750,0.050000,0.050000},{0.293750,0.893750,0.025000,0.025000},{0.293750,0.893750,0.050000,0.050000},{0.306250,0.893750,0.025000,0.025000},{0.306250,0.893750,0.050000,0.050000},{0.318750,0.893750,0.025000,0.025000},{0.318750,0.893750,0.050000,0.050000},{0.331250,0.893750,0.025000,0.025000},{0.331250,0.893750,0.050000,0.050000},{0.343750,0.893750,0.025000,0.025000},{0.343750,0.893750,0.050000,0.050000},{0.356250,0.893750,0.025000,0.025000},{0.356250,0.893750,0.050000,0.050000},{0.368750,0.893750,0.025000,0.025000},{0.368750,0.893750,0.050000,0.050000},{0.381250,0.893750,0.025000,0.025000},{0.381250,0.893750,0.050000,0.050000},{0.393750,0.893750,0.025000,0.025000},{0.393750,0.893750,0.050000,0.050000},{0.406250,0.893750,0.025000,0.025000},{0.406250,0.893750,0.050000,0.050000},{0.418750,0.893750,0.025000,0.025000},{0.418750,0.893750,0.050000,0.050000},{0.431250,0.893750,0.025000,0.025000},{0.431250,0.893750,0.050000,0.050000},{0.443750,0.893750,0.025000,0.025000},{0.443750,0.893750,0.050000,0.050000},{0.456250,0.893750,0.025000,0.025000},{0.456250,0.893750,0.050000,0.050000},{0.468750,0.893750,0.025000,0.025000},{0.468750,0.893750,0.050000,0.050000},{0.481250,0.893750,0.025000,0.025000},{0.481250,0.893750,0.050000,0.050000},{0.493750,0.893750,0.025000,0.025000},{0.493750,0.893750,0.050000,0.050000},{0.506250,0.893750,0.025000,0.025000},{0.506250,0.893750,0.050000,0.050000},{0.518750,0.893750,0.025000,0.025000},{0.518750,0.893750,0.050000,0.050000},{0.531250,0.893750,0.025000,0.025000},{0.531250,0.893750,0.050000,0.050000},{0.543750,0.893750,0.025000,0.025000},{0.543750,0.893750,0.050000,0.050000},{0.556250,0.893750,0.025000,0.025000},{0.556250,0.893750,0.050000,0.050000},{0.568750,0.893750,0.025000,0.025000},{0.568750,0.893750,0.050000,0.050000},{0.581250,0.893750,0.025000,0.025000},{0.581250,0.893750,0.050000,0.050000},{0.593750,0.893750,0.025000,0.025000},{0.593750,0.893750,0.050000,0.050000},{0.606250,0.893750,0.025000,0.025000},{0.606250,0.893750,0.050000,0.050000},{0.618750,0.893750,0.025000,0.025000},{0.618750,0.893750,0.050000,0.050000},{0.631250,0.893750,0.025000,0.025000},{0.631250,0.893750,0.050000,0.050000},{0.643750,0.893750,0.025000,0.025000},{0.643750,0.893750,0.050000,0.050000},{0.656250,0.893750,0.025000,0.025000},{0.656250,0.893750,0.050000,0.050000},{0.668750,0.893750,0.025000,0.025000},{0.668750,0.893750,0.050000,0.050000},{0.681250,0.893750,0.025000,0.025000},{0.681250,0.893750,0.050000,0.050000},{0.693750,0.893750,0.025000,0.025000},{0.693750,0.893750,0.050000,0.050000},{0.706250,0.893750,0.025000,0.025000},{0.706250,0.893750,0.050000,0.050000},{0.718750,0.893750,0.025000,0.025000},{0.718750,0.893750,0.050000,0.050000},{0.731250,0.893750,0.025000,0.025000},{0.731250,0.893750,0.050000,0.050000},{0.743750,0.893750,0.025000,0.025000},{0.743750,0.893750,0.050000,0.050000},{0.756250,0.893750,0.025000,0.025000},{0.756250,0.893750,0.050000,0.050000},{0.768750,0.893750,0.025000,0.025000},{0.768750,0.893750,0.050000,0.050000},{0.781250,0.893750,0.025000,0.025000},{0.781250,0.893750,0.050000,0.050000},{0.793750,0.893750,0.025000,0.025000},{0.793750,0.893750,0.050000,0.050000},{0.806250,0.893750,0.025000,0.025000},{0.806250,0.893750,0.050000,0.050000},{0.818750,0.893750,0.025000,0.025000},{0.818750,0.893750,0.050000,0.050000},{0.831250,0.893750,0.025000,0.025000},{0.831250,0.893750,0.050000,0.050000},{0.843750,0.893750,0.025000,0.025000},{0.843750,0.893750,0.050000,0.050000},{0.856250,0.893750,0.025000,0.025000},{0.856250,0.893750,0.050000,0.050000},{0.868750,0.893750,0.025000,0.025000},{0.868750,0.893750,0.050000,0.050000},{0.881250,0.893750,0.025000,0.025000},{0.881250,0.893750,0.050000,0.050000},{0.893750,0.893750,0.025000,0.025000},{0.893750,0.893750,0.050000,0.050000},{0.906250,0.893750,0.025000,0.025000},{0.906250,0.893750,0.050000,0.050000},{0.918750,0.893750,0.025000,0.025000},{0.918750,0.893750,0.050000,0.050000},{0.931250,0.893750,0.025000,0.025000},{0.931250,0.893750,0.050000,0.050000},{0.943750,0.893750,0.025000,0.025000},{0.943750,0.893750,0.050000,0.050000},{0.956250,0.893750,0.025000,0.025000},{0.956250,0.893750,0.050000,0.050000},{0.968750,0.893750,0.025000,0.025000},{0.968750,0.893750,0.050000,0.050000},{0.981250,0.893750,0.025000,0.025000},{0.981250,0.893750,0.050000,0.050000},{0.993750,0.893750,0.025000,0.025000},{0.993750,0.893750,0.050000,0.050000},{0.006250,0.906250,0.025000,0.025000},{0.006250,0.906250,0.050000,0.050000},{0.018750,0.906250,0.025000,0.025000},{0.018750,0.906250,0.050000,0.050000},{0.031250,0.906250,0.025000,0.025000},{0.031250,0.906250,0.050000,0.050000},{0.043750,0.906250,0.025000,0.025000},{0.043750,0.906250,0.050000,0.050000},{0.056250,0.906250,0.025000,0.025000},{0.056250,0.906250,0.050000,0.050000},{0.068750,0.906250,0.025000,0.025000},{0.068750,0.906250,0.050000,0.050000},{0.081250,0.906250,0.025000,0.025000},{0.081250,0.906250,0.050000,0.050000},{0.093750,0.906250,0.025000,0.025000},{0.093750,0.906250,0.050000,0.050000},{0.106250,0.906250,0.025000,0.025000},{0.106250,0.906250,0.050000,0.050000},{0.118750,0.906250,0.025000,0.025000},{0.118750,0.906250,0.050000,0.050000},{0.131250,0.906250,0.025000,0.025000},{0.131250,0.906250,0.050000,0.050000},{0.143750,0.906250,0.025000,0.025000},{0.143750,0.906250,0.050000,0.050000},{0.156250,0.906250,0.025000,0.025000},{0.156250,0.906250,0.050000,0.050000},{0.168750,0.906250,0.025000,0.025000},{0.168750,0.906250,0.050000,0.050000},{0.181250,0.906250,0.025000,0.025000},{0.181250,0.906250,0.050000,0.050000},{0.193750,0.906250,0.025000,0.025000},{0.193750,0.906250,0.050000,0.050000},{0.206250,0.906250,0.025000,0.025000},{0.206250,0.906250,0.050000,0.050000},{0.218750,0.906250,0.025000,0.025000},{0.218750,0.906250,0.050000,0.050000},{0.231250,0.906250,0.025000,0.025000},{0.231250,0.906250,0.050000,0.050000},{0.243750,0.906250,0.025000,0.025000},{0.243750,0.906250,0.050000,0.050000},{0.256250,0.906250,0.025000,0.025000},{0.256250,0.906250,0.050000,0.050000},{0.268750,0.906250,0.025000,0.025000},{0.268750,0.906250,0.050000,0.050000},{0.281250,0.906250,0.025000,0.025000},{0.281250,0.906250,0.050000,0.050000},{0.293750,0.906250,0.025000,0.025000},{0.293750,0.906250,0.050000,0.050000},{0.306250,0.906250,0.025000,0.025000},{0.306250,0.906250,0.050000,0.050000},{0.318750,0.906250,0.025000,0.025000},{0.318750,0.906250,0.050000,0.050000},{0.331250,0.906250,0.025000,0.025000},{0.331250,0.906250,0.050000,0.050000},{0.343750,0.906250,0.025000,0.025000},{0.343750,0.906250,0.050000,0.050000},{0.356250,0.906250,0.025000,0.025000},{0.356250,0.906250,0.050000,0.050000},{0.368750,0.906250,0.025000,0.025000},{0.368750,0.906250,0.050000,0.050000},{0.381250,0.906250,0.025000,0.025000},{0.381250,0.906250,0.050000,0.050000},{0.393750,0.906250,0.025000,0.025000},{0.393750,0.906250,0.050000,0.050000},{0.406250,0.906250,0.025000,0.025000},{0.406250,0.906250,0.050000,0.050000},{0.418750,0.906250,0.025000,0.025000},{0.418750,0.906250,0.050000,0.050000},{0.431250,0.906250,0.025000,0.025000},{0.431250,0.906250,0.050000,0.050000},{0.443750,0.906250,0.025000,0.025000},{0.443750,0.906250,0.050000,0.050000},{0.456250,0.906250,0.025000,0.025000},{0.456250,0.906250,0.050000,0.050000},{0.468750,0.906250,0.025000,0.025000},{0.468750,0.906250,0.050000,0.050000},{0.481250,0.906250,0.025000,0.025000},{0.481250,0.906250,0.050000,0.050000},{0.493750,0.906250,0.025000,0.025000},{0.493750,0.906250,0.050000,0.050000},{0.506250,0.906250,0.025000,0.025000},{0.506250,0.906250,0.050000,0.050000},{0.518750,0.906250,0.025000,0.025000},{0.518750,0.906250,0.050000,0.050000},{0.531250,0.906250,0.025000,0.025000},{0.531250,0.906250,0.050000,0.050000},{0.543750,0.906250,0.025000,0.025000},{0.543750,0.906250,0.050000,0.050000},{0.556250,0.906250,0.025000,0.025000},{0.556250,0.906250,0.050000,0.050000},{0.568750,0.906250,0.025000,0.025000},{0.568750,0.906250,0.050000,0.050000},{0.581250,0.906250,0.025000,0.025000},{0.581250,0.906250,0.050000,0.050000},{0.593750,0.906250,0.025000,0.025000},{0.593750,0.906250,0.050000,0.050000},{0.606250,0.906250,0.025000,0.025000},{0.606250,0.906250,0.050000,0.050000},{0.618750,0.906250,0.025000,0.025000},{0.618750,0.906250,0.050000,0.050000},{0.631250,0.906250,0.025000,0.025000},{0.631250,0.906250,0.050000,0.050000},{0.643750,0.906250,0.025000,0.025000},{0.643750,0.906250,0.050000,0.050000},{0.656250,0.906250,0.025000,0.025000},{0.656250,0.906250,0.050000,0.050000},{0.668750,0.906250,0.025000,0.025000},{0.668750,0.906250,0.050000,0.050000},{0.681250,0.906250,0.025000,0.025000},{0.681250,0.906250,0.050000,0.050000},{0.693750,0.906250,0.025000,0.025000},{0.693750,0.906250,0.050000,0.050000},{0.706250,0.906250,0.025000,0.025000},{0.706250,0.906250,0.050000,0.050000},{0.718750,0.906250,0.025000,0.025000},{0.718750,0.906250,0.050000,0.050000},{0.731250,0.906250,0.025000,0.025000},{0.731250,0.906250,0.050000,0.050000},{0.743750,0.906250,0.025000,0.025000},{0.743750,0.906250,0.050000,0.050000},{0.756250,0.906250,0.025000,0.025000},{0.756250,0.906250,0.050000,0.050000},{0.768750,0.906250,0.025000,0.025000},{0.768750,0.906250,0.050000,0.050000},{0.781250,0.906250,0.025000,0.025000},{0.781250,0.906250,0.050000,0.050000},{0.793750,0.906250,0.025000,0.025000},{0.793750,0.906250,0.050000,0.050000},{0.806250,0.906250,0.025000,0.025000},{0.806250,0.906250,0.050000,0.050000},{0.818750,0.906250,0.025000,0.025000},{0.818750,0.906250,0.050000,0.050000},{0.831250,0.906250,0.025000,0.025000},{0.831250,0.906250,0.050000,0.050000},{0.843750,0.906250,0.025000,0.025000},{0.843750,0.906250,0.050000,0.050000},{0.856250,0.906250,0.025000,0.025000},{0.856250,0.906250,0.050000,0.050000},{0.868750,0.906250,0.025000,0.025000},{0.868750,0.906250,0.050000,0.050000},{0.881250,0.906250,0.025000,0.025000},{0.881250,0.906250,0.050000,0.050000},{0.893750,0.906250,0.025000,0.025000},{0.893750,0.906250,0.050000,0.050000},{0.906250,0.906250,0.025000,0.025000},{0.906250,0.906250,0.050000,0.050000},{0.918750,0.906250,0.025000,0.025000},{0.918750,0.906250,0.050000,0.050000},{0.931250,0.906250,0.025000,0.025000},{0.931250,0.906250,0.050000,0.050000},{0.943750,0.906250,0.025000,0.025000},{0.943750,0.906250,0.050000,0.050000},{0.956250,0.906250,0.025000,0.025000},{0.956250,0.906250,0.050000,0.050000},{0.968750,0.906250,0.025000,0.025000},{0.968750,0.906250,0.050000,0.050000},{0.981250,0.906250,0.025000,0.025000},{0.981250,0.906250,0.050000,0.050000},{0.993750,0.906250,0.025000,0.025000},{0.993750,0.906250,0.050000,0.050000},{0.006250,0.918750,0.025000,0.025000},{0.006250,0.918750,0.050000,0.050000},{0.018750,0.918750,0.025000,0.025000},{0.018750,0.918750,0.050000,0.050000},{0.031250,0.918750,0.025000,0.025000},{0.031250,0.918750,0.050000,0.050000},{0.043750,0.918750,0.025000,0.025000},{0.043750,0.918750,0.050000,0.050000},{0.056250,0.918750,0.025000,0.025000},{0.056250,0.918750,0.050000,0.050000},{0.068750,0.918750,0.025000,0.025000},{0.068750,0.918750,0.050000,0.050000},{0.081250,0.918750,0.025000,0.025000},{0.081250,0.918750,0.050000,0.050000},{0.093750,0.918750,0.025000,0.025000},{0.093750,0.918750,0.050000,0.050000},{0.106250,0.918750,0.025000,0.025000},{0.106250,0.918750,0.050000,0.050000},{0.118750,0.918750,0.025000,0.025000},{0.118750,0.918750,0.050000,0.050000},{0.131250,0.918750,0.025000,0.025000},{0.131250,0.918750,0.050000,0.050000},{0.143750,0.918750,0.025000,0.025000},{0.143750,0.918750,0.050000,0.050000},{0.156250,0.918750,0.025000,0.025000},{0.156250,0.918750,0.050000,0.050000},{0.168750,0.918750,0.025000,0.025000},{0.168750,0.918750,0.050000,0.050000},{0.181250,0.918750,0.025000,0.025000},{0.181250,0.918750,0.050000,0.050000},{0.193750,0.918750,0.025000,0.025000},{0.193750,0.918750,0.050000,0.050000},{0.206250,0.918750,0.025000,0.025000},{0.206250,0.918750,0.050000,0.050000},{0.218750,0.918750,0.025000,0.025000},{0.218750,0.918750,0.050000,0.050000},{0.231250,0.918750,0.025000,0.025000},{0.231250,0.918750,0.050000,0.050000},{0.243750,0.918750,0.025000,0.025000},{0.243750,0.918750,0.050000,0.050000},{0.256250,0.918750,0.025000,0.025000},{0.256250,0.918750,0.050000,0.050000},{0.268750,0.918750,0.025000,0.025000},{0.268750,0.918750,0.050000,0.050000},{0.281250,0.918750,0.025000,0.025000},{0.281250,0.918750,0.050000,0.050000},{0.293750,0.918750,0.025000,0.025000},{0.293750,0.918750,0.050000,0.050000},{0.306250,0.918750,0.025000,0.025000},{0.306250,0.918750,0.050000,0.050000},{0.318750,0.918750,0.025000,0.025000},{0.318750,0.918750,0.050000,0.050000},{0.331250,0.918750,0.025000,0.025000},{0.331250,0.918750,0.050000,0.050000},{0.343750,0.918750,0.025000,0.025000},{0.343750,0.918750,0.050000,0.050000},{0.356250,0.918750,0.025000,0.025000},{0.356250,0.918750,0.050000,0.050000},{0.368750,0.918750,0.025000,0.025000},{0.368750,0.918750,0.050000,0.050000},{0.381250,0.918750,0.025000,0.025000},{0.381250,0.918750,0.050000,0.050000},{0.393750,0.918750,0.025000,0.025000},{0.393750,0.918750,0.050000,0.050000},{0.406250,0.918750,0.025000,0.025000},{0.406250,0.918750,0.050000,0.050000},{0.418750,0.918750,0.025000,0.025000},{0.418750,0.918750,0.050000,0.050000},{0.431250,0.918750,0.025000,0.025000},{0.431250,0.918750,0.050000,0.050000},{0.443750,0.918750,0.025000,0.025000},{0.443750,0.918750,0.050000,0.050000},{0.456250,0.918750,0.025000,0.025000},{0.456250,0.918750,0.050000,0.050000},{0.468750,0.918750,0.025000,0.025000},{0.468750,0.918750,0.050000,0.050000},{0.481250,0.918750,0.025000,0.025000},{0.481250,0.918750,0.050000,0.050000},{0.493750,0.918750,0.025000,0.025000},{0.493750,0.918750,0.050000,0.050000},{0.506250,0.918750,0.025000,0.025000},{0.506250,0.918750,0.050000,0.050000},{0.518750,0.918750,0.025000,0.025000},{0.518750,0.918750,0.050000,0.050000},{0.531250,0.918750,0.025000,0.025000},{0.531250,0.918750,0.050000,0.050000},{0.543750,0.918750,0.025000,0.025000},{0.543750,0.918750,0.050000,0.050000},{0.556250,0.918750,0.025000,0.025000},{0.556250,0.918750,0.050000,0.050000},{0.568750,0.918750,0.025000,0.025000},{0.568750,0.918750,0.050000,0.050000},{0.581250,0.918750,0.025000,0.025000},{0.581250,0.918750,0.050000,0.050000},{0.593750,0.918750,0.025000,0.025000},{0.593750,0.918750,0.050000,0.050000},{0.606250,0.918750,0.025000,0.025000},{0.606250,0.918750,0.050000,0.050000},{0.618750,0.918750,0.025000,0.025000},{0.618750,0.918750,0.050000,0.050000},{0.631250,0.918750,0.025000,0.025000},{0.631250,0.918750,0.050000,0.050000},{0.643750,0.918750,0.025000,0.025000},{0.643750,0.918750,0.050000,0.050000},{0.656250,0.918750,0.025000,0.025000},{0.656250,0.918750,0.050000,0.050000},{0.668750,0.918750,0.025000,0.025000},{0.668750,0.918750,0.050000,0.050000},{0.681250,0.918750,0.025000,0.025000},{0.681250,0.918750,0.050000,0.050000},{0.693750,0.918750,0.025000,0.025000},{0.693750,0.918750,0.050000,0.050000},{0.706250,0.918750,0.025000,0.025000},{0.706250,0.918750,0.050000,0.050000},{0.718750,0.918750,0.025000,0.025000},{0.718750,0.918750,0.050000,0.050000},{0.731250,0.918750,0.025000,0.025000},{0.731250,0.918750,0.050000,0.050000},{0.743750,0.918750,0.025000,0.025000},{0.743750,0.918750,0.050000,0.050000},{0.756250,0.918750,0.025000,0.025000},{0.756250,0.918750,0.050000,0.050000},{0.768750,0.918750,0.025000,0.025000},{0.768750,0.918750,0.050000,0.050000},{0.781250,0.918750,0.025000,0.025000},{0.781250,0.918750,0.050000,0.050000},{0.793750,0.918750,0.025000,0.025000},{0.793750,0.918750,0.050000,0.050000},{0.806250,0.918750,0.025000,0.025000},{0.806250,0.918750,0.050000,0.050000},{0.818750,0.918750,0.025000,0.025000},{0.818750,0.918750,0.050000,0.050000},{0.831250,0.918750,0.025000,0.025000},{0.831250,0.918750,0.050000,0.050000},{0.843750,0.918750,0.025000,0.025000},{0.843750,0.918750,0.050000,0.050000},{0.856250,0.918750,0.025000,0.025000},{0.856250,0.918750,0.050000,0.050000},{0.868750,0.918750,0.025000,0.025000},{0.868750,0.918750,0.050000,0.050000},{0.881250,0.918750,0.025000,0.025000},{0.881250,0.918750,0.050000,0.050000},{0.893750,0.918750,0.025000,0.025000},{0.893750,0.918750,0.050000,0.050000},{0.906250,0.918750,0.025000,0.025000},{0.906250,0.918750,0.050000,0.050000},{0.918750,0.918750,0.025000,0.025000},{0.918750,0.918750,0.050000,0.050000},{0.931250,0.918750,0.025000,0.025000},{0.931250,0.918750,0.050000,0.050000},{0.943750,0.918750,0.025000,0.025000},{0.943750,0.918750,0.050000,0.050000},{0.956250,0.918750,0.025000,0.025000},{0.956250,0.918750,0.050000,0.050000},{0.968750,0.918750,0.025000,0.025000},{0.968750,0.918750,0.050000,0.050000},{0.981250,0.918750,0.025000,0.025000},{0.981250,0.918750,0.050000,0.050000},{0.993750,0.918750,0.025000,0.025000},{0.993750,0.918750,0.050000,0.050000},{0.006250,0.931250,0.025000,0.025000},{0.006250,0.931250,0.050000,0.050000},{0.018750,0.931250,0.025000,0.025000},{0.018750,0.931250,0.050000,0.050000},{0.031250,0.931250,0.025000,0.025000},{0.031250,0.931250,0.050000,0.050000},{0.043750,0.931250,0.025000,0.025000},{0.043750,0.931250,0.050000,0.050000},{0.056250,0.931250,0.025000,0.025000},{0.056250,0.931250,0.050000,0.050000},{0.068750,0.931250,0.025000,0.025000},{0.068750,0.931250,0.050000,0.050000},{0.081250,0.931250,0.025000,0.025000},{0.081250,0.931250,0.050000,0.050000},{0.093750,0.931250,0.025000,0.025000},{0.093750,0.931250,0.050000,0.050000},{0.106250,0.931250,0.025000,0.025000},{0.106250,0.931250,0.050000,0.050000},{0.118750,0.931250,0.025000,0.025000},{0.118750,0.931250,0.050000,0.050000},{0.131250,0.931250,0.025000,0.025000},{0.131250,0.931250,0.050000,0.050000},{0.143750,0.931250,0.025000,0.025000},{0.143750,0.931250,0.050000,0.050000},{0.156250,0.931250,0.025000,0.025000},{0.156250,0.931250,0.050000,0.050000},{0.168750,0.931250,0.025000,0.025000},{0.168750,0.931250,0.050000,0.050000},{0.181250,0.931250,0.025000,0.025000},{0.181250,0.931250,0.050000,0.050000},{0.193750,0.931250,0.025000,0.025000},{0.193750,0.931250,0.050000,0.050000},{0.206250,0.931250,0.025000,0.025000},{0.206250,0.931250,0.050000,0.050000},{0.218750,0.931250,0.025000,0.025000},{0.218750,0.931250,0.050000,0.050000},{0.231250,0.931250,0.025000,0.025000},{0.231250,0.931250,0.050000,0.050000},{0.243750,0.931250,0.025000,0.025000},{0.243750,0.931250,0.050000,0.050000},{0.256250,0.931250,0.025000,0.025000},{0.256250,0.931250,0.050000,0.050000},{0.268750,0.931250,0.025000,0.025000},{0.268750,0.931250,0.050000,0.050000},{0.281250,0.931250,0.025000,0.025000},{0.281250,0.931250,0.050000,0.050000},{0.293750,0.931250,0.025000,0.025000},{0.293750,0.931250,0.050000,0.050000},{0.306250,0.931250,0.025000,0.025000},{0.306250,0.931250,0.050000,0.050000},{0.318750,0.931250,0.025000,0.025000},{0.318750,0.931250,0.050000,0.050000},{0.331250,0.931250,0.025000,0.025000},{0.331250,0.931250,0.050000,0.050000},{0.343750,0.931250,0.025000,0.025000},{0.343750,0.931250,0.050000,0.050000},{0.356250,0.931250,0.025000,0.025000},{0.356250,0.931250,0.050000,0.050000},{0.368750,0.931250,0.025000,0.025000},{0.368750,0.931250,0.050000,0.050000},{0.381250,0.931250,0.025000,0.025000},{0.381250,0.931250,0.050000,0.050000},{0.393750,0.931250,0.025000,0.025000},{0.393750,0.931250,0.050000,0.050000},{0.406250,0.931250,0.025000,0.025000},{0.406250,0.931250,0.050000,0.050000},{0.418750,0.931250,0.025000,0.025000},{0.418750,0.931250,0.050000,0.050000},{0.431250,0.931250,0.025000,0.025000},{0.431250,0.931250,0.050000,0.050000},{0.443750,0.931250,0.025000,0.025000},{0.443750,0.931250,0.050000,0.050000},{0.456250,0.931250,0.025000,0.025000},{0.456250,0.931250,0.050000,0.050000},{0.468750,0.931250,0.025000,0.025000},{0.468750,0.931250,0.050000,0.050000},{0.481250,0.931250,0.025000,0.025000},{0.481250,0.931250,0.050000,0.050000},{0.493750,0.931250,0.025000,0.025000},{0.493750,0.931250,0.050000,0.050000},{0.506250,0.931250,0.025000,0.025000},{0.506250,0.931250,0.050000,0.050000},{0.518750,0.931250,0.025000,0.025000},{0.518750,0.931250,0.050000,0.050000},{0.531250,0.931250,0.025000,0.025000},{0.531250,0.931250,0.050000,0.050000},{0.543750,0.931250,0.025000,0.025000},{0.543750,0.931250,0.050000,0.050000},{0.556250,0.931250,0.025000,0.025000},{0.556250,0.931250,0.050000,0.050000},{0.568750,0.931250,0.025000,0.025000},{0.568750,0.931250,0.050000,0.050000},{0.581250,0.931250,0.025000,0.025000},{0.581250,0.931250,0.050000,0.050000},{0.593750,0.931250,0.025000,0.025000},{0.593750,0.931250,0.050000,0.050000},{0.606250,0.931250,0.025000,0.025000},{0.606250,0.931250,0.050000,0.050000},{0.618750,0.931250,0.025000,0.025000},{0.618750,0.931250,0.050000,0.050000},{0.631250,0.931250,0.025000,0.025000},{0.631250,0.931250,0.050000,0.050000},{0.643750,0.931250,0.025000,0.025000},{0.643750,0.931250,0.050000,0.050000},{0.656250,0.931250,0.025000,0.025000},{0.656250,0.931250,0.050000,0.050000},{0.668750,0.931250,0.025000,0.025000},{0.668750,0.931250,0.050000,0.050000},{0.681250,0.931250,0.025000,0.025000},{0.681250,0.931250,0.050000,0.050000},{0.693750,0.931250,0.025000,0.025000},{0.693750,0.931250,0.050000,0.050000},{0.706250,0.931250,0.025000,0.025000},{0.706250,0.931250,0.050000,0.050000},{0.718750,0.931250,0.025000,0.025000},{0.718750,0.931250,0.050000,0.050000},{0.731250,0.931250,0.025000,0.025000},{0.731250,0.931250,0.050000,0.050000},{0.743750,0.931250,0.025000,0.025000},{0.743750,0.931250,0.050000,0.050000},{0.756250,0.931250,0.025000,0.025000},{0.756250,0.931250,0.050000,0.050000},{0.768750,0.931250,0.025000,0.025000},{0.768750,0.931250,0.050000,0.050000},{0.781250,0.931250,0.025000,0.025000},{0.781250,0.931250,0.050000,0.050000},{0.793750,0.931250,0.025000,0.025000},{0.793750,0.931250,0.050000,0.050000},{0.806250,0.931250,0.025000,0.025000},{0.806250,0.931250,0.050000,0.050000},{0.818750,0.931250,0.025000,0.025000},{0.818750,0.931250,0.050000,0.050000},{0.831250,0.931250,0.025000,0.025000},{0.831250,0.931250,0.050000,0.050000},{0.843750,0.931250,0.025000,0.025000},{0.843750,0.931250,0.050000,0.050000},{0.856250,0.931250,0.025000,0.025000},{0.856250,0.931250,0.050000,0.050000},{0.868750,0.931250,0.025000,0.025000},{0.868750,0.931250,0.050000,0.050000},{0.881250,0.931250,0.025000,0.025000},{0.881250,0.931250,0.050000,0.050000},{0.893750,0.931250,0.025000,0.025000},{0.893750,0.931250,0.050000,0.050000},{0.906250,0.931250,0.025000,0.025000},{0.906250,0.931250,0.050000,0.050000},{0.918750,0.931250,0.025000,0.025000},{0.918750,0.931250,0.050000,0.050000},{0.931250,0.931250,0.025000,0.025000},{0.931250,0.931250,0.050000,0.050000},{0.943750,0.931250,0.025000,0.025000},{0.943750,0.931250,0.050000,0.050000},{0.956250,0.931250,0.025000,0.025000},{0.956250,0.931250,0.050000,0.050000},{0.968750,0.931250,0.025000,0.025000},{0.968750,0.931250,0.050000,0.050000},{0.981250,0.931250,0.025000,0.025000},{0.981250,0.931250,0.050000,0.050000},{0.993750,0.931250,0.025000,0.025000},{0.993750,0.931250,0.050000,0.050000},{0.006250,0.943750,0.025000,0.025000},{0.006250,0.943750,0.050000,0.050000},{0.018750,0.943750,0.025000,0.025000},{0.018750,0.943750,0.050000,0.050000},{0.031250,0.943750,0.025000,0.025000},{0.031250,0.943750,0.050000,0.050000},{0.043750,0.943750,0.025000,0.025000},{0.043750,0.943750,0.050000,0.050000},{0.056250,0.943750,0.025000,0.025000},{0.056250,0.943750,0.050000,0.050000},{0.068750,0.943750,0.025000,0.025000},{0.068750,0.943750,0.050000,0.050000},{0.081250,0.943750,0.025000,0.025000},{0.081250,0.943750,0.050000,0.050000},{0.093750,0.943750,0.025000,0.025000},{0.093750,0.943750,0.050000,0.050000},{0.106250,0.943750,0.025000,0.025000},{0.106250,0.943750,0.050000,0.050000},{0.118750,0.943750,0.025000,0.025000},{0.118750,0.943750,0.050000,0.050000},{0.131250,0.943750,0.025000,0.025000},{0.131250,0.943750,0.050000,0.050000},{0.143750,0.943750,0.025000,0.025000},{0.143750,0.943750,0.050000,0.050000},{0.156250,0.943750,0.025000,0.025000},{0.156250,0.943750,0.050000,0.050000},{0.168750,0.943750,0.025000,0.025000},{0.168750,0.943750,0.050000,0.050000},{0.181250,0.943750,0.025000,0.025000},{0.181250,0.943750,0.050000,0.050000},{0.193750,0.943750,0.025000,0.025000},{0.193750,0.943750,0.050000,0.050000},{0.206250,0.943750,0.025000,0.025000},{0.206250,0.943750,0.050000,0.050000},{0.218750,0.943750,0.025000,0.025000},{0.218750,0.943750,0.050000,0.050000},{0.231250,0.943750,0.025000,0.025000},{0.231250,0.943750,0.050000,0.050000},{0.243750,0.943750,0.025000,0.025000},{0.243750,0.943750,0.050000,0.050000},{0.256250,0.943750,0.025000,0.025000},{0.256250,0.943750,0.050000,0.050000},{0.268750,0.943750,0.025000,0.025000},{0.268750,0.943750,0.050000,0.050000},{0.281250,0.943750,0.025000,0.025000},{0.281250,0.943750,0.050000,0.050000},{0.293750,0.943750,0.025000,0.025000},{0.293750,0.943750,0.050000,0.050000},{0.306250,0.943750,0.025000,0.025000},{0.306250,0.943750,0.050000,0.050000},{0.318750,0.943750,0.025000,0.025000},{0.318750,0.943750,0.050000,0.050000},{0.331250,0.943750,0.025000,0.025000},{0.331250,0.943750,0.050000,0.050000},{0.343750,0.943750,0.025000,0.025000},{0.343750,0.943750,0.050000,0.050000},{0.356250,0.943750,0.025000,0.025000},{0.356250,0.943750,0.050000,0.050000},{0.368750,0.943750,0.025000,0.025000},{0.368750,0.943750,0.050000,0.050000},{0.381250,0.943750,0.025000,0.025000},{0.381250,0.943750,0.050000,0.050000},{0.393750,0.943750,0.025000,0.025000},{0.393750,0.943750,0.050000,0.050000},{0.406250,0.943750,0.025000,0.025000},{0.406250,0.943750,0.050000,0.050000},{0.418750,0.943750,0.025000,0.025000},{0.418750,0.943750,0.050000,0.050000},{0.431250,0.943750,0.025000,0.025000},{0.431250,0.943750,0.050000,0.050000},{0.443750,0.943750,0.025000,0.025000},{0.443750,0.943750,0.050000,0.050000},{0.456250,0.943750,0.025000,0.025000},{0.456250,0.943750,0.050000,0.050000},{0.468750,0.943750,0.025000,0.025000},{0.468750,0.943750,0.050000,0.050000},{0.481250,0.943750,0.025000,0.025000},{0.481250,0.943750,0.050000,0.050000},{0.493750,0.943750,0.025000,0.025000},{0.493750,0.943750,0.050000,0.050000},{0.506250,0.943750,0.025000,0.025000},{0.506250,0.943750,0.050000,0.050000},{0.518750,0.943750,0.025000,0.025000},{0.518750,0.943750,0.050000,0.050000},{0.531250,0.943750,0.025000,0.025000},{0.531250,0.943750,0.050000,0.050000},{0.543750,0.943750,0.025000,0.025000},{0.543750,0.943750,0.050000,0.050000},{0.556250,0.943750,0.025000,0.025000},{0.556250,0.943750,0.050000,0.050000},{0.568750,0.943750,0.025000,0.025000},{0.568750,0.943750,0.050000,0.050000},{0.581250,0.943750,0.025000,0.025000},{0.581250,0.943750,0.050000,0.050000},{0.593750,0.943750,0.025000,0.025000},{0.593750,0.943750,0.050000,0.050000},{0.606250,0.943750,0.025000,0.025000},{0.606250,0.943750,0.050000,0.050000},{0.618750,0.943750,0.025000,0.025000},{0.618750,0.943750,0.050000,0.050000},{0.631250,0.943750,0.025000,0.025000},{0.631250,0.943750,0.050000,0.050000},{0.643750,0.943750,0.025000,0.025000},{0.643750,0.943750,0.050000,0.050000},{0.656250,0.943750,0.025000,0.025000},{0.656250,0.943750,0.050000,0.050000},{0.668750,0.943750,0.025000,0.025000},{0.668750,0.943750,0.050000,0.050000},{0.681250,0.943750,0.025000,0.025000},{0.681250,0.943750,0.050000,0.050000},{0.693750,0.943750,0.025000,0.025000},{0.693750,0.943750,0.050000,0.050000},{0.706250,0.943750,0.025000,0.025000},{0.706250,0.943750,0.050000,0.050000},{0.718750,0.943750,0.025000,0.025000},{0.718750,0.943750,0.050000,0.050000},{0.731250,0.943750,0.025000,0.025000},{0.731250,0.943750,0.050000,0.050000},{0.743750,0.943750,0.025000,0.025000},{0.743750,0.943750,0.050000,0.050000},{0.756250,0.943750,0.025000,0.025000},{0.756250,0.943750,0.050000,0.050000},{0.768750,0.943750,0.025000,0.025000},{0.768750,0.943750,0.050000,0.050000},{0.781250,0.943750,0.025000,0.025000},{0.781250,0.943750,0.050000,0.050000},{0.793750,0.943750,0.025000,0.025000},{0.793750,0.943750,0.050000,0.050000},{0.806250,0.943750,0.025000,0.025000},{0.806250,0.943750,0.050000,0.050000},{0.818750,0.943750,0.025000,0.025000},{0.818750,0.943750,0.050000,0.050000},{0.831250,0.943750,0.025000,0.025000},{0.831250,0.943750,0.050000,0.050000},{0.843750,0.943750,0.025000,0.025000},{0.843750,0.943750,0.050000,0.050000},{0.856250,0.943750,0.025000,0.025000},{0.856250,0.943750,0.050000,0.050000},{0.868750,0.943750,0.025000,0.025000},{0.868750,0.943750,0.050000,0.050000},{0.881250,0.943750,0.025000,0.025000},{0.881250,0.943750,0.050000,0.050000},{0.893750,0.943750,0.025000,0.025000},{0.893750,0.943750,0.050000,0.050000},{0.906250,0.943750,0.025000,0.025000},{0.906250,0.943750,0.050000,0.050000},{0.918750,0.943750,0.025000,0.025000},{0.918750,0.943750,0.050000,0.050000},{0.931250,0.943750,0.025000,0.025000},{0.931250,0.943750,0.050000,0.050000},{0.943750,0.943750,0.025000,0.025000},{0.943750,0.943750,0.050000,0.050000},{0.956250,0.943750,0.025000,0.025000},{0.956250,0.943750,0.050000,0.050000},{0.968750,0.943750,0.025000,0.025000},{0.968750,0.943750,0.050000,0.050000},{0.981250,0.943750,0.025000,0.025000},{0.981250,0.943750,0.050000,0.050000},{0.993750,0.943750,0.025000,0.025000},{0.993750,0.943750,0.050000,0.050000},{0.006250,0.956250,0.025000,0.025000},{0.006250,0.956250,0.050000,0.050000},{0.018750,0.956250,0.025000,0.025000},{0.018750,0.956250,0.050000,0.050000},{0.031250,0.956250,0.025000,0.025000},{0.031250,0.956250,0.050000,0.050000},{0.043750,0.956250,0.025000,0.025000},{0.043750,0.956250,0.050000,0.050000},{0.056250,0.956250,0.025000,0.025000},{0.056250,0.956250,0.050000,0.050000},{0.068750,0.956250,0.025000,0.025000},{0.068750,0.956250,0.050000,0.050000},{0.081250,0.956250,0.025000,0.025000},{0.081250,0.956250,0.050000,0.050000},{0.093750,0.956250,0.025000,0.025000},{0.093750,0.956250,0.050000,0.050000},{0.106250,0.956250,0.025000,0.025000},{0.106250,0.956250,0.050000,0.050000},{0.118750,0.956250,0.025000,0.025000},{0.118750,0.956250,0.050000,0.050000},{0.131250,0.956250,0.025000,0.025000},{0.131250,0.956250,0.050000,0.050000},{0.143750,0.956250,0.025000,0.025000},{0.143750,0.956250,0.050000,0.050000},{0.156250,0.956250,0.025000,0.025000},{0.156250,0.956250,0.050000,0.050000},{0.168750,0.956250,0.025000,0.025000},{0.168750,0.956250,0.050000,0.050000},{0.181250,0.956250,0.025000,0.025000},{0.181250,0.956250,0.050000,0.050000},{0.193750,0.956250,0.025000,0.025000},{0.193750,0.956250,0.050000,0.050000},{0.206250,0.956250,0.025000,0.025000},{0.206250,0.956250,0.050000,0.050000},{0.218750,0.956250,0.025000,0.025000},{0.218750,0.956250,0.050000,0.050000},{0.231250,0.956250,0.025000,0.025000},{0.231250,0.956250,0.050000,0.050000},{0.243750,0.956250,0.025000,0.025000},{0.243750,0.956250,0.050000,0.050000},{0.256250,0.956250,0.025000,0.025000},{0.256250,0.956250,0.050000,0.050000},{0.268750,0.956250,0.025000,0.025000},{0.268750,0.956250,0.050000,0.050000},{0.281250,0.956250,0.025000,0.025000},{0.281250,0.956250,0.050000,0.050000},{0.293750,0.956250,0.025000,0.025000},{0.293750,0.956250,0.050000,0.050000},{0.306250,0.956250,0.025000,0.025000},{0.306250,0.956250,0.050000,0.050000},{0.318750,0.956250,0.025000,0.025000},{0.318750,0.956250,0.050000,0.050000},{0.331250,0.956250,0.025000,0.025000},{0.331250,0.956250,0.050000,0.050000},{0.343750,0.956250,0.025000,0.025000},{0.343750,0.956250,0.050000,0.050000},{0.356250,0.956250,0.025000,0.025000},{0.356250,0.956250,0.050000,0.050000},{0.368750,0.956250,0.025000,0.025000},{0.368750,0.956250,0.050000,0.050000},{0.381250,0.956250,0.025000,0.025000},{0.381250,0.956250,0.050000,0.050000},{0.393750,0.956250,0.025000,0.025000},{0.393750,0.956250,0.050000,0.050000},{0.406250,0.956250,0.025000,0.025000},{0.406250,0.956250,0.050000,0.050000},{0.418750,0.956250,0.025000,0.025000},{0.418750,0.956250,0.050000,0.050000},{0.431250,0.956250,0.025000,0.025000},{0.431250,0.956250,0.050000,0.050000},{0.443750,0.956250,0.025000,0.025000},{0.443750,0.956250,0.050000,0.050000},{0.456250,0.956250,0.025000,0.025000},{0.456250,0.956250,0.050000,0.050000},{0.468750,0.956250,0.025000,0.025000},{0.468750,0.956250,0.050000,0.050000},{0.481250,0.956250,0.025000,0.025000},{0.481250,0.956250,0.050000,0.050000},{0.493750,0.956250,0.025000,0.025000},{0.493750,0.956250,0.050000,0.050000},{0.506250,0.956250,0.025000,0.025000},{0.506250,0.956250,0.050000,0.050000},{0.518750,0.956250,0.025000,0.025000},{0.518750,0.956250,0.050000,0.050000},{0.531250,0.956250,0.025000,0.025000},{0.531250,0.956250,0.050000,0.050000},{0.543750,0.956250,0.025000,0.025000},{0.543750,0.956250,0.050000,0.050000},{0.556250,0.956250,0.025000,0.025000},{0.556250,0.956250,0.050000,0.050000},{0.568750,0.956250,0.025000,0.025000},{0.568750,0.956250,0.050000,0.050000},{0.581250,0.956250,0.025000,0.025000},{0.581250,0.956250,0.050000,0.050000},{0.593750,0.956250,0.025000,0.025000},{0.593750,0.956250,0.050000,0.050000},{0.606250,0.956250,0.025000,0.025000},{0.606250,0.956250,0.050000,0.050000},{0.618750,0.956250,0.025000,0.025000},{0.618750,0.956250,0.050000,0.050000},{0.631250,0.956250,0.025000,0.025000},{0.631250,0.956250,0.050000,0.050000},{0.643750,0.956250,0.025000,0.025000},{0.643750,0.956250,0.050000,0.050000},{0.656250,0.956250,0.025000,0.025000},{0.656250,0.956250,0.050000,0.050000},{0.668750,0.956250,0.025000,0.025000},{0.668750,0.956250,0.050000,0.050000},{0.681250,0.956250,0.025000,0.025000},{0.681250,0.956250,0.050000,0.050000},{0.693750,0.956250,0.025000,0.025000},{0.693750,0.956250,0.050000,0.050000},{0.706250,0.956250,0.025000,0.025000},{0.706250,0.956250,0.050000,0.050000},{0.718750,0.956250,0.025000,0.025000},{0.718750,0.956250,0.050000,0.050000},{0.731250,0.956250,0.025000,0.025000},{0.731250,0.956250,0.050000,0.050000},{0.743750,0.956250,0.025000,0.025000},{0.743750,0.956250,0.050000,0.050000},{0.756250,0.956250,0.025000,0.025000},{0.756250,0.956250,0.050000,0.050000},{0.768750,0.956250,0.025000,0.025000},{0.768750,0.956250,0.050000,0.050000},{0.781250,0.956250,0.025000,0.025000},{0.781250,0.956250,0.050000,0.050000},{0.793750,0.956250,0.025000,0.025000},{0.793750,0.956250,0.050000,0.050000},{0.806250,0.956250,0.025000,0.025000},{0.806250,0.956250,0.050000,0.050000},{0.818750,0.956250,0.025000,0.025000},{0.818750,0.956250,0.050000,0.050000},{0.831250,0.956250,0.025000,0.025000},{0.831250,0.956250,0.050000,0.050000},{0.843750,0.956250,0.025000,0.025000},{0.843750,0.956250,0.050000,0.050000},{0.856250,0.956250,0.025000,0.025000},{0.856250,0.956250,0.050000,0.050000},{0.868750,0.956250,0.025000,0.025000},{0.868750,0.956250,0.050000,0.050000},{0.881250,0.956250,0.025000,0.025000},{0.881250,0.956250,0.050000,0.050000},{0.893750,0.956250,0.025000,0.025000},{0.893750,0.956250,0.050000,0.050000},{0.906250,0.956250,0.025000,0.025000},{0.906250,0.956250,0.050000,0.050000},{0.918750,0.956250,0.025000,0.025000},{0.918750,0.956250,0.050000,0.050000},{0.931250,0.956250,0.025000,0.025000},{0.931250,0.956250,0.050000,0.050000},{0.943750,0.956250,0.025000,0.025000},{0.943750,0.956250,0.050000,0.050000},{0.956250,0.956250,0.025000,0.025000},{0.956250,0.956250,0.050000,0.050000},{0.968750,0.956250,0.025000,0.025000},{0.968750,0.956250,0.050000,0.050000},{0.981250,0.956250,0.025000,0.025000},{0.981250,0.956250,0.050000,0.050000},{0.993750,0.956250,0.025000,0.025000},{0.993750,0.956250,0.050000,0.050000},{0.006250,0.968750,0.025000,0.025000},{0.006250,0.968750,0.050000,0.050000},{0.018750,0.968750,0.025000,0.025000},{0.018750,0.968750,0.050000,0.050000},{0.031250,0.968750,0.025000,0.025000},{0.031250,0.968750,0.050000,0.050000},{0.043750,0.968750,0.025000,0.025000},{0.043750,0.968750,0.050000,0.050000},{0.056250,0.968750,0.025000,0.025000},{0.056250,0.968750,0.050000,0.050000},{0.068750,0.968750,0.025000,0.025000},{0.068750,0.968750,0.050000,0.050000},{0.081250,0.968750,0.025000,0.025000},{0.081250,0.968750,0.050000,0.050000},{0.093750,0.968750,0.025000,0.025000},{0.093750,0.968750,0.050000,0.050000},{0.106250,0.968750,0.025000,0.025000},{0.106250,0.968750,0.050000,0.050000},{0.118750,0.968750,0.025000,0.025000},{0.118750,0.968750,0.050000,0.050000},{0.131250,0.968750,0.025000,0.025000},{0.131250,0.968750,0.050000,0.050000},{0.143750,0.968750,0.025000,0.025000},{0.143750,0.968750,0.050000,0.050000},{0.156250,0.968750,0.025000,0.025000},{0.156250,0.968750,0.050000,0.050000},{0.168750,0.968750,0.025000,0.025000},{0.168750,0.968750,0.050000,0.050000},{0.181250,0.968750,0.025000,0.025000},{0.181250,0.968750,0.050000,0.050000},{0.193750,0.968750,0.025000,0.025000},{0.193750,0.968750,0.050000,0.050000},{0.206250,0.968750,0.025000,0.025000},{0.206250,0.968750,0.050000,0.050000},{0.218750,0.968750,0.025000,0.025000},{0.218750,0.968750,0.050000,0.050000},{0.231250,0.968750,0.025000,0.025000},{0.231250,0.968750,0.050000,0.050000},{0.243750,0.968750,0.025000,0.025000},{0.243750,0.968750,0.050000,0.050000},{0.256250,0.968750,0.025000,0.025000},{0.256250,0.968750,0.050000,0.050000},{0.268750,0.968750,0.025000,0.025000},{0.268750,0.968750,0.050000,0.050000},{0.281250,0.968750,0.025000,0.025000},{0.281250,0.968750,0.050000,0.050000},{0.293750,0.968750,0.025000,0.025000},{0.293750,0.968750,0.050000,0.050000},{0.306250,0.968750,0.025000,0.025000},{0.306250,0.968750,0.050000,0.050000},{0.318750,0.968750,0.025000,0.025000},{0.318750,0.968750,0.050000,0.050000},{0.331250,0.968750,0.025000,0.025000},{0.331250,0.968750,0.050000,0.050000},{0.343750,0.968750,0.025000,0.025000},{0.343750,0.968750,0.050000,0.050000},{0.356250,0.968750,0.025000,0.025000},{0.356250,0.968750,0.050000,0.050000},{0.368750,0.968750,0.025000,0.025000},{0.368750,0.968750,0.050000,0.050000},{0.381250,0.968750,0.025000,0.025000},{0.381250,0.968750,0.050000,0.050000},{0.393750,0.968750,0.025000,0.025000},{0.393750,0.968750,0.050000,0.050000},{0.406250,0.968750,0.025000,0.025000},{0.406250,0.968750,0.050000,0.050000},{0.418750,0.968750,0.025000,0.025000},{0.418750,0.968750,0.050000,0.050000},{0.431250,0.968750,0.025000,0.025000},{0.431250,0.968750,0.050000,0.050000},{0.443750,0.968750,0.025000,0.025000},{0.443750,0.968750,0.050000,0.050000},{0.456250,0.968750,0.025000,0.025000},{0.456250,0.968750,0.050000,0.050000},{0.468750,0.968750,0.025000,0.025000},{0.468750,0.968750,0.050000,0.050000},{0.481250,0.968750,0.025000,0.025000},{0.481250,0.968750,0.050000,0.050000},{0.493750,0.968750,0.025000,0.025000},{0.493750,0.968750,0.050000,0.050000},{0.506250,0.968750,0.025000,0.025000},{0.506250,0.968750,0.050000,0.050000},{0.518750,0.968750,0.025000,0.025000},{0.518750,0.968750,0.050000,0.050000},{0.531250,0.968750,0.025000,0.025000},{0.531250,0.968750,0.050000,0.050000},{0.543750,0.968750,0.025000,0.025000},{0.543750,0.968750,0.050000,0.050000},{0.556250,0.968750,0.025000,0.025000},{0.556250,0.968750,0.050000,0.050000},{0.568750,0.968750,0.025000,0.025000},{0.568750,0.968750,0.050000,0.050000},{0.581250,0.968750,0.025000,0.025000},{0.581250,0.968750,0.050000,0.050000},{0.593750,0.968750,0.025000,0.025000},{0.593750,0.968750,0.050000,0.050000},{0.606250,0.968750,0.025000,0.025000},{0.606250,0.968750,0.050000,0.050000},{0.618750,0.968750,0.025000,0.025000},{0.618750,0.968750,0.050000,0.050000},{0.631250,0.968750,0.025000,0.025000},{0.631250,0.968750,0.050000,0.050000},{0.643750,0.968750,0.025000,0.025000},{0.643750,0.968750,0.050000,0.050000},{0.656250,0.968750,0.025000,0.025000},{0.656250,0.968750,0.050000,0.050000},{0.668750,0.968750,0.025000,0.025000},{0.668750,0.968750,0.050000,0.050000},{0.681250,0.968750,0.025000,0.025000},{0.681250,0.968750,0.050000,0.050000},{0.693750,0.968750,0.025000,0.025000},{0.693750,0.968750,0.050000,0.050000},{0.706250,0.968750,0.025000,0.025000},{0.706250,0.968750,0.050000,0.050000},{0.718750,0.968750,0.025000,0.025000},{0.718750,0.968750,0.050000,0.050000},{0.731250,0.968750,0.025000,0.025000},{0.731250,0.968750,0.050000,0.050000},{0.743750,0.968750,0.025000,0.025000},{0.743750,0.968750,0.050000,0.050000},{0.756250,0.968750,0.025000,0.025000},{0.756250,0.968750,0.050000,0.050000},{0.768750,0.968750,0.025000,0.025000},{0.768750,0.968750,0.050000,0.050000},{0.781250,0.968750,0.025000,0.025000},{0.781250,0.968750,0.050000,0.050000},{0.793750,0.968750,0.025000,0.025000},{0.793750,0.968750,0.050000,0.050000},{0.806250,0.968750,0.025000,0.025000},{0.806250,0.968750,0.050000,0.050000},{0.818750,0.968750,0.025000,0.025000},{0.818750,0.968750,0.050000,0.050000},{0.831250,0.968750,0.025000,0.025000},{0.831250,0.968750,0.050000,0.050000},{0.843750,0.968750,0.025000,0.025000},{0.843750,0.968750,0.050000,0.050000},{0.856250,0.968750,0.025000,0.025000},{0.856250,0.968750,0.050000,0.050000},{0.868750,0.968750,0.025000,0.025000},{0.868750,0.968750,0.050000,0.050000},{0.881250,0.968750,0.025000,0.025000},{0.881250,0.968750,0.050000,0.050000},{0.893750,0.968750,0.025000,0.025000},{0.893750,0.968750,0.050000,0.050000},{0.906250,0.968750,0.025000,0.025000},{0.906250,0.968750,0.050000,0.050000},{0.918750,0.968750,0.025000,0.025000},{0.918750,0.968750,0.050000,0.050000},{0.931250,0.968750,0.025000,0.025000},{0.931250,0.968750,0.050000,0.050000},{0.943750,0.968750,0.025000,0.025000},{0.943750,0.968750,0.050000,0.050000},{0.956250,0.968750,0.025000,0.025000},{0.956250,0.968750,0.050000,0.050000},{0.968750,0.968750,0.025000,0.025000},{0.968750,0.968750,0.050000,0.050000},{0.981250,0.968750,0.025000,0.025000},{0.981250,0.968750,0.050000,0.050000},{0.993750,0.968750,0.025000,0.025000},{0.993750,0.968750,0.050000,0.050000},{0.006250,0.981250,0.025000,0.025000},{0.006250,0.981250,0.050000,0.050000},{0.018750,0.981250,0.025000,0.025000},{0.018750,0.981250,0.050000,0.050000},{0.031250,0.981250,0.025000,0.025000},{0.031250,0.981250,0.050000,0.050000},{0.043750,0.981250,0.025000,0.025000},{0.043750,0.981250,0.050000,0.050000},{0.056250,0.981250,0.025000,0.025000},{0.056250,0.981250,0.050000,0.050000},{0.068750,0.981250,0.025000,0.025000},{0.068750,0.981250,0.050000,0.050000},{0.081250,0.981250,0.025000,0.025000},{0.081250,0.981250,0.050000,0.050000},{0.093750,0.981250,0.025000,0.025000},{0.093750,0.981250,0.050000,0.050000},{0.106250,0.981250,0.025000,0.025000},{0.106250,0.981250,0.050000,0.050000},{0.118750,0.981250,0.025000,0.025000},{0.118750,0.981250,0.050000,0.050000},{0.131250,0.981250,0.025000,0.025000},{0.131250,0.981250,0.050000,0.050000},{0.143750,0.981250,0.025000,0.025000},{0.143750,0.981250,0.050000,0.050000},{0.156250,0.981250,0.025000,0.025000},{0.156250,0.981250,0.050000,0.050000},{0.168750,0.981250,0.025000,0.025000},{0.168750,0.981250,0.050000,0.050000},{0.181250,0.981250,0.025000,0.025000},{0.181250,0.981250,0.050000,0.050000},{0.193750,0.981250,0.025000,0.025000},{0.193750,0.981250,0.050000,0.050000},{0.206250,0.981250,0.025000,0.025000},{0.206250,0.981250,0.050000,0.050000},{0.218750,0.981250,0.025000,0.025000},{0.218750,0.981250,0.050000,0.050000},{0.231250,0.981250,0.025000,0.025000},{0.231250,0.981250,0.050000,0.050000},{0.243750,0.981250,0.025000,0.025000},{0.243750,0.981250,0.050000,0.050000},{0.256250,0.981250,0.025000,0.025000},{0.256250,0.981250,0.050000,0.050000},{0.268750,0.981250,0.025000,0.025000},{0.268750,0.981250,0.050000,0.050000},{0.281250,0.981250,0.025000,0.025000},{0.281250,0.981250,0.050000,0.050000},{0.293750,0.981250,0.025000,0.025000},{0.293750,0.981250,0.050000,0.050000},{0.306250,0.981250,0.025000,0.025000},{0.306250,0.981250,0.050000,0.050000},{0.318750,0.981250,0.025000,0.025000},{0.318750,0.981250,0.050000,0.050000},{0.331250,0.981250,0.025000,0.025000},{0.331250,0.981250,0.050000,0.050000},{0.343750,0.981250,0.025000,0.025000},{0.343750,0.981250,0.050000,0.050000},{0.356250,0.981250,0.025000,0.025000},{0.356250,0.981250,0.050000,0.050000},{0.368750,0.981250,0.025000,0.025000},{0.368750,0.981250,0.050000,0.050000},{0.381250,0.981250,0.025000,0.025000},{0.381250,0.981250,0.050000,0.050000},{0.393750,0.981250,0.025000,0.025000},{0.393750,0.981250,0.050000,0.050000},{0.406250,0.981250,0.025000,0.025000},{0.406250,0.981250,0.050000,0.050000},{0.418750,0.981250,0.025000,0.025000},{0.418750,0.981250,0.050000,0.050000},{0.431250,0.981250,0.025000,0.025000},{0.431250,0.981250,0.050000,0.050000},{0.443750,0.981250,0.025000,0.025000},{0.443750,0.981250,0.050000,0.050000},{0.456250,0.981250,0.025000,0.025000},{0.456250,0.981250,0.050000,0.050000},{0.468750,0.981250,0.025000,0.025000},{0.468750,0.981250,0.050000,0.050000},{0.481250,0.981250,0.025000,0.025000},{0.481250,0.981250,0.050000,0.050000},{0.493750,0.981250,0.025000,0.025000},{0.493750,0.981250,0.050000,0.050000},{0.506250,0.981250,0.025000,0.025000},{0.506250,0.981250,0.050000,0.050000},{0.518750,0.981250,0.025000,0.025000},{0.518750,0.981250,0.050000,0.050000},{0.531250,0.981250,0.025000,0.025000},{0.531250,0.981250,0.050000,0.050000},{0.543750,0.981250,0.025000,0.025000},{0.543750,0.981250,0.050000,0.050000},{0.556250,0.981250,0.025000,0.025000},{0.556250,0.981250,0.050000,0.050000},{0.568750,0.981250,0.025000,0.025000},{0.568750,0.981250,0.050000,0.050000},{0.581250,0.981250,0.025000,0.025000},{0.581250,0.981250,0.050000,0.050000},{0.593750,0.981250,0.025000,0.025000},{0.593750,0.981250,0.050000,0.050000},{0.606250,0.981250,0.025000,0.025000},{0.606250,0.981250,0.050000,0.050000},{0.618750,0.981250,0.025000,0.025000},{0.618750,0.981250,0.050000,0.050000},{0.631250,0.981250,0.025000,0.025000},{0.631250,0.981250,0.050000,0.050000},{0.643750,0.981250,0.025000,0.025000},{0.643750,0.981250,0.050000,0.050000},{0.656250,0.981250,0.025000,0.025000},{0.656250,0.981250,0.050000,0.050000},{0.668750,0.981250,0.025000,0.025000},{0.668750,0.981250,0.050000,0.050000},{0.681250,0.981250,0.025000,0.025000},{0.681250,0.981250,0.050000,0.050000},{0.693750,0.981250,0.025000,0.025000},{0.693750,0.981250,0.050000,0.050000},{0.706250,0.981250,0.025000,0.025000},{0.706250,0.981250,0.050000,0.050000},{0.718750,0.981250,0.025000,0.025000},{0.718750,0.981250,0.050000,0.050000},{0.731250,0.981250,0.025000,0.025000},{0.731250,0.981250,0.050000,0.050000},{0.743750,0.981250,0.025000,0.025000},{0.743750,0.981250,0.050000,0.050000},{0.756250,0.981250,0.025000,0.025000},{0.756250,0.981250,0.050000,0.050000},{0.768750,0.981250,0.025000,0.025000},{0.768750,0.981250,0.050000,0.050000},{0.781250,0.981250,0.025000,0.025000},{0.781250,0.981250,0.050000,0.050000},{0.793750,0.981250,0.025000,0.025000},{0.793750,0.981250,0.050000,0.050000},{0.806250,0.981250,0.025000,0.025000},{0.806250,0.981250,0.050000,0.050000},{0.818750,0.981250,0.025000,0.025000},{0.818750,0.981250,0.050000,0.050000},{0.831250,0.981250,0.025000,0.025000},{0.831250,0.981250,0.050000,0.050000},{0.843750,0.981250,0.025000,0.025000},{0.843750,0.981250,0.050000,0.050000},{0.856250,0.981250,0.025000,0.025000},{0.856250,0.981250,0.050000,0.050000},{0.868750,0.981250,0.025000,0.025000},{0.868750,0.981250,0.050000,0.050000},{0.881250,0.981250,0.025000,0.025000},{0.881250,0.981250,0.050000,0.050000},{0.893750,0.981250,0.025000,0.025000},{0.893750,0.981250,0.050000,0.050000},{0.906250,0.981250,0.025000,0.025000},{0.906250,0.981250,0.050000,0.050000},{0.918750,0.981250,0.025000,0.025000},{0.918750,0.981250,0.050000,0.050000},{0.931250,0.981250,0.025000,0.025000},{0.931250,0.981250,0.050000,0.050000},{0.943750,0.981250,0.025000,0.025000},{0.943750,0.981250,0.050000,0.050000},{0.956250,0.981250,0.025000,0.025000},{0.956250,0.981250,0.050000,0.050000},{0.968750,0.981250,0.025000,0.025000},{0.968750,0.981250,0.050000,0.050000},{0.981250,0.981250,0.025000,0.025000},{0.981250,0.981250,0.050000,0.050000},{0.993750,0.981250,0.025000,0.025000},{0.993750,0.981250,0.050000,0.050000},{0.006250,0.993750,0.025000,0.025000},{0.006250,0.993750,0.050000,0.050000},{0.018750,0.993750,0.025000,0.025000},{0.018750,0.993750,0.050000,0.050000},{0.031250,0.993750,0.025000,0.025000},{0.031250,0.993750,0.050000,0.050000},{0.043750,0.993750,0.025000,0.025000},{0.043750,0.993750,0.050000,0.050000},{0.056250,0.993750,0.025000,0.025000},{0.056250,0.993750,0.050000,0.050000},{0.068750,0.993750,0.025000,0.025000},{0.068750,0.993750,0.050000,0.050000},{0.081250,0.993750,0.025000,0.025000},{0.081250,0.993750,0.050000,0.050000},{0.093750,0.993750,0.025000,0.025000},{0.093750,0.993750,0.050000,0.050000},{0.106250,0.993750,0.025000,0.025000},{0.106250,0.993750,0.050000,0.050000},{0.118750,0.993750,0.025000,0.025000},{0.118750,0.993750,0.050000,0.050000},{0.131250,0.993750,0.025000,0.025000},{0.131250,0.993750,0.050000,0.050000},{0.143750,0.993750,0.025000,0.025000},{0.143750,0.993750,0.050000,0.050000},{0.156250,0.993750,0.025000,0.025000},{0.156250,0.993750,0.050000,0.050000},{0.168750,0.993750,0.025000,0.025000},{0.168750,0.993750,0.050000,0.050000},{0.181250,0.993750,0.025000,0.025000},{0.181250,0.993750,0.050000,0.050000},{0.193750,0.993750,0.025000,0.025000},{0.193750,0.993750,0.050000,0.050000},{0.206250,0.993750,0.025000,0.025000},{0.206250,0.993750,0.050000,0.050000},{0.218750,0.993750,0.025000,0.025000},{0.218750,0.993750,0.050000,0.050000},{0.231250,0.993750,0.025000,0.025000},{0.231250,0.993750,0.050000,0.050000},{0.243750,0.993750,0.025000,0.025000},{0.243750,0.993750,0.050000,0.050000},{0.256250,0.993750,0.025000,0.025000},{0.256250,0.993750,0.050000,0.050000},{0.268750,0.993750,0.025000,0.025000},{0.268750,0.993750,0.050000,0.050000},{0.281250,0.993750,0.025000,0.025000},{0.281250,0.993750,0.050000,0.050000},{0.293750,0.993750,0.025000,0.025000},{0.293750,0.993750,0.050000,0.050000},{0.306250,0.993750,0.025000,0.025000},{0.306250,0.993750,0.050000,0.050000},{0.318750,0.993750,0.025000,0.025000},{0.318750,0.993750,0.050000,0.050000},{0.331250,0.993750,0.025000,0.025000},{0.331250,0.993750,0.050000,0.050000},{0.343750,0.993750,0.025000,0.025000},{0.343750,0.993750,0.050000,0.050000},{0.356250,0.993750,0.025000,0.025000},{0.356250,0.993750,0.050000,0.050000},{0.368750,0.993750,0.025000,0.025000},{0.368750,0.993750,0.050000,0.050000},{0.381250,0.993750,0.025000,0.025000},{0.381250,0.993750,0.050000,0.050000},{0.393750,0.993750,0.025000,0.025000},{0.393750,0.993750,0.050000,0.050000},{0.406250,0.993750,0.025000,0.025000},{0.406250,0.993750,0.050000,0.050000},{0.418750,0.993750,0.025000,0.025000},{0.418750,0.993750,0.050000,0.050000},{0.431250,0.993750,0.025000,0.025000},{0.431250,0.993750,0.050000,0.050000},{0.443750,0.993750,0.025000,0.025000},{0.443750,0.993750,0.050000,0.050000},{0.456250,0.993750,0.025000,0.025000},{0.456250,0.993750,0.050000,0.050000},{0.468750,0.993750,0.025000,0.025000},{0.468750,0.993750,0.050000,0.050000},{0.481250,0.993750,0.025000,0.025000},{0.481250,0.993750,0.050000,0.050000},{0.493750,0.993750,0.025000,0.025000},{0.493750,0.993750,0.050000,0.050000},{0.506250,0.993750,0.025000,0.025000},{0.506250,0.993750,0.050000,0.050000},{0.518750,0.993750,0.025000,0.025000},{0.518750,0.993750,0.050000,0.050000},{0.531250,0.993750,0.025000,0.025000},{0.531250,0.993750,0.050000,0.050000},{0.543750,0.993750,0.025000,0.025000},{0.543750,0.993750,0.050000,0.050000},{0.556250,0.993750,0.025000,0.025000},{0.556250,0.993750,0.050000,0.050000},{0.568750,0.993750,0.025000,0.025000},{0.568750,0.993750,0.050000,0.050000},{0.581250,0.993750,0.025000,0.025000},{0.581250,0.993750,0.050000,0.050000},{0.593750,0.993750,0.025000,0.025000},{0.593750,0.993750,0.050000,0.050000},{0.606250,0.993750,0.025000,0.025000},{0.606250,0.993750,0.050000,0.050000},{0.618750,0.993750,0.025000,0.025000},{0.618750,0.993750,0.050000,0.050000},{0.631250,0.993750,0.025000,0.025000},{0.631250,0.993750,0.050000,0.050000},{0.643750,0.993750,0.025000,0.025000},{0.643750,0.993750,0.050000,0.050000},{0.656250,0.993750,0.025000,0.025000},{0.656250,0.993750,0.050000,0.050000},{0.668750,0.993750,0.025000,0.025000},{0.668750,0.993750,0.050000,0.050000},{0.681250,0.993750,0.025000,0.025000},{0.681250,0.993750,0.050000,0.050000},{0.693750,0.993750,0.025000,0.025000},{0.693750,0.993750,0.050000,0.050000},{0.706250,0.993750,0.025000,0.025000},{0.706250,0.993750,0.050000,0.050000},{0.718750,0.993750,0.025000,0.025000},{0.718750,0.993750,0.050000,0.050000},{0.731250,0.993750,0.025000,0.025000},{0.731250,0.993750,0.050000,0.050000},{0.743750,0.993750,0.025000,0.025000},{0.743750,0.993750,0.050000,0.050000},{0.756250,0.993750,0.025000,0.025000},{0.756250,0.993750,0.050000,0.050000},{0.768750,0.993750,0.025000,0.025000},{0.768750,0.993750,0.050000,0.050000},{0.781250,0.993750,0.025000,0.025000},{0.781250,0.993750,0.050000,0.050000},{0.793750,0.993750,0.025000,0.025000},{0.793750,0.993750,0.050000,0.050000},{0.806250,0.993750,0.025000,0.025000},{0.806250,0.993750,0.050000,0.050000},{0.818750,0.993750,0.025000,0.025000},{0.818750,0.993750,0.050000,0.050000},{0.831250,0.993750,0.025000,0.025000},{0.831250,0.993750,0.050000,0.050000},{0.843750,0.993750,0.025000,0.025000},{0.843750,0.993750,0.050000,0.050000},{0.856250,0.993750,0.025000,0.025000},{0.856250,0.993750,0.050000,0.050000},{0.868750,0.993750,0.025000,0.025000},{0.868750,0.993750,0.050000,0.050000},{0.881250,0.993750,0.025000,0.025000},{0.881250,0.993750,0.050000,0.050000},{0.893750,0.993750,0.025000,0.025000},{0.893750,0.993750,0.050000,0.050000},{0.906250,0.993750,0.025000,0.025000},{0.906250,0.993750,0.050000,0.050000},{0.918750,0.993750,0.025000,0.025000},{0.918750,0.993750,0.050000,0.050000},{0.931250,0.993750,0.025000,0.025000},{0.931250,0.993750,0.050000,0.050000},{0.943750,0.993750,0.025000,0.025000},{0.943750,0.993750,0.050000,0.050000},{0.956250,0.993750,0.025000,0.025000},{0.956250,0.993750,0.050000,0.050000},{0.968750,0.993750,0.025000,0.025000},{0.968750,0.993750,0.050000,0.050000},{0.981250,0.993750,0.025000,0.025000},{0.981250,0.993750,0.050000,0.050000},{0.993750,0.993750,0.025000,0.025000},{0.993750,0.993750,0.050000,0.050000},{0.012500,0.012500,0.100000,0.100000},{0.012500,0.012500,0.200000,0.200000},{0.037500,0.012500,0.100000,0.100000},{0.037500,0.012500,0.200000,0.200000},{0.062500,0.012500,0.100000,0.100000},{0.062500,0.012500,0.200000,0.200000},{0.087500,0.012500,0.100000,0.100000},{0.087500,0.012500,0.200000,0.200000},{0.112500,0.012500,0.100000,0.100000},{0.112500,0.012500,0.200000,0.200000},{0.137500,0.012500,0.100000,0.100000},{0.137500,0.012500,0.200000,0.200000},{0.162500,0.012500,0.100000,0.100000},{0.162500,0.012500,0.200000,0.200000},{0.187500,0.012500,0.100000,0.100000},{0.187500,0.012500,0.200000,0.200000},{0.212500,0.012500,0.100000,0.100000},{0.212500,0.012500,0.200000,0.200000},{0.237500,0.012500,0.100000,0.100000},{0.237500,0.012500,0.200000,0.200000},{0.262500,0.012500,0.100000,0.100000},{0.262500,0.012500,0.200000,0.200000},{0.287500,0.012500,0.100000,0.100000},{0.287500,0.012500,0.200000,0.200000},{0.312500,0.012500,0.100000,0.100000},{0.312500,0.012500,0.200000,0.200000},{0.337500,0.012500,0.100000,0.100000},{0.337500,0.012500,0.200000,0.200000},{0.362500,0.012500,0.100000,0.100000},{0.362500,0.012500,0.200000,0.200000},{0.387500,0.012500,0.100000,0.100000},{0.387500,0.012500,0.200000,0.200000},{0.412500,0.012500,0.100000,0.100000},{0.412500,0.012500,0.200000,0.200000},{0.437500,0.012500,0.100000,0.100000},{0.437500,0.012500,0.200000,0.200000},{0.462500,0.012500,0.100000,0.100000},{0.462500,0.012500,0.200000,0.200000},{0.487500,0.012500,0.100000,0.100000},{0.487500,0.012500,0.200000,0.200000},{0.512500,0.012500,0.100000,0.100000},{0.512500,0.012500,0.200000,0.200000},{0.537500,0.012500,0.100000,0.100000},{0.537500,0.012500,0.200000,0.200000},{0.562500,0.012500,0.100000,0.100000},{0.562500,0.012500,0.200000,0.200000},{0.587500,0.012500,0.100000,0.100000},{0.587500,0.012500,0.200000,0.200000},{0.612500,0.012500,0.100000,0.100000},{0.612500,0.012500,0.200000,0.200000},{0.637500,0.012500,0.100000,0.100000},{0.637500,0.012500,0.200000,0.200000},{0.662500,0.012500,0.100000,0.100000},{0.662500,0.012500,0.200000,0.200000},{0.687500,0.012500,0.100000,0.100000},{0.687500,0.012500,0.200000,0.200000},{0.712500,0.012500,0.100000,0.100000},{0.712500,0.012500,0.200000,0.200000},{0.737500,0.012500,0.100000,0.100000},{0.737500,0.012500,0.200000,0.200000},{0.762500,0.012500,0.100000,0.100000},{0.762500,0.012500,0.200000,0.200000},{0.787500,0.012500,0.100000,0.100000},{0.787500,0.012500,0.200000,0.200000},{0.812500,0.012500,0.100000,0.100000},{0.812500,0.012500,0.200000,0.200000},{0.837500,0.012500,0.100000,0.100000},{0.837500,0.012500,0.200000,0.200000},{0.862500,0.012500,0.100000,0.100000},{0.862500,0.012500,0.200000,0.200000},{0.887500,0.012500,0.100000,0.100000},{0.887500,0.012500,0.200000,0.200000},{0.912500,0.012500,0.100000,0.100000},{0.912500,0.012500,0.200000,0.200000},{0.937500,0.012500,0.100000,0.100000},{0.937500,0.012500,0.200000,0.200000},{0.962500,0.012500,0.100000,0.100000},{0.962500,0.012500,0.200000,0.200000},{0.987500,0.012500,0.100000,0.100000},{0.987500,0.012500,0.200000,0.200000},{0.012500,0.037500,0.100000,0.100000},{0.012500,0.037500,0.200000,0.200000},{0.037500,0.037500,0.100000,0.100000},{0.037500,0.037500,0.200000,0.200000},{0.062500,0.037500,0.100000,0.100000},{0.062500,0.037500,0.200000,0.200000},{0.087500,0.037500,0.100000,0.100000},{0.087500,0.037500,0.200000,0.200000},{0.112500,0.037500,0.100000,0.100000},{0.112500,0.037500,0.200000,0.200000},{0.137500,0.037500,0.100000,0.100000},{0.137500,0.037500,0.200000,0.200000},{0.162500,0.037500,0.100000,0.100000},{0.162500,0.037500,0.200000,0.200000},{0.187500,0.037500,0.100000,0.100000},{0.187500,0.037500,0.200000,0.200000},{0.212500,0.037500,0.100000,0.100000},{0.212500,0.037500,0.200000,0.200000},{0.237500,0.037500,0.100000,0.100000},{0.237500,0.037500,0.200000,0.200000},{0.262500,0.037500,0.100000,0.100000},{0.262500,0.037500,0.200000,0.200000},{0.287500,0.037500,0.100000,0.100000},{0.287500,0.037500,0.200000,0.200000},{0.312500,0.037500,0.100000,0.100000},{0.312500,0.037500,0.200000,0.200000},{0.337500,0.037500,0.100000,0.100000},{0.337500,0.037500,0.200000,0.200000},{0.362500,0.037500,0.100000,0.100000},{0.362500,0.037500,0.200000,0.200000},{0.387500,0.037500,0.100000,0.100000},{0.387500,0.037500,0.200000,0.200000},{0.412500,0.037500,0.100000,0.100000},{0.412500,0.037500,0.200000,0.200000},{0.437500,0.037500,0.100000,0.100000},{0.437500,0.037500,0.200000,0.200000},{0.462500,0.037500,0.100000,0.100000},{0.462500,0.037500,0.200000,0.200000},{0.487500,0.037500,0.100000,0.100000},{0.487500,0.037500,0.200000,0.200000},{0.512500,0.037500,0.100000,0.100000},{0.512500,0.037500,0.200000,0.200000},{0.537500,0.037500,0.100000,0.100000},{0.537500,0.037500,0.200000,0.200000},{0.562500,0.037500,0.100000,0.100000},{0.562500,0.037500,0.200000,0.200000},{0.587500,0.037500,0.100000,0.100000},{0.587500,0.037500,0.200000,0.200000},{0.612500,0.037500,0.100000,0.100000},{0.612500,0.037500,0.200000,0.200000},{0.637500,0.037500,0.100000,0.100000},{0.637500,0.037500,0.200000,0.200000},{0.662500,0.037500,0.100000,0.100000},{0.662500,0.037500,0.200000,0.200000},{0.687500,0.037500,0.100000,0.100000},{0.687500,0.037500,0.200000,0.200000},{0.712500,0.037500,0.100000,0.100000},{0.712500,0.037500,0.200000,0.200000},{0.737500,0.037500,0.100000,0.100000},{0.737500,0.037500,0.200000,0.200000},{0.762500,0.037500,0.100000,0.100000},{0.762500,0.037500,0.200000,0.200000},{0.787500,0.037500,0.100000,0.100000},{0.787500,0.037500,0.200000,0.200000},{0.812500,0.037500,0.100000,0.100000},{0.812500,0.037500,0.200000,0.200000},{0.837500,0.037500,0.100000,0.100000},{0.837500,0.037500,0.200000,0.200000},{0.862500,0.037500,0.100000,0.100000},{0.862500,0.037500,0.200000,0.200000},{0.887500,0.037500,0.100000,0.100000},{0.887500,0.037500,0.200000,0.200000},{0.912500,0.037500,0.100000,0.100000},{0.912500,0.037500,0.200000,0.200000},{0.937500,0.037500,0.100000,0.100000},{0.937500,0.037500,0.200000,0.200000},{0.962500,0.037500,0.100000,0.100000},{0.962500,0.037500,0.200000,0.200000},{0.987500,0.037500,0.100000,0.100000},{0.987500,0.037500,0.200000,0.200000},{0.012500,0.062500,0.100000,0.100000},{0.012500,0.062500,0.200000,0.200000},{0.037500,0.062500,0.100000,0.100000},{0.037500,0.062500,0.200000,0.200000},{0.062500,0.062500,0.100000,0.100000},{0.062500,0.062500,0.200000,0.200000},{0.087500,0.062500,0.100000,0.100000},{0.087500,0.062500,0.200000,0.200000},{0.112500,0.062500,0.100000,0.100000},{0.112500,0.062500,0.200000,0.200000},{0.137500,0.062500,0.100000,0.100000},{0.137500,0.062500,0.200000,0.200000},{0.162500,0.062500,0.100000,0.100000},{0.162500,0.062500,0.200000,0.200000},{0.187500,0.062500,0.100000,0.100000},{0.187500,0.062500,0.200000,0.200000},{0.212500,0.062500,0.100000,0.100000},{0.212500,0.062500,0.200000,0.200000},{0.237500,0.062500,0.100000,0.100000},{0.237500,0.062500,0.200000,0.200000},{0.262500,0.062500,0.100000,0.100000},{0.262500,0.062500,0.200000,0.200000},{0.287500,0.062500,0.100000,0.100000},{0.287500,0.062500,0.200000,0.200000},{0.312500,0.062500,0.100000,0.100000},{0.312500,0.062500,0.200000,0.200000},{0.337500,0.062500,0.100000,0.100000},{0.337500,0.062500,0.200000,0.200000},{0.362500,0.062500,0.100000,0.100000},{0.362500,0.062500,0.200000,0.200000},{0.387500,0.062500,0.100000,0.100000},{0.387500,0.062500,0.200000,0.200000},{0.412500,0.062500,0.100000,0.100000},{0.412500,0.062500,0.200000,0.200000},{0.437500,0.062500,0.100000,0.100000},{0.437500,0.062500,0.200000,0.200000},{0.462500,0.062500,0.100000,0.100000},{0.462500,0.062500,0.200000,0.200000},{0.487500,0.062500,0.100000,0.100000},{0.487500,0.062500,0.200000,0.200000},{0.512500,0.062500,0.100000,0.100000},{0.512500,0.062500,0.200000,0.200000},{0.537500,0.062500,0.100000,0.100000},{0.537500,0.062500,0.200000,0.200000},{0.562500,0.062500,0.100000,0.100000},{0.562500,0.062500,0.200000,0.200000},{0.587500,0.062500,0.100000,0.100000},{0.587500,0.062500,0.200000,0.200000},{0.612500,0.062500,0.100000,0.100000},{0.612500,0.062500,0.200000,0.200000},{0.637500,0.062500,0.100000,0.100000},{0.637500,0.062500,0.200000,0.200000},{0.662500,0.062500,0.100000,0.100000},{0.662500,0.062500,0.200000,0.200000},{0.687500,0.062500,0.100000,0.100000},{0.687500,0.062500,0.200000,0.200000},{0.712500,0.062500,0.100000,0.100000},{0.712500,0.062500,0.200000,0.200000},{0.737500,0.062500,0.100000,0.100000},{0.737500,0.062500,0.200000,0.200000},{0.762500,0.062500,0.100000,0.100000},{0.762500,0.062500,0.200000,0.200000},{0.787500,0.062500,0.100000,0.100000},{0.787500,0.062500,0.200000,0.200000},{0.812500,0.062500,0.100000,0.100000},{0.812500,0.062500,0.200000,0.200000},{0.837500,0.062500,0.100000,0.100000},{0.837500,0.062500,0.200000,0.200000},{0.862500,0.062500,0.100000,0.100000},{0.862500,0.062500,0.200000,0.200000},{0.887500,0.062500,0.100000,0.100000},{0.887500,0.062500,0.200000,0.200000},{0.912500,0.062500,0.100000,0.100000},{0.912500,0.062500,0.200000,0.200000},{0.937500,0.062500,0.100000,0.100000},{0.937500,0.062500,0.200000,0.200000},{0.962500,0.062500,0.100000,0.100000},{0.962500,0.062500,0.200000,0.200000},{0.987500,0.062500,0.100000,0.100000},{0.987500,0.062500,0.200000,0.200000},{0.012500,0.087500,0.100000,0.100000},{0.012500,0.087500,0.200000,0.200000},{0.037500,0.087500,0.100000,0.100000},{0.037500,0.087500,0.200000,0.200000},{0.062500,0.087500,0.100000,0.100000},{0.062500,0.087500,0.200000,0.200000},{0.087500,0.087500,0.100000,0.100000},{0.087500,0.087500,0.200000,0.200000},{0.112500,0.087500,0.100000,0.100000},{0.112500,0.087500,0.200000,0.200000},{0.137500,0.087500,0.100000,0.100000},{0.137500,0.087500,0.200000,0.200000},{0.162500,0.087500,0.100000,0.100000},{0.162500,0.087500,0.200000,0.200000},{0.187500,0.087500,0.100000,0.100000},{0.187500,0.087500,0.200000,0.200000},{0.212500,0.087500,0.100000,0.100000},{0.212500,0.087500,0.200000,0.200000},{0.237500,0.087500,0.100000,0.100000},{0.237500,0.087500,0.200000,0.200000},{0.262500,0.087500,0.100000,0.100000},{0.262500,0.087500,0.200000,0.200000},{0.287500,0.087500,0.100000,0.100000},{0.287500,0.087500,0.200000,0.200000},{0.312500,0.087500,0.100000,0.100000},{0.312500,0.087500,0.200000,0.200000},{0.337500,0.087500,0.100000,0.100000},{0.337500,0.087500,0.200000,0.200000},{0.362500,0.087500,0.100000,0.100000},{0.362500,0.087500,0.200000,0.200000},{0.387500,0.087500,0.100000,0.100000},{0.387500,0.087500,0.200000,0.200000},{0.412500,0.087500,0.100000,0.100000},{0.412500,0.087500,0.200000,0.200000},{0.437500,0.087500,0.100000,0.100000},{0.437500,0.087500,0.200000,0.200000},{0.462500,0.087500,0.100000,0.100000},{0.462500,0.087500,0.200000,0.200000},{0.487500,0.087500,0.100000,0.100000},{0.487500,0.087500,0.200000,0.200000},{0.512500,0.087500,0.100000,0.100000},{0.512500,0.087500,0.200000,0.200000},{0.537500,0.087500,0.100000,0.100000},{0.537500,0.087500,0.200000,0.200000},{0.562500,0.087500,0.100000,0.100000},{0.562500,0.087500,0.200000,0.200000},{0.587500,0.087500,0.100000,0.100000},{0.587500,0.087500,0.200000,0.200000},{0.612500,0.087500,0.100000,0.100000},{0.612500,0.087500,0.200000,0.200000},{0.637500,0.087500,0.100000,0.100000},{0.637500,0.087500,0.200000,0.200000},{0.662500,0.087500,0.100000,0.100000},{0.662500,0.087500,0.200000,0.200000},{0.687500,0.087500,0.100000,0.100000},{0.687500,0.087500,0.200000,0.200000},{0.712500,0.087500,0.100000,0.100000},{0.712500,0.087500,0.200000,0.200000},{0.737500,0.087500,0.100000,0.100000},{0.737500,0.087500,0.200000,0.200000},{0.762500,0.087500,0.100000,0.100000},{0.762500,0.087500,0.200000,0.200000},{0.787500,0.087500,0.100000,0.100000},{0.787500,0.087500,0.200000,0.200000},{0.812500,0.087500,0.100000,0.100000},{0.812500,0.087500,0.200000,0.200000},{0.837500,0.087500,0.100000,0.100000},{0.837500,0.087500,0.200000,0.200000},{0.862500,0.087500,0.100000,0.100000},{0.862500,0.087500,0.200000,0.200000},{0.887500,0.087500,0.100000,0.100000},{0.887500,0.087500,0.200000,0.200000},{0.912500,0.087500,0.100000,0.100000},{0.912500,0.087500,0.200000,0.200000},{0.937500,0.087500,0.100000,0.100000},{0.937500,0.087500,0.200000,0.200000},{0.962500,0.087500,0.100000,0.100000},{0.962500,0.087500,0.200000,0.200000},{0.987500,0.087500,0.100000,0.100000},{0.987500,0.087500,0.200000,0.200000},{0.012500,0.112500,0.100000,0.100000},{0.012500,0.112500,0.200000,0.200000},{0.037500,0.112500,0.100000,0.100000},{0.037500,0.112500,0.200000,0.200000},{0.062500,0.112500,0.100000,0.100000},{0.062500,0.112500,0.200000,0.200000},{0.087500,0.112500,0.100000,0.100000},{0.087500,0.112500,0.200000,0.200000},{0.112500,0.112500,0.100000,0.100000},{0.112500,0.112500,0.200000,0.200000},{0.137500,0.112500,0.100000,0.100000},{0.137500,0.112500,0.200000,0.200000},{0.162500,0.112500,0.100000,0.100000},{0.162500,0.112500,0.200000,0.200000},{0.187500,0.112500,0.100000,0.100000},{0.187500,0.112500,0.200000,0.200000},{0.212500,0.112500,0.100000,0.100000},{0.212500,0.112500,0.200000,0.200000},{0.237500,0.112500,0.100000,0.100000},{0.237500,0.112500,0.200000,0.200000},{0.262500,0.112500,0.100000,0.100000},{0.262500,0.112500,0.200000,0.200000},{0.287500,0.112500,0.100000,0.100000},{0.287500,0.112500,0.200000,0.200000},{0.312500,0.112500,0.100000,0.100000},{0.312500,0.112500,0.200000,0.200000},{0.337500,0.112500,0.100000,0.100000},{0.337500,0.112500,0.200000,0.200000},{0.362500,0.112500,0.100000,0.100000},{0.362500,0.112500,0.200000,0.200000},{0.387500,0.112500,0.100000,0.100000},{0.387500,0.112500,0.200000,0.200000},{0.412500,0.112500,0.100000,0.100000},{0.412500,0.112500,0.200000,0.200000},{0.437500,0.112500,0.100000,0.100000},{0.437500,0.112500,0.200000,0.200000},{0.462500,0.112500,0.100000,0.100000},{0.462500,0.112500,0.200000,0.200000},{0.487500,0.112500,0.100000,0.100000},{0.487500,0.112500,0.200000,0.200000},{0.512500,0.112500,0.100000,0.100000},{0.512500,0.112500,0.200000,0.200000},{0.537500,0.112500,0.100000,0.100000},{0.537500,0.112500,0.200000,0.200000},{0.562500,0.112500,0.100000,0.100000},{0.562500,0.112500,0.200000,0.200000},{0.587500,0.112500,0.100000,0.100000},{0.587500,0.112500,0.200000,0.200000},{0.612500,0.112500,0.100000,0.100000},{0.612500,0.112500,0.200000,0.200000},{0.637500,0.112500,0.100000,0.100000},{0.637500,0.112500,0.200000,0.200000},{0.662500,0.112500,0.100000,0.100000},{0.662500,0.112500,0.200000,0.200000},{0.687500,0.112500,0.100000,0.100000},{0.687500,0.112500,0.200000,0.200000},{0.712500,0.112500,0.100000,0.100000},{0.712500,0.112500,0.200000,0.200000},{0.737500,0.112500,0.100000,0.100000},{0.737500,0.112500,0.200000,0.200000},{0.762500,0.112500,0.100000,0.100000},{0.762500,0.112500,0.200000,0.200000},{0.787500,0.112500,0.100000,0.100000},{0.787500,0.112500,0.200000,0.200000},{0.812500,0.112500,0.100000,0.100000},{0.812500,0.112500,0.200000,0.200000},{0.837500,0.112500,0.100000,0.100000},{0.837500,0.112500,0.200000,0.200000},{0.862500,0.112500,0.100000,0.100000},{0.862500,0.112500,0.200000,0.200000},{0.887500,0.112500,0.100000,0.100000},{0.887500,0.112500,0.200000,0.200000},{0.912500,0.112500,0.100000,0.100000},{0.912500,0.112500,0.200000,0.200000},{0.937500,0.112500,0.100000,0.100000},{0.937500,0.112500,0.200000,0.200000},{0.962500,0.112500,0.100000,0.100000},{0.962500,0.112500,0.200000,0.200000},{0.987500,0.112500,0.100000,0.100000},{0.987500,0.112500,0.200000,0.200000},{0.012500,0.137500,0.100000,0.100000},{0.012500,0.137500,0.200000,0.200000},{0.037500,0.137500,0.100000,0.100000},{0.037500,0.137500,0.200000,0.200000},{0.062500,0.137500,0.100000,0.100000},{0.062500,0.137500,0.200000,0.200000},{0.087500,0.137500,0.100000,0.100000},{0.087500,0.137500,0.200000,0.200000},{0.112500,0.137500,0.100000,0.100000},{0.112500,0.137500,0.200000,0.200000},{0.137500,0.137500,0.100000,0.100000},{0.137500,0.137500,0.200000,0.200000},{0.162500,0.137500,0.100000,0.100000},{0.162500,0.137500,0.200000,0.200000},{0.187500,0.137500,0.100000,0.100000},{0.187500,0.137500,0.200000,0.200000},{0.212500,0.137500,0.100000,0.100000},{0.212500,0.137500,0.200000,0.200000},{0.237500,0.137500,0.100000,0.100000},{0.237500,0.137500,0.200000,0.200000},{0.262500,0.137500,0.100000,0.100000},{0.262500,0.137500,0.200000,0.200000},{0.287500,0.137500,0.100000,0.100000},{0.287500,0.137500,0.200000,0.200000},{0.312500,0.137500,0.100000,0.100000},{0.312500,0.137500,0.200000,0.200000},{0.337500,0.137500,0.100000,0.100000},{0.337500,0.137500,0.200000,0.200000},{0.362500,0.137500,0.100000,0.100000},{0.362500,0.137500,0.200000,0.200000},{0.387500,0.137500,0.100000,0.100000},{0.387500,0.137500,0.200000,0.200000},{0.412500,0.137500,0.100000,0.100000},{0.412500,0.137500,0.200000,0.200000},{0.437500,0.137500,0.100000,0.100000},{0.437500,0.137500,0.200000,0.200000},{0.462500,0.137500,0.100000,0.100000},{0.462500,0.137500,0.200000,0.200000},{0.487500,0.137500,0.100000,0.100000},{0.487500,0.137500,0.200000,0.200000},{0.512500,0.137500,0.100000,0.100000},{0.512500,0.137500,0.200000,0.200000},{0.537500,0.137500,0.100000,0.100000},{0.537500,0.137500,0.200000,0.200000},{0.562500,0.137500,0.100000,0.100000},{0.562500,0.137500,0.200000,0.200000},{0.587500,0.137500,0.100000,0.100000},{0.587500,0.137500,0.200000,0.200000},{0.612500,0.137500,0.100000,0.100000},{0.612500,0.137500,0.200000,0.200000},{0.637500,0.137500,0.100000,0.100000},{0.637500,0.137500,0.200000,0.200000},{0.662500,0.137500,0.100000,0.100000},{0.662500,0.137500,0.200000,0.200000},{0.687500,0.137500,0.100000,0.100000},{0.687500,0.137500,0.200000,0.200000},{0.712500,0.137500,0.100000,0.100000},{0.712500,0.137500,0.200000,0.200000},{0.737500,0.137500,0.100000,0.100000},{0.737500,0.137500,0.200000,0.200000},{0.762500,0.137500,0.100000,0.100000},{0.762500,0.137500,0.200000,0.200000},{0.787500,0.137500,0.100000,0.100000},{0.787500,0.137500,0.200000,0.200000},{0.812500,0.137500,0.100000,0.100000},{0.812500,0.137500,0.200000,0.200000},{0.837500,0.137500,0.100000,0.100000},{0.837500,0.137500,0.200000,0.200000},{0.862500,0.137500,0.100000,0.100000},{0.862500,0.137500,0.200000,0.200000},{0.887500,0.137500,0.100000,0.100000},{0.887500,0.137500,0.200000,0.200000},{0.912500,0.137500,0.100000,0.100000},{0.912500,0.137500,0.200000,0.200000},{0.937500,0.137500,0.100000,0.100000},{0.937500,0.137500,0.200000,0.200000},{0.962500,0.137500,0.100000,0.100000},{0.962500,0.137500,0.200000,0.200000},{0.987500,0.137500,0.100000,0.100000},{0.987500,0.137500,0.200000,0.200000},{0.012500,0.162500,0.100000,0.100000},{0.012500,0.162500,0.200000,0.200000},{0.037500,0.162500,0.100000,0.100000},{0.037500,0.162500,0.200000,0.200000},{0.062500,0.162500,0.100000,0.100000},{0.062500,0.162500,0.200000,0.200000},{0.087500,0.162500,0.100000,0.100000},{0.087500,0.162500,0.200000,0.200000},{0.112500,0.162500,0.100000,0.100000},{0.112500,0.162500,0.200000,0.200000},{0.137500,0.162500,0.100000,0.100000},{0.137500,0.162500,0.200000,0.200000},{0.162500,0.162500,0.100000,0.100000},{0.162500,0.162500,0.200000,0.200000},{0.187500,0.162500,0.100000,0.100000},{0.187500,0.162500,0.200000,0.200000},{0.212500,0.162500,0.100000,0.100000},{0.212500,0.162500,0.200000,0.200000},{0.237500,0.162500,0.100000,0.100000},{0.237500,0.162500,0.200000,0.200000},{0.262500,0.162500,0.100000,0.100000},{0.262500,0.162500,0.200000,0.200000},{0.287500,0.162500,0.100000,0.100000},{0.287500,0.162500,0.200000,0.200000},{0.312500,0.162500,0.100000,0.100000},{0.312500,0.162500,0.200000,0.200000},{0.337500,0.162500,0.100000,0.100000},{0.337500,0.162500,0.200000,0.200000},{0.362500,0.162500,0.100000,0.100000},{0.362500,0.162500,0.200000,0.200000},{0.387500,0.162500,0.100000,0.100000},{0.387500,0.162500,0.200000,0.200000},{0.412500,0.162500,0.100000,0.100000},{0.412500,0.162500,0.200000,0.200000},{0.437500,0.162500,0.100000,0.100000},{0.437500,0.162500,0.200000,0.200000},{0.462500,0.162500,0.100000,0.100000},{0.462500,0.162500,0.200000,0.200000},{0.487500,0.162500,0.100000,0.100000},{0.487500,0.162500,0.200000,0.200000},{0.512500,0.162500,0.100000,0.100000},{0.512500,0.162500,0.200000,0.200000},{0.537500,0.162500,0.100000,0.100000},{0.537500,0.162500,0.200000,0.200000},{0.562500,0.162500,0.100000,0.100000},{0.562500,0.162500,0.200000,0.200000},{0.587500,0.162500,0.100000,0.100000},{0.587500,0.162500,0.200000,0.200000},{0.612500,0.162500,0.100000,0.100000},{0.612500,0.162500,0.200000,0.200000},{0.637500,0.162500,0.100000,0.100000},{0.637500,0.162500,0.200000,0.200000},{0.662500,0.162500,0.100000,0.100000},{0.662500,0.162500,0.200000,0.200000},{0.687500,0.162500,0.100000,0.100000},{0.687500,0.162500,0.200000,0.200000},{0.712500,0.162500,0.100000,0.100000},{0.712500,0.162500,0.200000,0.200000},{0.737500,0.162500,0.100000,0.100000},{0.737500,0.162500,0.200000,0.200000},{0.762500,0.162500,0.100000,0.100000},{0.762500,0.162500,0.200000,0.200000},{0.787500,0.162500,0.100000,0.100000},{0.787500,0.162500,0.200000,0.200000},{0.812500,0.162500,0.100000,0.100000},{0.812500,0.162500,0.200000,0.200000},{0.837500,0.162500,0.100000,0.100000},{0.837500,0.162500,0.200000,0.200000},{0.862500,0.162500,0.100000,0.100000},{0.862500,0.162500,0.200000,0.200000},{0.887500,0.162500,0.100000,0.100000},{0.887500,0.162500,0.200000,0.200000},{0.912500,0.162500,0.100000,0.100000},{0.912500,0.162500,0.200000,0.200000},{0.937500,0.162500,0.100000,0.100000},{0.937500,0.162500,0.200000,0.200000},{0.962500,0.162500,0.100000,0.100000},{0.962500,0.162500,0.200000,0.200000},{0.987500,0.162500,0.100000,0.100000},{0.987500,0.162500,0.200000,0.200000},{0.012500,0.187500,0.100000,0.100000},{0.012500,0.187500,0.200000,0.200000},{0.037500,0.187500,0.100000,0.100000},{0.037500,0.187500,0.200000,0.200000},{0.062500,0.187500,0.100000,0.100000},{0.062500,0.187500,0.200000,0.200000},{0.087500,0.187500,0.100000,0.100000},{0.087500,0.187500,0.200000,0.200000},{0.112500,0.187500,0.100000,0.100000},{0.112500,0.187500,0.200000,0.200000},{0.137500,0.187500,0.100000,0.100000},{0.137500,0.187500,0.200000,0.200000},{0.162500,0.187500,0.100000,0.100000},{0.162500,0.187500,0.200000,0.200000},{0.187500,0.187500,0.100000,0.100000},{0.187500,0.187500,0.200000,0.200000},{0.212500,0.187500,0.100000,0.100000},{0.212500,0.187500,0.200000,0.200000},{0.237500,0.187500,0.100000,0.100000},{0.237500,0.187500,0.200000,0.200000},{0.262500,0.187500,0.100000,0.100000},{0.262500,0.187500,0.200000,0.200000},{0.287500,0.187500,0.100000,0.100000},{0.287500,0.187500,0.200000,0.200000},{0.312500,0.187500,0.100000,0.100000},{0.312500,0.187500,0.200000,0.200000},{0.337500,0.187500,0.100000,0.100000},{0.337500,0.187500,0.200000,0.200000},{0.362500,0.187500,0.100000,0.100000},{0.362500,0.187500,0.200000,0.200000},{0.387500,0.187500,0.100000,0.100000},{0.387500,0.187500,0.200000,0.200000},{0.412500,0.187500,0.100000,0.100000},{0.412500,0.187500,0.200000,0.200000},{0.437500,0.187500,0.100000,0.100000},{0.437500,0.187500,0.200000,0.200000},{0.462500,0.187500,0.100000,0.100000},{0.462500,0.187500,0.200000,0.200000},{0.487500,0.187500,0.100000,0.100000},{0.487500,0.187500,0.200000,0.200000},{0.512500,0.187500,0.100000,0.100000},{0.512500,0.187500,0.200000,0.200000},{0.537500,0.187500,0.100000,0.100000},{0.537500,0.187500,0.200000,0.200000},{0.562500,0.187500,0.100000,0.100000},{0.562500,0.187500,0.200000,0.200000},{0.587500,0.187500,0.100000,0.100000},{0.587500,0.187500,0.200000,0.200000},{0.612500,0.187500,0.100000,0.100000},{0.612500,0.187500,0.200000,0.200000},{0.637500,0.187500,0.100000,0.100000},{0.637500,0.187500,0.200000,0.200000},{0.662500,0.187500,0.100000,0.100000},{0.662500,0.187500,0.200000,0.200000},{0.687500,0.187500,0.100000,0.100000},{0.687500,0.187500,0.200000,0.200000},{0.712500,0.187500,0.100000,0.100000},{0.712500,0.187500,0.200000,0.200000},{0.737500,0.187500,0.100000,0.100000},{0.737500,0.187500,0.200000,0.200000},{0.762500,0.187500,0.100000,0.100000},{0.762500,0.187500,0.200000,0.200000},{0.787500,0.187500,0.100000,0.100000},{0.787500,0.187500,0.200000,0.200000},{0.812500,0.187500,0.100000,0.100000},{0.812500,0.187500,0.200000,0.200000},{0.837500,0.187500,0.100000,0.100000},{0.837500,0.187500,0.200000,0.200000},{0.862500,0.187500,0.100000,0.100000},{0.862500,0.187500,0.200000,0.200000},{0.887500,0.187500,0.100000,0.100000},{0.887500,0.187500,0.200000,0.200000},{0.912500,0.187500,0.100000,0.100000},{0.912500,0.187500,0.200000,0.200000},{0.937500,0.187500,0.100000,0.100000},{0.937500,0.187500,0.200000,0.200000},{0.962500,0.187500,0.100000,0.100000},{0.962500,0.187500,0.200000,0.200000},{0.987500,0.187500,0.100000,0.100000},{0.987500,0.187500,0.200000,0.200000},{0.012500,0.212500,0.100000,0.100000},{0.012500,0.212500,0.200000,0.200000},{0.037500,0.212500,0.100000,0.100000},{0.037500,0.212500,0.200000,0.200000},{0.062500,0.212500,0.100000,0.100000},{0.062500,0.212500,0.200000,0.200000},{0.087500,0.212500,0.100000,0.100000},{0.087500,0.212500,0.200000,0.200000},{0.112500,0.212500,0.100000,0.100000},{0.112500,0.212500,0.200000,0.200000},{0.137500,0.212500,0.100000,0.100000},{0.137500,0.212500,0.200000,0.200000},{0.162500,0.212500,0.100000,0.100000},{0.162500,0.212500,0.200000,0.200000},{0.187500,0.212500,0.100000,0.100000},{0.187500,0.212500,0.200000,0.200000},{0.212500,0.212500,0.100000,0.100000},{0.212500,0.212500,0.200000,0.200000},{0.237500,0.212500,0.100000,0.100000},{0.237500,0.212500,0.200000,0.200000},{0.262500,0.212500,0.100000,0.100000},{0.262500,0.212500,0.200000,0.200000},{0.287500,0.212500,0.100000,0.100000},{0.287500,0.212500,0.200000,0.200000},{0.312500,0.212500,0.100000,0.100000},{0.312500,0.212500,0.200000,0.200000},{0.337500,0.212500,0.100000,0.100000},{0.337500,0.212500,0.200000,0.200000},{0.362500,0.212500,0.100000,0.100000},{0.362500,0.212500,0.200000,0.200000},{0.387500,0.212500,0.100000,0.100000},{0.387500,0.212500,0.200000,0.200000},{0.412500,0.212500,0.100000,0.100000},{0.412500,0.212500,0.200000,0.200000},{0.437500,0.212500,0.100000,0.100000},{0.437500,0.212500,0.200000,0.200000},{0.462500,0.212500,0.100000,0.100000},{0.462500,0.212500,0.200000,0.200000},{0.487500,0.212500,0.100000,0.100000},{0.487500,0.212500,0.200000,0.200000},{0.512500,0.212500,0.100000,0.100000},{0.512500,0.212500,0.200000,0.200000},{0.537500,0.212500,0.100000,0.100000},{0.537500,0.212500,0.200000,0.200000},{0.562500,0.212500,0.100000,0.100000},{0.562500,0.212500,0.200000,0.200000},{0.587500,0.212500,0.100000,0.100000},{0.587500,0.212500,0.200000,0.200000},{0.612500,0.212500,0.100000,0.100000},{0.612500,0.212500,0.200000,0.200000},{0.637500,0.212500,0.100000,0.100000},{0.637500,0.212500,0.200000,0.200000},{0.662500,0.212500,0.100000,0.100000},{0.662500,0.212500,0.200000,0.200000},{0.687500,0.212500,0.100000,0.100000},{0.687500,0.212500,0.200000,0.200000},{0.712500,0.212500,0.100000,0.100000},{0.712500,0.212500,0.200000,0.200000},{0.737500,0.212500,0.100000,0.100000},{0.737500,0.212500,0.200000,0.200000},{0.762500,0.212500,0.100000,0.100000},{0.762500,0.212500,0.200000,0.200000},{0.787500,0.212500,0.100000,0.100000},{0.787500,0.212500,0.200000,0.200000},{0.812500,0.212500,0.100000,0.100000},{0.812500,0.212500,0.200000,0.200000},{0.837500,0.212500,0.100000,0.100000},{0.837500,0.212500,0.200000,0.200000},{0.862500,0.212500,0.100000,0.100000},{0.862500,0.212500,0.200000,0.200000},{0.887500,0.212500,0.100000,0.100000},{0.887500,0.212500,0.200000,0.200000},{0.912500,0.212500,0.100000,0.100000},{0.912500,0.212500,0.200000,0.200000},{0.937500,0.212500,0.100000,0.100000},{0.937500,0.212500,0.200000,0.200000},{0.962500,0.212500,0.100000,0.100000},{0.962500,0.212500,0.200000,0.200000},{0.987500,0.212500,0.100000,0.100000},{0.987500,0.212500,0.200000,0.200000},{0.012500,0.237500,0.100000,0.100000},{0.012500,0.237500,0.200000,0.200000},{0.037500,0.237500,0.100000,0.100000},{0.037500,0.237500,0.200000,0.200000},{0.062500,0.237500,0.100000,0.100000},{0.062500,0.237500,0.200000,0.200000},{0.087500,0.237500,0.100000,0.100000},{0.087500,0.237500,0.200000,0.200000},{0.112500,0.237500,0.100000,0.100000},{0.112500,0.237500,0.200000,0.200000},{0.137500,0.237500,0.100000,0.100000},{0.137500,0.237500,0.200000,0.200000},{0.162500,0.237500,0.100000,0.100000},{0.162500,0.237500,0.200000,0.200000},{0.187500,0.237500,0.100000,0.100000},{0.187500,0.237500,0.200000,0.200000},{0.212500,0.237500,0.100000,0.100000},{0.212500,0.237500,0.200000,0.200000},{0.237500,0.237500,0.100000,0.100000},{0.237500,0.237500,0.200000,0.200000},{0.262500,0.237500,0.100000,0.100000},{0.262500,0.237500,0.200000,0.200000},{0.287500,0.237500,0.100000,0.100000},{0.287500,0.237500,0.200000,0.200000},{0.312500,0.237500,0.100000,0.100000},{0.312500,0.237500,0.200000,0.200000},{0.337500,0.237500,0.100000,0.100000},{0.337500,0.237500,0.200000,0.200000},{0.362500,0.237500,0.100000,0.100000},{0.362500,0.237500,0.200000,0.200000},{0.387500,0.237500,0.100000,0.100000},{0.387500,0.237500,0.200000,0.200000},{0.412500,0.237500,0.100000,0.100000},{0.412500,0.237500,0.200000,0.200000},{0.437500,0.237500,0.100000,0.100000},{0.437500,0.237500,0.200000,0.200000},{0.462500,0.237500,0.100000,0.100000},{0.462500,0.237500,0.200000,0.200000},{0.487500,0.237500,0.100000,0.100000},{0.487500,0.237500,0.200000,0.200000},{0.512500,0.237500,0.100000,0.100000},{0.512500,0.237500,0.200000,0.200000},{0.537500,0.237500,0.100000,0.100000},{0.537500,0.237500,0.200000,0.200000},{0.562500,0.237500,0.100000,0.100000},{0.562500,0.237500,0.200000,0.200000},{0.587500,0.237500,0.100000,0.100000},{0.587500,0.237500,0.200000,0.200000},{0.612500,0.237500,0.100000,0.100000},{0.612500,0.237500,0.200000,0.200000},{0.637500,0.237500,0.100000,0.100000},{0.637500,0.237500,0.200000,0.200000},{0.662500,0.237500,0.100000,0.100000},{0.662500,0.237500,0.200000,0.200000},{0.687500,0.237500,0.100000,0.100000},{0.687500,0.237500,0.200000,0.200000},{0.712500,0.237500,0.100000,0.100000},{0.712500,0.237500,0.200000,0.200000},{0.737500,0.237500,0.100000,0.100000},{0.737500,0.237500,0.200000,0.200000},{0.762500,0.237500,0.100000,0.100000},{0.762500,0.237500,0.200000,0.200000},{0.787500,0.237500,0.100000,0.100000},{0.787500,0.237500,0.200000,0.200000},{0.812500,0.237500,0.100000,0.100000},{0.812500,0.237500,0.200000,0.200000},{0.837500,0.237500,0.100000,0.100000},{0.837500,0.237500,0.200000,0.200000},{0.862500,0.237500,0.100000,0.100000},{0.862500,0.237500,0.200000,0.200000},{0.887500,0.237500,0.100000,0.100000},{0.887500,0.237500,0.200000,0.200000},{0.912500,0.237500,0.100000,0.100000},{0.912500,0.237500,0.200000,0.200000},{0.937500,0.237500,0.100000,0.100000},{0.937500,0.237500,0.200000,0.200000},{0.962500,0.237500,0.100000,0.100000},{0.962500,0.237500,0.200000,0.200000},{0.987500,0.237500,0.100000,0.100000},{0.987500,0.237500,0.200000,0.200000},{0.012500,0.262500,0.100000,0.100000},{0.012500,0.262500,0.200000,0.200000},{0.037500,0.262500,0.100000,0.100000},{0.037500,0.262500,0.200000,0.200000},{0.062500,0.262500,0.100000,0.100000},{0.062500,0.262500,0.200000,0.200000},{0.087500,0.262500,0.100000,0.100000},{0.087500,0.262500,0.200000,0.200000},{0.112500,0.262500,0.100000,0.100000},{0.112500,0.262500,0.200000,0.200000},{0.137500,0.262500,0.100000,0.100000},{0.137500,0.262500,0.200000,0.200000},{0.162500,0.262500,0.100000,0.100000},{0.162500,0.262500,0.200000,0.200000},{0.187500,0.262500,0.100000,0.100000},{0.187500,0.262500,0.200000,0.200000},{0.212500,0.262500,0.100000,0.100000},{0.212500,0.262500,0.200000,0.200000},{0.237500,0.262500,0.100000,0.100000},{0.237500,0.262500,0.200000,0.200000},{0.262500,0.262500,0.100000,0.100000},{0.262500,0.262500,0.200000,0.200000},{0.287500,0.262500,0.100000,0.100000},{0.287500,0.262500,0.200000,0.200000},{0.312500,0.262500,0.100000,0.100000},{0.312500,0.262500,0.200000,0.200000},{0.337500,0.262500,0.100000,0.100000},{0.337500,0.262500,0.200000,0.200000},{0.362500,0.262500,0.100000,0.100000},{0.362500,0.262500,0.200000,0.200000},{0.387500,0.262500,0.100000,0.100000},{0.387500,0.262500,0.200000,0.200000},{0.412500,0.262500,0.100000,0.100000},{0.412500,0.262500,0.200000,0.200000},{0.437500,0.262500,0.100000,0.100000},{0.437500,0.262500,0.200000,0.200000},{0.462500,0.262500,0.100000,0.100000},{0.462500,0.262500,0.200000,0.200000},{0.487500,0.262500,0.100000,0.100000},{0.487500,0.262500,0.200000,0.200000},{0.512500,0.262500,0.100000,0.100000},{0.512500,0.262500,0.200000,0.200000},{0.537500,0.262500,0.100000,0.100000},{0.537500,0.262500,0.200000,0.200000},{0.562500,0.262500,0.100000,0.100000},{0.562500,0.262500,0.200000,0.200000},{0.587500,0.262500,0.100000,0.100000},{0.587500,0.262500,0.200000,0.200000},{0.612500,0.262500,0.100000,0.100000},{0.612500,0.262500,0.200000,0.200000},{0.637500,0.262500,0.100000,0.100000},{0.637500,0.262500,0.200000,0.200000},{0.662500,0.262500,0.100000,0.100000},{0.662500,0.262500,0.200000,0.200000},{0.687500,0.262500,0.100000,0.100000},{0.687500,0.262500,0.200000,0.200000},{0.712500,0.262500,0.100000,0.100000},{0.712500,0.262500,0.200000,0.200000},{0.737500,0.262500,0.100000,0.100000},{0.737500,0.262500,0.200000,0.200000},{0.762500,0.262500,0.100000,0.100000},{0.762500,0.262500,0.200000,0.200000},{0.787500,0.262500,0.100000,0.100000},{0.787500,0.262500,0.200000,0.200000},{0.812500,0.262500,0.100000,0.100000},{0.812500,0.262500,0.200000,0.200000},{0.837500,0.262500,0.100000,0.100000},{0.837500,0.262500,0.200000,0.200000},{0.862500,0.262500,0.100000,0.100000},{0.862500,0.262500,0.200000,0.200000},{0.887500,0.262500,0.100000,0.100000},{0.887500,0.262500,0.200000,0.200000},{0.912500,0.262500,0.100000,0.100000},{0.912500,0.262500,0.200000,0.200000},{0.937500,0.262500,0.100000,0.100000},{0.937500,0.262500,0.200000,0.200000},{0.962500,0.262500,0.100000,0.100000},{0.962500,0.262500,0.200000,0.200000},{0.987500,0.262500,0.100000,0.100000},{0.987500,0.262500,0.200000,0.200000},{0.012500,0.287500,0.100000,0.100000},{0.012500,0.287500,0.200000,0.200000},{0.037500,0.287500,0.100000,0.100000},{0.037500,0.287500,0.200000,0.200000},{0.062500,0.287500,0.100000,0.100000},{0.062500,0.287500,0.200000,0.200000},{0.087500,0.287500,0.100000,0.100000},{0.087500,0.287500,0.200000,0.200000},{0.112500,0.287500,0.100000,0.100000},{0.112500,0.287500,0.200000,0.200000},{0.137500,0.287500,0.100000,0.100000},{0.137500,0.287500,0.200000,0.200000},{0.162500,0.287500,0.100000,0.100000},{0.162500,0.287500,0.200000,0.200000},{0.187500,0.287500,0.100000,0.100000},{0.187500,0.287500,0.200000,0.200000},{0.212500,0.287500,0.100000,0.100000},{0.212500,0.287500,0.200000,0.200000},{0.237500,0.287500,0.100000,0.100000},{0.237500,0.287500,0.200000,0.200000},{0.262500,0.287500,0.100000,0.100000},{0.262500,0.287500,0.200000,0.200000},{0.287500,0.287500,0.100000,0.100000},{0.287500,0.287500,0.200000,0.200000},{0.312500,0.287500,0.100000,0.100000},{0.312500,0.287500,0.200000,0.200000},{0.337500,0.287500,0.100000,0.100000},{0.337500,0.287500,0.200000,0.200000},{0.362500,0.287500,0.100000,0.100000},{0.362500,0.287500,0.200000,0.200000},{0.387500,0.287500,0.100000,0.100000},{0.387500,0.287500,0.200000,0.200000},{0.412500,0.287500,0.100000,0.100000},{0.412500,0.287500,0.200000,0.200000},{0.437500,0.287500,0.100000,0.100000},{0.437500,0.287500,0.200000,0.200000},{0.462500,0.287500,0.100000,0.100000},{0.462500,0.287500,0.200000,0.200000},{0.487500,0.287500,0.100000,0.100000},{0.487500,0.287500,0.200000,0.200000},{0.512500,0.287500,0.100000,0.100000},{0.512500,0.287500,0.200000,0.200000},{0.537500,0.287500,0.100000,0.100000},{0.537500,0.287500,0.200000,0.200000},{0.562500,0.287500,0.100000,0.100000},{0.562500,0.287500,0.200000,0.200000},{0.587500,0.287500,0.100000,0.100000},{0.587500,0.287500,0.200000,0.200000},{0.612500,0.287500,0.100000,0.100000},{0.612500,0.287500,0.200000,0.200000},{0.637500,0.287500,0.100000,0.100000},{0.637500,0.287500,0.200000,0.200000},{0.662500,0.287500,0.100000,0.100000},{0.662500,0.287500,0.200000,0.200000},{0.687500,0.287500,0.100000,0.100000},{0.687500,0.287500,0.200000,0.200000},{0.712500,0.287500,0.100000,0.100000},{0.712500,0.287500,0.200000,0.200000},{0.737500,0.287500,0.100000,0.100000},{0.737500,0.287500,0.200000,0.200000},{0.762500,0.287500,0.100000,0.100000},{0.762500,0.287500,0.200000,0.200000},{0.787500,0.287500,0.100000,0.100000},{0.787500,0.287500,0.200000,0.200000},{0.812500,0.287500,0.100000,0.100000},{0.812500,0.287500,0.200000,0.200000},{0.837500,0.287500,0.100000,0.100000},{0.837500,0.287500,0.200000,0.200000},{0.862500,0.287500,0.100000,0.100000},{0.862500,0.287500,0.200000,0.200000},{0.887500,0.287500,0.100000,0.100000},{0.887500,0.287500,0.200000,0.200000},{0.912500,0.287500,0.100000,0.100000},{0.912500,0.287500,0.200000,0.200000},{0.937500,0.287500,0.100000,0.100000},{0.937500,0.287500,0.200000,0.200000},{0.962500,0.287500,0.100000,0.100000},{0.962500,0.287500,0.200000,0.200000},{0.987500,0.287500,0.100000,0.100000},{0.987500,0.287500,0.200000,0.200000},{0.012500,0.312500,0.100000,0.100000},{0.012500,0.312500,0.200000,0.200000},{0.037500,0.312500,0.100000,0.100000},{0.037500,0.312500,0.200000,0.200000},{0.062500,0.312500,0.100000,0.100000},{0.062500,0.312500,0.200000,0.200000},{0.087500,0.312500,0.100000,0.100000},{0.087500,0.312500,0.200000,0.200000},{0.112500,0.312500,0.100000,0.100000},{0.112500,0.312500,0.200000,0.200000},{0.137500,0.312500,0.100000,0.100000},{0.137500,0.312500,0.200000,0.200000},{0.162500,0.312500,0.100000,0.100000},{0.162500,0.312500,0.200000,0.200000},{0.187500,0.312500,0.100000,0.100000},{0.187500,0.312500,0.200000,0.200000},{0.212500,0.312500,0.100000,0.100000},{0.212500,0.312500,0.200000,0.200000},{0.237500,0.312500,0.100000,0.100000},{0.237500,0.312500,0.200000,0.200000},{0.262500,0.312500,0.100000,0.100000},{0.262500,0.312500,0.200000,0.200000},{0.287500,0.312500,0.100000,0.100000},{0.287500,0.312500,0.200000,0.200000},{0.312500,0.312500,0.100000,0.100000},{0.312500,0.312500,0.200000,0.200000},{0.337500,0.312500,0.100000,0.100000},{0.337500,0.312500,0.200000,0.200000},{0.362500,0.312500,0.100000,0.100000},{0.362500,0.312500,0.200000,0.200000},{0.387500,0.312500,0.100000,0.100000},{0.387500,0.312500,0.200000,0.200000},{0.412500,0.312500,0.100000,0.100000},{0.412500,0.312500,0.200000,0.200000},{0.437500,0.312500,0.100000,0.100000},{0.437500,0.312500,0.200000,0.200000},{0.462500,0.312500,0.100000,0.100000},{0.462500,0.312500,0.200000,0.200000},{0.487500,0.312500,0.100000,0.100000},{0.487500,0.312500,0.200000,0.200000},{0.512500,0.312500,0.100000,0.100000},{0.512500,0.312500,0.200000,0.200000},{0.537500,0.312500,0.100000,0.100000},{0.537500,0.312500,0.200000,0.200000},{0.562500,0.312500,0.100000,0.100000},{0.562500,0.312500,0.200000,0.200000},{0.587500,0.312500,0.100000,0.100000},{0.587500,0.312500,0.200000,0.200000},{0.612500,0.312500,0.100000,0.100000},{0.612500,0.312500,0.200000,0.200000},{0.637500,0.312500,0.100000,0.100000},{0.637500,0.312500,0.200000,0.200000},{0.662500,0.312500,0.100000,0.100000},{0.662500,0.312500,0.200000,0.200000},{0.687500,0.312500,0.100000,0.100000},{0.687500,0.312500,0.200000,0.200000},{0.712500,0.312500,0.100000,0.100000},{0.712500,0.312500,0.200000,0.200000},{0.737500,0.312500,0.100000,0.100000},{0.737500,0.312500,0.200000,0.200000},{0.762500,0.312500,0.100000,0.100000},{0.762500,0.312500,0.200000,0.200000},{0.787500,0.312500,0.100000,0.100000},{0.787500,0.312500,0.200000,0.200000},{0.812500,0.312500,0.100000,0.100000},{0.812500,0.312500,0.200000,0.200000},{0.837500,0.312500,0.100000,0.100000},{0.837500,0.312500,0.200000,0.200000},{0.862500,0.312500,0.100000,0.100000},{0.862500,0.312500,0.200000,0.200000},{0.887500,0.312500,0.100000,0.100000},{0.887500,0.312500,0.200000,0.200000},{0.912500,0.312500,0.100000,0.100000},{0.912500,0.312500,0.200000,0.200000},{0.937500,0.312500,0.100000,0.100000},{0.937500,0.312500,0.200000,0.200000},{0.962500,0.312500,0.100000,0.100000},{0.962500,0.312500,0.200000,0.200000},{0.987500,0.312500,0.100000,0.100000},{0.987500,0.312500,0.200000,0.200000},{0.012500,0.337500,0.100000,0.100000},{0.012500,0.337500,0.200000,0.200000},{0.037500,0.337500,0.100000,0.100000},{0.037500,0.337500,0.200000,0.200000},{0.062500,0.337500,0.100000,0.100000},{0.062500,0.337500,0.200000,0.200000},{0.087500,0.337500,0.100000,0.100000},{0.087500,0.337500,0.200000,0.200000},{0.112500,0.337500,0.100000,0.100000},{0.112500,0.337500,0.200000,0.200000},{0.137500,0.337500,0.100000,0.100000},{0.137500,0.337500,0.200000,0.200000},{0.162500,0.337500,0.100000,0.100000},{0.162500,0.337500,0.200000,0.200000},{0.187500,0.337500,0.100000,0.100000},{0.187500,0.337500,0.200000,0.200000},{0.212500,0.337500,0.100000,0.100000},{0.212500,0.337500,0.200000,0.200000},{0.237500,0.337500,0.100000,0.100000},{0.237500,0.337500,0.200000,0.200000},{0.262500,0.337500,0.100000,0.100000},{0.262500,0.337500,0.200000,0.200000},{0.287500,0.337500,0.100000,0.100000},{0.287500,0.337500,0.200000,0.200000},{0.312500,0.337500,0.100000,0.100000},{0.312500,0.337500,0.200000,0.200000},{0.337500,0.337500,0.100000,0.100000},{0.337500,0.337500,0.200000,0.200000},{0.362500,0.337500,0.100000,0.100000},{0.362500,0.337500,0.200000,0.200000},{0.387500,0.337500,0.100000,0.100000},{0.387500,0.337500,0.200000,0.200000},{0.412500,0.337500,0.100000,0.100000},{0.412500,0.337500,0.200000,0.200000},{0.437500,0.337500,0.100000,0.100000},{0.437500,0.337500,0.200000,0.200000},{0.462500,0.337500,0.100000,0.100000},{0.462500,0.337500,0.200000,0.200000},{0.487500,0.337500,0.100000,0.100000},{0.487500,0.337500,0.200000,0.200000},{0.512500,0.337500,0.100000,0.100000},{0.512500,0.337500,0.200000,0.200000},{0.537500,0.337500,0.100000,0.100000},{0.537500,0.337500,0.200000,0.200000},{0.562500,0.337500,0.100000,0.100000},{0.562500,0.337500,0.200000,0.200000},{0.587500,0.337500,0.100000,0.100000},{0.587500,0.337500,0.200000,0.200000},{0.612500,0.337500,0.100000,0.100000},{0.612500,0.337500,0.200000,0.200000},{0.637500,0.337500,0.100000,0.100000},{0.637500,0.337500,0.200000,0.200000},{0.662500,0.337500,0.100000,0.100000},{0.662500,0.337500,0.200000,0.200000},{0.687500,0.337500,0.100000,0.100000},{0.687500,0.337500,0.200000,0.200000},{0.712500,0.337500,0.100000,0.100000},{0.712500,0.337500,0.200000,0.200000},{0.737500,0.337500,0.100000,0.100000},{0.737500,0.337500,0.200000,0.200000},{0.762500,0.337500,0.100000,0.100000},{0.762500,0.337500,0.200000,0.200000},{0.787500,0.337500,0.100000,0.100000},{0.787500,0.337500,0.200000,0.200000},{0.812500,0.337500,0.100000,0.100000},{0.812500,0.337500,0.200000,0.200000},{0.837500,0.337500,0.100000,0.100000},{0.837500,0.337500,0.200000,0.200000},{0.862500,0.337500,0.100000,0.100000},{0.862500,0.337500,0.200000,0.200000},{0.887500,0.337500,0.100000,0.100000},{0.887500,0.337500,0.200000,0.200000},{0.912500,0.337500,0.100000,0.100000},{0.912500,0.337500,0.200000,0.200000},{0.937500,0.337500,0.100000,0.100000},{0.937500,0.337500,0.200000,0.200000},{0.962500,0.337500,0.100000,0.100000},{0.962500,0.337500,0.200000,0.200000},{0.987500,0.337500,0.100000,0.100000},{0.987500,0.337500,0.200000,0.200000},{0.012500,0.362500,0.100000,0.100000},{0.012500,0.362500,0.200000,0.200000},{0.037500,0.362500,0.100000,0.100000},{0.037500,0.362500,0.200000,0.200000},{0.062500,0.362500,0.100000,0.100000},{0.062500,0.362500,0.200000,0.200000},{0.087500,0.362500,0.100000,0.100000},{0.087500,0.362500,0.200000,0.200000},{0.112500,0.362500,0.100000,0.100000},{0.112500,0.362500,0.200000,0.200000},{0.137500,0.362500,0.100000,0.100000},{0.137500,0.362500,0.200000,0.200000},{0.162500,0.362500,0.100000,0.100000},{0.162500,0.362500,0.200000,0.200000},{0.187500,0.362500,0.100000,0.100000},{0.187500,0.362500,0.200000,0.200000},{0.212500,0.362500,0.100000,0.100000},{0.212500,0.362500,0.200000,0.200000},{0.237500,0.362500,0.100000,0.100000},{0.237500,0.362500,0.200000,0.200000},{0.262500,0.362500,0.100000,0.100000},{0.262500,0.362500,0.200000,0.200000},{0.287500,0.362500,0.100000,0.100000},{0.287500,0.362500,0.200000,0.200000},{0.312500,0.362500,0.100000,0.100000},{0.312500,0.362500,0.200000,0.200000},{0.337500,0.362500,0.100000,0.100000},{0.337500,0.362500,0.200000,0.200000},{0.362500,0.362500,0.100000,0.100000},{0.362500,0.362500,0.200000,0.200000},{0.387500,0.362500,0.100000,0.100000},{0.387500,0.362500,0.200000,0.200000},{0.412500,0.362500,0.100000,0.100000},{0.412500,0.362500,0.200000,0.200000},{0.437500,0.362500,0.100000,0.100000},{0.437500,0.362500,0.200000,0.200000},{0.462500,0.362500,0.100000,0.100000},{0.462500,0.362500,0.200000,0.200000},{0.487500,0.362500,0.100000,0.100000},{0.487500,0.362500,0.200000,0.200000},{0.512500,0.362500,0.100000,0.100000},{0.512500,0.362500,0.200000,0.200000},{0.537500,0.362500,0.100000,0.100000},{0.537500,0.362500,0.200000,0.200000},{0.562500,0.362500,0.100000,0.100000},{0.562500,0.362500,0.200000,0.200000},{0.587500,0.362500,0.100000,0.100000},{0.587500,0.362500,0.200000,0.200000},{0.612500,0.362500,0.100000,0.100000},{0.612500,0.362500,0.200000,0.200000},{0.637500,0.362500,0.100000,0.100000},{0.637500,0.362500,0.200000,0.200000},{0.662500,0.362500,0.100000,0.100000},{0.662500,0.362500,0.200000,0.200000},{0.687500,0.362500,0.100000,0.100000},{0.687500,0.362500,0.200000,0.200000},{0.712500,0.362500,0.100000,0.100000},{0.712500,0.362500,0.200000,0.200000},{0.737500,0.362500,0.100000,0.100000},{0.737500,0.362500,0.200000,0.200000},{0.762500,0.362500,0.100000,0.100000},{0.762500,0.362500,0.200000,0.200000},{0.787500,0.362500,0.100000,0.100000},{0.787500,0.362500,0.200000,0.200000},{0.812500,0.362500,0.100000,0.100000},{0.812500,0.362500,0.200000,0.200000},{0.837500,0.362500,0.100000,0.100000},{0.837500,0.362500,0.200000,0.200000},{0.862500,0.362500,0.100000,0.100000},{0.862500,0.362500,0.200000,0.200000},{0.887500,0.362500,0.100000,0.100000},{0.887500,0.362500,0.200000,0.200000},{0.912500,0.362500,0.100000,0.100000},{0.912500,0.362500,0.200000,0.200000},{0.937500,0.362500,0.100000,0.100000},{0.937500,0.362500,0.200000,0.200000},{0.962500,0.362500,0.100000,0.100000},{0.962500,0.362500,0.200000,0.200000},{0.987500,0.362500,0.100000,0.100000},{0.987500,0.362500,0.200000,0.200000},{0.012500,0.387500,0.100000,0.100000},{0.012500,0.387500,0.200000,0.200000},{0.037500,0.387500,0.100000,0.100000},{0.037500,0.387500,0.200000,0.200000},{0.062500,0.387500,0.100000,0.100000},{0.062500,0.387500,0.200000,0.200000},{0.087500,0.387500,0.100000,0.100000},{0.087500,0.387500,0.200000,0.200000},{0.112500,0.387500,0.100000,0.100000},{0.112500,0.387500,0.200000,0.200000},{0.137500,0.387500,0.100000,0.100000},{0.137500,0.387500,0.200000,0.200000},{0.162500,0.387500,0.100000,0.100000},{0.162500,0.387500,0.200000,0.200000},{0.187500,0.387500,0.100000,0.100000},{0.187500,0.387500,0.200000,0.200000},{0.212500,0.387500,0.100000,0.100000},{0.212500,0.387500,0.200000,0.200000},{0.237500,0.387500,0.100000,0.100000},{0.237500,0.387500,0.200000,0.200000},{0.262500,0.387500,0.100000,0.100000},{0.262500,0.387500,0.200000,0.200000},{0.287500,0.387500,0.100000,0.100000},{0.287500,0.387500,0.200000,0.200000},{0.312500,0.387500,0.100000,0.100000},{0.312500,0.387500,0.200000,0.200000},{0.337500,0.387500,0.100000,0.100000},{0.337500,0.387500,0.200000,0.200000},{0.362500,0.387500,0.100000,0.100000},{0.362500,0.387500,0.200000,0.200000},{0.387500,0.387500,0.100000,0.100000},{0.387500,0.387500,0.200000,0.200000},{0.412500,0.387500,0.100000,0.100000},{0.412500,0.387500,0.200000,0.200000},{0.437500,0.387500,0.100000,0.100000},{0.437500,0.387500,0.200000,0.200000},{0.462500,0.387500,0.100000,0.100000},{0.462500,0.387500,0.200000,0.200000},{0.487500,0.387500,0.100000,0.100000},{0.487500,0.387500,0.200000,0.200000},{0.512500,0.387500,0.100000,0.100000},{0.512500,0.387500,0.200000,0.200000},{0.537500,0.387500,0.100000,0.100000},{0.537500,0.387500,0.200000,0.200000},{0.562500,0.387500,0.100000,0.100000},{0.562500,0.387500,0.200000,0.200000},{0.587500,0.387500,0.100000,0.100000},{0.587500,0.387500,0.200000,0.200000},{0.612500,0.387500,0.100000,0.100000},{0.612500,0.387500,0.200000,0.200000},{0.637500,0.387500,0.100000,0.100000},{0.637500,0.387500,0.200000,0.200000},{0.662500,0.387500,0.100000,0.100000},{0.662500,0.387500,0.200000,0.200000},{0.687500,0.387500,0.100000,0.100000},{0.687500,0.387500,0.200000,0.200000},{0.712500,0.387500,0.100000,0.100000},{0.712500,0.387500,0.200000,0.200000},{0.737500,0.387500,0.100000,0.100000},{0.737500,0.387500,0.200000,0.200000},{0.762500,0.387500,0.100000,0.100000},{0.762500,0.387500,0.200000,0.200000},{0.787500,0.387500,0.100000,0.100000},{0.787500,0.387500,0.200000,0.200000},{0.812500,0.387500,0.100000,0.100000},{0.812500,0.387500,0.200000,0.200000},{0.837500,0.387500,0.100000,0.100000},{0.837500,0.387500,0.200000,0.200000},{0.862500,0.387500,0.100000,0.100000},{0.862500,0.387500,0.200000,0.200000},{0.887500,0.387500,0.100000,0.100000},{0.887500,0.387500,0.200000,0.200000},{0.912500,0.387500,0.100000,0.100000},{0.912500,0.387500,0.200000,0.200000},{0.937500,0.387500,0.100000,0.100000},{0.937500,0.387500,0.200000,0.200000},{0.962500,0.387500,0.100000,0.100000},{0.962500,0.387500,0.200000,0.200000},{0.987500,0.387500,0.100000,0.100000},{0.987500,0.387500,0.200000,0.200000},{0.012500,0.412500,0.100000,0.100000},{0.012500,0.412500,0.200000,0.200000},{0.037500,0.412500,0.100000,0.100000},{0.037500,0.412500,0.200000,0.200000},{0.062500,0.412500,0.100000,0.100000},{0.062500,0.412500,0.200000,0.200000},{0.087500,0.412500,0.100000,0.100000},{0.087500,0.412500,0.200000,0.200000},{0.112500,0.412500,0.100000,0.100000},{0.112500,0.412500,0.200000,0.200000},{0.137500,0.412500,0.100000,0.100000},{0.137500,0.412500,0.200000,0.200000},{0.162500,0.412500,0.100000,0.100000},{0.162500,0.412500,0.200000,0.200000},{0.187500,0.412500,0.100000,0.100000},{0.187500,0.412500,0.200000,0.200000},{0.212500,0.412500,0.100000,0.100000},{0.212500,0.412500,0.200000,0.200000},{0.237500,0.412500,0.100000,0.100000},{0.237500,0.412500,0.200000,0.200000},{0.262500,0.412500,0.100000,0.100000},{0.262500,0.412500,0.200000,0.200000},{0.287500,0.412500,0.100000,0.100000},{0.287500,0.412500,0.200000,0.200000},{0.312500,0.412500,0.100000,0.100000},{0.312500,0.412500,0.200000,0.200000},{0.337500,0.412500,0.100000,0.100000},{0.337500,0.412500,0.200000,0.200000},{0.362500,0.412500,0.100000,0.100000},{0.362500,0.412500,0.200000,0.200000},{0.387500,0.412500,0.100000,0.100000},{0.387500,0.412500,0.200000,0.200000},{0.412500,0.412500,0.100000,0.100000},{0.412500,0.412500,0.200000,0.200000},{0.437500,0.412500,0.100000,0.100000},{0.437500,0.412500,0.200000,0.200000},{0.462500,0.412500,0.100000,0.100000},{0.462500,0.412500,0.200000,0.200000},{0.487500,0.412500,0.100000,0.100000},{0.487500,0.412500,0.200000,0.200000},{0.512500,0.412500,0.100000,0.100000},{0.512500,0.412500,0.200000,0.200000},{0.537500,0.412500,0.100000,0.100000},{0.537500,0.412500,0.200000,0.200000},{0.562500,0.412500,0.100000,0.100000},{0.562500,0.412500,0.200000,0.200000},{0.587500,0.412500,0.100000,0.100000},{0.587500,0.412500,0.200000,0.200000},{0.612500,0.412500,0.100000,0.100000},{0.612500,0.412500,0.200000,0.200000},{0.637500,0.412500,0.100000,0.100000},{0.637500,0.412500,0.200000,0.200000},{0.662500,0.412500,0.100000,0.100000},{0.662500,0.412500,0.200000,0.200000},{0.687500,0.412500,0.100000,0.100000},{0.687500,0.412500,0.200000,0.200000},{0.712500,0.412500,0.100000,0.100000},{0.712500,0.412500,0.200000,0.200000},{0.737500,0.412500,0.100000,0.100000},{0.737500,0.412500,0.200000,0.200000},{0.762500,0.412500,0.100000,0.100000},{0.762500,0.412500,0.200000,0.200000},{0.787500,0.412500,0.100000,0.100000},{0.787500,0.412500,0.200000,0.200000},{0.812500,0.412500,0.100000,0.100000},{0.812500,0.412500,0.200000,0.200000},{0.837500,0.412500,0.100000,0.100000},{0.837500,0.412500,0.200000,0.200000},{0.862500,0.412500,0.100000,0.100000},{0.862500,0.412500,0.200000,0.200000},{0.887500,0.412500,0.100000,0.100000},{0.887500,0.412500,0.200000,0.200000},{0.912500,0.412500,0.100000,0.100000},{0.912500,0.412500,0.200000,0.200000},{0.937500,0.412500,0.100000,0.100000},{0.937500,0.412500,0.200000,0.200000},{0.962500,0.412500,0.100000,0.100000},{0.962500,0.412500,0.200000,0.200000},{0.987500,0.412500,0.100000,0.100000},{0.987500,0.412500,0.200000,0.200000},{0.012500,0.437500,0.100000,0.100000},{0.012500,0.437500,0.200000,0.200000},{0.037500,0.437500,0.100000,0.100000},{0.037500,0.437500,0.200000,0.200000},{0.062500,0.437500,0.100000,0.100000},{0.062500,0.437500,0.200000,0.200000},{0.087500,0.437500,0.100000,0.100000},{0.087500,0.437500,0.200000,0.200000},{0.112500,0.437500,0.100000,0.100000},{0.112500,0.437500,0.200000,0.200000},{0.137500,0.437500,0.100000,0.100000},{0.137500,0.437500,0.200000,0.200000},{0.162500,0.437500,0.100000,0.100000},{0.162500,0.437500,0.200000,0.200000},{0.187500,0.437500,0.100000,0.100000},{0.187500,0.437500,0.200000,0.200000},{0.212500,0.437500,0.100000,0.100000},{0.212500,0.437500,0.200000,0.200000},{0.237500,0.437500,0.100000,0.100000},{0.237500,0.437500,0.200000,0.200000},{0.262500,0.437500,0.100000,0.100000},{0.262500,0.437500,0.200000,0.200000},{0.287500,0.437500,0.100000,0.100000},{0.287500,0.437500,0.200000,0.200000},{0.312500,0.437500,0.100000,0.100000},{0.312500,0.437500,0.200000,0.200000},{0.337500,0.437500,0.100000,0.100000},{0.337500,0.437500,0.200000,0.200000},{0.362500,0.437500,0.100000,0.100000},{0.362500,0.437500,0.200000,0.200000},{0.387500,0.437500,0.100000,0.100000},{0.387500,0.437500,0.200000,0.200000},{0.412500,0.437500,0.100000,0.100000},{0.412500,0.437500,0.200000,0.200000},{0.437500,0.437500,0.100000,0.100000},{0.437500,0.437500,0.200000,0.200000},{0.462500,0.437500,0.100000,0.100000},{0.462500,0.437500,0.200000,0.200000},{0.487500,0.437500,0.100000,0.100000},{0.487500,0.437500,0.200000,0.200000},{0.512500,0.437500,0.100000,0.100000},{0.512500,0.437500,0.200000,0.200000},{0.537500,0.437500,0.100000,0.100000},{0.537500,0.437500,0.200000,0.200000},{0.562500,0.437500,0.100000,0.100000},{0.562500,0.437500,0.200000,0.200000},{0.587500,0.437500,0.100000,0.100000},{0.587500,0.437500,0.200000,0.200000},{0.612500,0.437500,0.100000,0.100000},{0.612500,0.437500,0.200000,0.200000},{0.637500,0.437500,0.100000,0.100000},{0.637500,0.437500,0.200000,0.200000},{0.662500,0.437500,0.100000,0.100000},{0.662500,0.437500,0.200000,0.200000},{0.687500,0.437500,0.100000,0.100000},{0.687500,0.437500,0.200000,0.200000},{0.712500,0.437500,0.100000,0.100000},{0.712500,0.437500,0.200000,0.200000},{0.737500,0.437500,0.100000,0.100000},{0.737500,0.437500,0.200000,0.200000},{0.762500,0.437500,0.100000,0.100000},{0.762500,0.437500,0.200000,0.200000},{0.787500,0.437500,0.100000,0.100000},{0.787500,0.437500,0.200000,0.200000},{0.812500,0.437500,0.100000,0.100000},{0.812500,0.437500,0.200000,0.200000},{0.837500,0.437500,0.100000,0.100000},{0.837500,0.437500,0.200000,0.200000},{0.862500,0.437500,0.100000,0.100000},{0.862500,0.437500,0.200000,0.200000},{0.887500,0.437500,0.100000,0.100000},{0.887500,0.437500,0.200000,0.200000},{0.912500,0.437500,0.100000,0.100000},{0.912500,0.437500,0.200000,0.200000},{0.937500,0.437500,0.100000,0.100000},{0.937500,0.437500,0.200000,0.200000},{0.962500,0.437500,0.100000,0.100000},{0.962500,0.437500,0.200000,0.200000},{0.987500,0.437500,0.100000,0.100000},{0.987500,0.437500,0.200000,0.200000},{0.012500,0.462500,0.100000,0.100000},{0.012500,0.462500,0.200000,0.200000},{0.037500,0.462500,0.100000,0.100000},{0.037500,0.462500,0.200000,0.200000},{0.062500,0.462500,0.100000,0.100000},{0.062500,0.462500,0.200000,0.200000},{0.087500,0.462500,0.100000,0.100000},{0.087500,0.462500,0.200000,0.200000},{0.112500,0.462500,0.100000,0.100000},{0.112500,0.462500,0.200000,0.200000},{0.137500,0.462500,0.100000,0.100000},{0.137500,0.462500,0.200000,0.200000},{0.162500,0.462500,0.100000,0.100000},{0.162500,0.462500,0.200000,0.200000},{0.187500,0.462500,0.100000,0.100000},{0.187500,0.462500,0.200000,0.200000},{0.212500,0.462500,0.100000,0.100000},{0.212500,0.462500,0.200000,0.200000},{0.237500,0.462500,0.100000,0.100000},{0.237500,0.462500,0.200000,0.200000},{0.262500,0.462500,0.100000,0.100000},{0.262500,0.462500,0.200000,0.200000},{0.287500,0.462500,0.100000,0.100000},{0.287500,0.462500,0.200000,0.200000},{0.312500,0.462500,0.100000,0.100000},{0.312500,0.462500,0.200000,0.200000},{0.337500,0.462500,0.100000,0.100000},{0.337500,0.462500,0.200000,0.200000},{0.362500,0.462500,0.100000,0.100000},{0.362500,0.462500,0.200000,0.200000},{0.387500,0.462500,0.100000,0.100000},{0.387500,0.462500,0.200000,0.200000},{0.412500,0.462500,0.100000,0.100000},{0.412500,0.462500,0.200000,0.200000},{0.437500,0.462500,0.100000,0.100000},{0.437500,0.462500,0.200000,0.200000},{0.462500,0.462500,0.100000,0.100000},{0.462500,0.462500,0.200000,0.200000},{0.487500,0.462500,0.100000,0.100000},{0.487500,0.462500,0.200000,0.200000},{0.512500,0.462500,0.100000,0.100000},{0.512500,0.462500,0.200000,0.200000},{0.537500,0.462500,0.100000,0.100000},{0.537500,0.462500,0.200000,0.200000},{0.562500,0.462500,0.100000,0.100000},{0.562500,0.462500,0.200000,0.200000},{0.587500,0.462500,0.100000,0.100000},{0.587500,0.462500,0.200000,0.200000},{0.612500,0.462500,0.100000,0.100000},{0.612500,0.462500,0.200000,0.200000},{0.637500,0.462500,0.100000,0.100000},{0.637500,0.462500,0.200000,0.200000},{0.662500,0.462500,0.100000,0.100000},{0.662500,0.462500,0.200000,0.200000},{0.687500,0.462500,0.100000,0.100000},{0.687500,0.462500,0.200000,0.200000},{0.712500,0.462500,0.100000,0.100000},{0.712500,0.462500,0.200000,0.200000},{0.737500,0.462500,0.100000,0.100000},{0.737500,0.462500,0.200000,0.200000},{0.762500,0.462500,0.100000,0.100000},{0.762500,0.462500,0.200000,0.200000},{0.787500,0.462500,0.100000,0.100000},{0.787500,0.462500,0.200000,0.200000},{0.812500,0.462500,0.100000,0.100000},{0.812500,0.462500,0.200000,0.200000},{0.837500,0.462500,0.100000,0.100000},{0.837500,0.462500,0.200000,0.200000},{0.862500,0.462500,0.100000,0.100000},{0.862500,0.462500,0.200000,0.200000},{0.887500,0.462500,0.100000,0.100000},{0.887500,0.462500,0.200000,0.200000},{0.912500,0.462500,0.100000,0.100000},{0.912500,0.462500,0.200000,0.200000},{0.937500,0.462500,0.100000,0.100000},{0.937500,0.462500,0.200000,0.200000},{0.962500,0.462500,0.100000,0.100000},{0.962500,0.462500,0.200000,0.200000},{0.987500,0.462500,0.100000,0.100000},{0.987500,0.462500,0.200000,0.200000},{0.012500,0.487500,0.100000,0.100000},{0.012500,0.487500,0.200000,0.200000},{0.037500,0.487500,0.100000,0.100000},{0.037500,0.487500,0.200000,0.200000},{0.062500,0.487500,0.100000,0.100000},{0.062500,0.487500,0.200000,0.200000},{0.087500,0.487500,0.100000,0.100000},{0.087500,0.487500,0.200000,0.200000},{0.112500,0.487500,0.100000,0.100000},{0.112500,0.487500,0.200000,0.200000},{0.137500,0.487500,0.100000,0.100000},{0.137500,0.487500,0.200000,0.200000},{0.162500,0.487500,0.100000,0.100000},{0.162500,0.487500,0.200000,0.200000},{0.187500,0.487500,0.100000,0.100000},{0.187500,0.487500,0.200000,0.200000},{0.212500,0.487500,0.100000,0.100000},{0.212500,0.487500,0.200000,0.200000},{0.237500,0.487500,0.100000,0.100000},{0.237500,0.487500,0.200000,0.200000},{0.262500,0.487500,0.100000,0.100000},{0.262500,0.487500,0.200000,0.200000},{0.287500,0.487500,0.100000,0.100000},{0.287500,0.487500,0.200000,0.200000},{0.312500,0.487500,0.100000,0.100000},{0.312500,0.487500,0.200000,0.200000},{0.337500,0.487500,0.100000,0.100000},{0.337500,0.487500,0.200000,0.200000},{0.362500,0.487500,0.100000,0.100000},{0.362500,0.487500,0.200000,0.200000},{0.387500,0.487500,0.100000,0.100000},{0.387500,0.487500,0.200000,0.200000},{0.412500,0.487500,0.100000,0.100000},{0.412500,0.487500,0.200000,0.200000},{0.437500,0.487500,0.100000,0.100000},{0.437500,0.487500,0.200000,0.200000},{0.462500,0.487500,0.100000,0.100000},{0.462500,0.487500,0.200000,0.200000},{0.487500,0.487500,0.100000,0.100000},{0.487500,0.487500,0.200000,0.200000},{0.512500,0.487500,0.100000,0.100000},{0.512500,0.487500,0.200000,0.200000},{0.537500,0.487500,0.100000,0.100000},{0.537500,0.487500,0.200000,0.200000},{0.562500,0.487500,0.100000,0.100000},{0.562500,0.487500,0.200000,0.200000},{0.587500,0.487500,0.100000,0.100000},{0.587500,0.487500,0.200000,0.200000},{0.612500,0.487500,0.100000,0.100000},{0.612500,0.487500,0.200000,0.200000},{0.637500,0.487500,0.100000,0.100000},{0.637500,0.487500,0.200000,0.200000},{0.662500,0.487500,0.100000,0.100000},{0.662500,0.487500,0.200000,0.200000},{0.687500,0.487500,0.100000,0.100000},{0.687500,0.487500,0.200000,0.200000},{0.712500,0.487500,0.100000,0.100000},{0.712500,0.487500,0.200000,0.200000},{0.737500,0.487500,0.100000,0.100000},{0.737500,0.487500,0.200000,0.200000},{0.762500,0.487500,0.100000,0.100000},{0.762500,0.487500,0.200000,0.200000},{0.787500,0.487500,0.100000,0.100000},{0.787500,0.487500,0.200000,0.200000},{0.812500,0.487500,0.100000,0.100000},{0.812500,0.487500,0.200000,0.200000},{0.837500,0.487500,0.100000,0.100000},{0.837500,0.487500,0.200000,0.200000},{0.862500,0.487500,0.100000,0.100000},{0.862500,0.487500,0.200000,0.200000},{0.887500,0.487500,0.100000,0.100000},{0.887500,0.487500,0.200000,0.200000},{0.912500,0.487500,0.100000,0.100000},{0.912500,0.487500,0.200000,0.200000},{0.937500,0.487500,0.100000,0.100000},{0.937500,0.487500,0.200000,0.200000},{0.962500,0.487500,0.100000,0.100000},{0.962500,0.487500,0.200000,0.200000},{0.987500,0.487500,0.100000,0.100000},{0.987500,0.487500,0.200000,0.200000},{0.012500,0.512500,0.100000,0.100000},{0.012500,0.512500,0.200000,0.200000},{0.037500,0.512500,0.100000,0.100000},{0.037500,0.512500,0.200000,0.200000},{0.062500,0.512500,0.100000,0.100000},{0.062500,0.512500,0.200000,0.200000},{0.087500,0.512500,0.100000,0.100000},{0.087500,0.512500,0.200000,0.200000},{0.112500,0.512500,0.100000,0.100000},{0.112500,0.512500,0.200000,0.200000},{0.137500,0.512500,0.100000,0.100000},{0.137500,0.512500,0.200000,0.200000},{0.162500,0.512500,0.100000,0.100000},{0.162500,0.512500,0.200000,0.200000},{0.187500,0.512500,0.100000,0.100000},{0.187500,0.512500,0.200000,0.200000},{0.212500,0.512500,0.100000,0.100000},{0.212500,0.512500,0.200000,0.200000},{0.237500,0.512500,0.100000,0.100000},{0.237500,0.512500,0.200000,0.200000},{0.262500,0.512500,0.100000,0.100000},{0.262500,0.512500,0.200000,0.200000},{0.287500,0.512500,0.100000,0.100000},{0.287500,0.512500,0.200000,0.200000},{0.312500,0.512500,0.100000,0.100000},{0.312500,0.512500,0.200000,0.200000},{0.337500,0.512500,0.100000,0.100000},{0.337500,0.512500,0.200000,0.200000},{0.362500,0.512500,0.100000,0.100000},{0.362500,0.512500,0.200000,0.200000},{0.387500,0.512500,0.100000,0.100000},{0.387500,0.512500,0.200000,0.200000},{0.412500,0.512500,0.100000,0.100000},{0.412500,0.512500,0.200000,0.200000},{0.437500,0.512500,0.100000,0.100000},{0.437500,0.512500,0.200000,0.200000},{0.462500,0.512500,0.100000,0.100000},{0.462500,0.512500,0.200000,0.200000},{0.487500,0.512500,0.100000,0.100000},{0.487500,0.512500,0.200000,0.200000},{0.512500,0.512500,0.100000,0.100000},{0.512500,0.512500,0.200000,0.200000},{0.537500,0.512500,0.100000,0.100000},{0.537500,0.512500,0.200000,0.200000},{0.562500,0.512500,0.100000,0.100000},{0.562500,0.512500,0.200000,0.200000},{0.587500,0.512500,0.100000,0.100000},{0.587500,0.512500,0.200000,0.200000},{0.612500,0.512500,0.100000,0.100000},{0.612500,0.512500,0.200000,0.200000},{0.637500,0.512500,0.100000,0.100000},{0.637500,0.512500,0.200000,0.200000},{0.662500,0.512500,0.100000,0.100000},{0.662500,0.512500,0.200000,0.200000},{0.687500,0.512500,0.100000,0.100000},{0.687500,0.512500,0.200000,0.200000},{0.712500,0.512500,0.100000,0.100000},{0.712500,0.512500,0.200000,0.200000},{0.737500,0.512500,0.100000,0.100000},{0.737500,0.512500,0.200000,0.200000},{0.762500,0.512500,0.100000,0.100000},{0.762500,0.512500,0.200000,0.200000},{0.787500,0.512500,0.100000,0.100000},{0.787500,0.512500,0.200000,0.200000},{0.812500,0.512500,0.100000,0.100000},{0.812500,0.512500,0.200000,0.200000},{0.837500,0.512500,0.100000,0.100000},{0.837500,0.512500,0.200000,0.200000},{0.862500,0.512500,0.100000,0.100000},{0.862500,0.512500,0.200000,0.200000},{0.887500,0.512500,0.100000,0.100000},{0.887500,0.512500,0.200000,0.200000},{0.912500,0.512500,0.100000,0.100000},{0.912500,0.512500,0.200000,0.200000},{0.937500,0.512500,0.100000,0.100000},{0.937500,0.512500,0.200000,0.200000},{0.962500,0.512500,0.100000,0.100000},{0.962500,0.512500,0.200000,0.200000},{0.987500,0.512500,0.100000,0.100000},{0.987500,0.512500,0.200000,0.200000},{0.012500,0.537500,0.100000,0.100000},{0.012500,0.537500,0.200000,0.200000},{0.037500,0.537500,0.100000,0.100000},{0.037500,0.537500,0.200000,0.200000},{0.062500,0.537500,0.100000,0.100000},{0.062500,0.537500,0.200000,0.200000},{0.087500,0.537500,0.100000,0.100000},{0.087500,0.537500,0.200000,0.200000},{0.112500,0.537500,0.100000,0.100000},{0.112500,0.537500,0.200000,0.200000},{0.137500,0.537500,0.100000,0.100000},{0.137500,0.537500,0.200000,0.200000},{0.162500,0.537500,0.100000,0.100000},{0.162500,0.537500,0.200000,0.200000},{0.187500,0.537500,0.100000,0.100000},{0.187500,0.537500,0.200000,0.200000},{0.212500,0.537500,0.100000,0.100000},{0.212500,0.537500,0.200000,0.200000},{0.237500,0.537500,0.100000,0.100000},{0.237500,0.537500,0.200000,0.200000},{0.262500,0.537500,0.100000,0.100000},{0.262500,0.537500,0.200000,0.200000},{0.287500,0.537500,0.100000,0.100000},{0.287500,0.537500,0.200000,0.200000},{0.312500,0.537500,0.100000,0.100000},{0.312500,0.537500,0.200000,0.200000},{0.337500,0.537500,0.100000,0.100000},{0.337500,0.537500,0.200000,0.200000},{0.362500,0.537500,0.100000,0.100000},{0.362500,0.537500,0.200000,0.200000},{0.387500,0.537500,0.100000,0.100000},{0.387500,0.537500,0.200000,0.200000},{0.412500,0.537500,0.100000,0.100000},{0.412500,0.537500,0.200000,0.200000},{0.437500,0.537500,0.100000,0.100000},{0.437500,0.537500,0.200000,0.200000},{0.462500,0.537500,0.100000,0.100000},{0.462500,0.537500,0.200000,0.200000},{0.487500,0.537500,0.100000,0.100000},{0.487500,0.537500,0.200000,0.200000},{0.512500,0.537500,0.100000,0.100000},{0.512500,0.537500,0.200000,0.200000},{0.537500,0.537500,0.100000,0.100000},{0.537500,0.537500,0.200000,0.200000},{0.562500,0.537500,0.100000,0.100000},{0.562500,0.537500,0.200000,0.200000},{0.587500,0.537500,0.100000,0.100000},{0.587500,0.537500,0.200000,0.200000},{0.612500,0.537500,0.100000,0.100000},{0.612500,0.537500,0.200000,0.200000},{0.637500,0.537500,0.100000,0.100000},{0.637500,0.537500,0.200000,0.200000},{0.662500,0.537500,0.100000,0.100000},{0.662500,0.537500,0.200000,0.200000},{0.687500,0.537500,0.100000,0.100000},{0.687500,0.537500,0.200000,0.200000},{0.712500,0.537500,0.100000,0.100000},{0.712500,0.537500,0.200000,0.200000},{0.737500,0.537500,0.100000,0.100000},{0.737500,0.537500,0.200000,0.200000},{0.762500,0.537500,0.100000,0.100000},{0.762500,0.537500,0.200000,0.200000},{0.787500,0.537500,0.100000,0.100000},{0.787500,0.537500,0.200000,0.200000},{0.812500,0.537500,0.100000,0.100000},{0.812500,0.537500,0.200000,0.200000},{0.837500,0.537500,0.100000,0.100000},{0.837500,0.537500,0.200000,0.200000},{0.862500,0.537500,0.100000,0.100000},{0.862500,0.537500,0.200000,0.200000},{0.887500,0.537500,0.100000,0.100000},{0.887500,0.537500,0.200000,0.200000},{0.912500,0.537500,0.100000,0.100000},{0.912500,0.537500,0.200000,0.200000},{0.937500,0.537500,0.100000,0.100000},{0.937500,0.537500,0.200000,0.200000},{0.962500,0.537500,0.100000,0.100000},{0.962500,0.537500,0.200000,0.200000},{0.987500,0.537500,0.100000,0.100000},{0.987500,0.537500,0.200000,0.200000},{0.012500,0.562500,0.100000,0.100000},{0.012500,0.562500,0.200000,0.200000},{0.037500,0.562500,0.100000,0.100000},{0.037500,0.562500,0.200000,0.200000},{0.062500,0.562500,0.100000,0.100000},{0.062500,0.562500,0.200000,0.200000},{0.087500,0.562500,0.100000,0.100000},{0.087500,0.562500,0.200000,0.200000},{0.112500,0.562500,0.100000,0.100000},{0.112500,0.562500,0.200000,0.200000},{0.137500,0.562500,0.100000,0.100000},{0.137500,0.562500,0.200000,0.200000},{0.162500,0.562500,0.100000,0.100000},{0.162500,0.562500,0.200000,0.200000},{0.187500,0.562500,0.100000,0.100000},{0.187500,0.562500,0.200000,0.200000},{0.212500,0.562500,0.100000,0.100000},{0.212500,0.562500,0.200000,0.200000},{0.237500,0.562500,0.100000,0.100000},{0.237500,0.562500,0.200000,0.200000},{0.262500,0.562500,0.100000,0.100000},{0.262500,0.562500,0.200000,0.200000},{0.287500,0.562500,0.100000,0.100000},{0.287500,0.562500,0.200000,0.200000},{0.312500,0.562500,0.100000,0.100000},{0.312500,0.562500,0.200000,0.200000},{0.337500,0.562500,0.100000,0.100000},{0.337500,0.562500,0.200000,0.200000},{0.362500,0.562500,0.100000,0.100000},{0.362500,0.562500,0.200000,0.200000},{0.387500,0.562500,0.100000,0.100000},{0.387500,0.562500,0.200000,0.200000},{0.412500,0.562500,0.100000,0.100000},{0.412500,0.562500,0.200000,0.200000},{0.437500,0.562500,0.100000,0.100000},{0.437500,0.562500,0.200000,0.200000},{0.462500,0.562500,0.100000,0.100000},{0.462500,0.562500,0.200000,0.200000},{0.487500,0.562500,0.100000,0.100000},{0.487500,0.562500,0.200000,0.200000},{0.512500,0.562500,0.100000,0.100000},{0.512500,0.562500,0.200000,0.200000},{0.537500,0.562500,0.100000,0.100000},{0.537500,0.562500,0.200000,0.200000},{0.562500,0.562500,0.100000,0.100000},{0.562500,0.562500,0.200000,0.200000},{0.587500,0.562500,0.100000,0.100000},{0.587500,0.562500,0.200000,0.200000},{0.612500,0.562500,0.100000,0.100000},{0.612500,0.562500,0.200000,0.200000},{0.637500,0.562500,0.100000,0.100000},{0.637500,0.562500,0.200000,0.200000},{0.662500,0.562500,0.100000,0.100000},{0.662500,0.562500,0.200000,0.200000},{0.687500,0.562500,0.100000,0.100000},{0.687500,0.562500,0.200000,0.200000},{0.712500,0.562500,0.100000,0.100000},{0.712500,0.562500,0.200000,0.200000},{0.737500,0.562500,0.100000,0.100000},{0.737500,0.562500,0.200000,0.200000},{0.762500,0.562500,0.100000,0.100000},{0.762500,0.562500,0.200000,0.200000},{0.787500,0.562500,0.100000,0.100000},{0.787500,0.562500,0.200000,0.200000},{0.812500,0.562500,0.100000,0.100000},{0.812500,0.562500,0.200000,0.200000},{0.837500,0.562500,0.100000,0.100000},{0.837500,0.562500,0.200000,0.200000},{0.862500,0.562500,0.100000,0.100000},{0.862500,0.562500,0.200000,0.200000},{0.887500,0.562500,0.100000,0.100000},{0.887500,0.562500,0.200000,0.200000},{0.912500,0.562500,0.100000,0.100000},{0.912500,0.562500,0.200000,0.200000},{0.937500,0.562500,0.100000,0.100000},{0.937500,0.562500,0.200000,0.200000},{0.962500,0.562500,0.100000,0.100000},{0.962500,0.562500,0.200000,0.200000},{0.987500,0.562500,0.100000,0.100000},{0.987500,0.562500,0.200000,0.200000},{0.012500,0.587500,0.100000,0.100000},{0.012500,0.587500,0.200000,0.200000},{0.037500,0.587500,0.100000,0.100000},{0.037500,0.587500,0.200000,0.200000},{0.062500,0.587500,0.100000,0.100000},{0.062500,0.587500,0.200000,0.200000},{0.087500,0.587500,0.100000,0.100000},{0.087500,0.587500,0.200000,0.200000},{0.112500,0.587500,0.100000,0.100000},{0.112500,0.587500,0.200000,0.200000},{0.137500,0.587500,0.100000,0.100000},{0.137500,0.587500,0.200000,0.200000},{0.162500,0.587500,0.100000,0.100000},{0.162500,0.587500,0.200000,0.200000},{0.187500,0.587500,0.100000,0.100000},{0.187500,0.587500,0.200000,0.200000},{0.212500,0.587500,0.100000,0.100000},{0.212500,0.587500,0.200000,0.200000},{0.237500,0.587500,0.100000,0.100000},{0.237500,0.587500,0.200000,0.200000},{0.262500,0.587500,0.100000,0.100000},{0.262500,0.587500,0.200000,0.200000},{0.287500,0.587500,0.100000,0.100000},{0.287500,0.587500,0.200000,0.200000},{0.312500,0.587500,0.100000,0.100000},{0.312500,0.587500,0.200000,0.200000},{0.337500,0.587500,0.100000,0.100000},{0.337500,0.587500,0.200000,0.200000},{0.362500,0.587500,0.100000,0.100000},{0.362500,0.587500,0.200000,0.200000},{0.387500,0.587500,0.100000,0.100000},{0.387500,0.587500,0.200000,0.200000},{0.412500,0.587500,0.100000,0.100000},{0.412500,0.587500,0.200000,0.200000},{0.437500,0.587500,0.100000,0.100000},{0.437500,0.587500,0.200000,0.200000},{0.462500,0.587500,0.100000,0.100000},{0.462500,0.587500,0.200000,0.200000},{0.487500,0.587500,0.100000,0.100000},{0.487500,0.587500,0.200000,0.200000},{0.512500,0.587500,0.100000,0.100000},{0.512500,0.587500,0.200000,0.200000},{0.537500,0.587500,0.100000,0.100000},{0.537500,0.587500,0.200000,0.200000},{0.562500,0.587500,0.100000,0.100000},{0.562500,0.587500,0.200000,0.200000},{0.587500,0.587500,0.100000,0.100000},{0.587500,0.587500,0.200000,0.200000},{0.612500,0.587500,0.100000,0.100000},{0.612500,0.587500,0.200000,0.200000},{0.637500,0.587500,0.100000,0.100000},{0.637500,0.587500,0.200000,0.200000},{0.662500,0.587500,0.100000,0.100000},{0.662500,0.587500,0.200000,0.200000},{0.687500,0.587500,0.100000,0.100000},{0.687500,0.587500,0.200000,0.200000},{0.712500,0.587500,0.100000,0.100000},{0.712500,0.587500,0.200000,0.200000},{0.737500,0.587500,0.100000,0.100000},{0.737500,0.587500,0.200000,0.200000},{0.762500,0.587500,0.100000,0.100000},{0.762500,0.587500,0.200000,0.200000},{0.787500,0.587500,0.100000,0.100000},{0.787500,0.587500,0.200000,0.200000},{0.812500,0.587500,0.100000,0.100000},{0.812500,0.587500,0.200000,0.200000},{0.837500,0.587500,0.100000,0.100000},{0.837500,0.587500,0.200000,0.200000},{0.862500,0.587500,0.100000,0.100000},{0.862500,0.587500,0.200000,0.200000},{0.887500,0.587500,0.100000,0.100000},{0.887500,0.587500,0.200000,0.200000},{0.912500,0.587500,0.100000,0.100000},{0.912500,0.587500,0.200000,0.200000},{0.937500,0.587500,0.100000,0.100000},{0.937500,0.587500,0.200000,0.200000},{0.962500,0.587500,0.100000,0.100000},{0.962500,0.587500,0.200000,0.200000},{0.987500,0.587500,0.100000,0.100000},{0.987500,0.587500,0.200000,0.200000},{0.012500,0.612500,0.100000,0.100000},{0.012500,0.612500,0.200000,0.200000},{0.037500,0.612500,0.100000,0.100000},{0.037500,0.612500,0.200000,0.200000},{0.062500,0.612500,0.100000,0.100000},{0.062500,0.612500,0.200000,0.200000},{0.087500,0.612500,0.100000,0.100000},{0.087500,0.612500,0.200000,0.200000},{0.112500,0.612500,0.100000,0.100000},{0.112500,0.612500,0.200000,0.200000},{0.137500,0.612500,0.100000,0.100000},{0.137500,0.612500,0.200000,0.200000},{0.162500,0.612500,0.100000,0.100000},{0.162500,0.612500,0.200000,0.200000},{0.187500,0.612500,0.100000,0.100000},{0.187500,0.612500,0.200000,0.200000},{0.212500,0.612500,0.100000,0.100000},{0.212500,0.612500,0.200000,0.200000},{0.237500,0.612500,0.100000,0.100000},{0.237500,0.612500,0.200000,0.200000},{0.262500,0.612500,0.100000,0.100000},{0.262500,0.612500,0.200000,0.200000},{0.287500,0.612500,0.100000,0.100000},{0.287500,0.612500,0.200000,0.200000},{0.312500,0.612500,0.100000,0.100000},{0.312500,0.612500,0.200000,0.200000},{0.337500,0.612500,0.100000,0.100000},{0.337500,0.612500,0.200000,0.200000},{0.362500,0.612500,0.100000,0.100000},{0.362500,0.612500,0.200000,0.200000},{0.387500,0.612500,0.100000,0.100000},{0.387500,0.612500,0.200000,0.200000},{0.412500,0.612500,0.100000,0.100000},{0.412500,0.612500,0.200000,0.200000},{0.437500,0.612500,0.100000,0.100000},{0.437500,0.612500,0.200000,0.200000},{0.462500,0.612500,0.100000,0.100000},{0.462500,0.612500,0.200000,0.200000},{0.487500,0.612500,0.100000,0.100000},{0.487500,0.612500,0.200000,0.200000},{0.512500,0.612500,0.100000,0.100000},{0.512500,0.612500,0.200000,0.200000},{0.537500,0.612500,0.100000,0.100000},{0.537500,0.612500,0.200000,0.200000},{0.562500,0.612500,0.100000,0.100000},{0.562500,0.612500,0.200000,0.200000},{0.587500,0.612500,0.100000,0.100000},{0.587500,0.612500,0.200000,0.200000},{0.612500,0.612500,0.100000,0.100000},{0.612500,0.612500,0.200000,0.200000},{0.637500,0.612500,0.100000,0.100000},{0.637500,0.612500,0.200000,0.200000},{0.662500,0.612500,0.100000,0.100000},{0.662500,0.612500,0.200000,0.200000},{0.687500,0.612500,0.100000,0.100000},{0.687500,0.612500,0.200000,0.200000},{0.712500,0.612500,0.100000,0.100000},{0.712500,0.612500,0.200000,0.200000},{0.737500,0.612500,0.100000,0.100000},{0.737500,0.612500,0.200000,0.200000},{0.762500,0.612500,0.100000,0.100000},{0.762500,0.612500,0.200000,0.200000},{0.787500,0.612500,0.100000,0.100000},{0.787500,0.612500,0.200000,0.200000},{0.812500,0.612500,0.100000,0.100000},{0.812500,0.612500,0.200000,0.200000},{0.837500,0.612500,0.100000,0.100000},{0.837500,0.612500,0.200000,0.200000},{0.862500,0.612500,0.100000,0.100000},{0.862500,0.612500,0.200000,0.200000},{0.887500,0.612500,0.100000,0.100000},{0.887500,0.612500,0.200000,0.200000},{0.912500,0.612500,0.100000,0.100000},{0.912500,0.612500,0.200000,0.200000},{0.937500,0.612500,0.100000,0.100000},{0.937500,0.612500,0.200000,0.200000},{0.962500,0.612500,0.100000,0.100000},{0.962500,0.612500,0.200000,0.200000},{0.987500,0.612500,0.100000,0.100000},{0.987500,0.612500,0.200000,0.200000},{0.012500,0.637500,0.100000,0.100000},{0.012500,0.637500,0.200000,0.200000},{0.037500,0.637500,0.100000,0.100000},{0.037500,0.637500,0.200000,0.200000},{0.062500,0.637500,0.100000,0.100000},{0.062500,0.637500,0.200000,0.200000},{0.087500,0.637500,0.100000,0.100000},{0.087500,0.637500,0.200000,0.200000},{0.112500,0.637500,0.100000,0.100000},{0.112500,0.637500,0.200000,0.200000},{0.137500,0.637500,0.100000,0.100000},{0.137500,0.637500,0.200000,0.200000},{0.162500,0.637500,0.100000,0.100000},{0.162500,0.637500,0.200000,0.200000},{0.187500,0.637500,0.100000,0.100000},{0.187500,0.637500,0.200000,0.200000},{0.212500,0.637500,0.100000,0.100000},{0.212500,0.637500,0.200000,0.200000},{0.237500,0.637500,0.100000,0.100000},{0.237500,0.637500,0.200000,0.200000},{0.262500,0.637500,0.100000,0.100000},{0.262500,0.637500,0.200000,0.200000},{0.287500,0.637500,0.100000,0.100000},{0.287500,0.637500,0.200000,0.200000},{0.312500,0.637500,0.100000,0.100000},{0.312500,0.637500,0.200000,0.200000},{0.337500,0.637500,0.100000,0.100000},{0.337500,0.637500,0.200000,0.200000},{0.362500,0.637500,0.100000,0.100000},{0.362500,0.637500,0.200000,0.200000},{0.387500,0.637500,0.100000,0.100000},{0.387500,0.637500,0.200000,0.200000},{0.412500,0.637500,0.100000,0.100000},{0.412500,0.637500,0.200000,0.200000},{0.437500,0.637500,0.100000,0.100000},{0.437500,0.637500,0.200000,0.200000},{0.462500,0.637500,0.100000,0.100000},{0.462500,0.637500,0.200000,0.200000},{0.487500,0.637500,0.100000,0.100000},{0.487500,0.637500,0.200000,0.200000},{0.512500,0.637500,0.100000,0.100000},{0.512500,0.637500,0.200000,0.200000},{0.537500,0.637500,0.100000,0.100000},{0.537500,0.637500,0.200000,0.200000},{0.562500,0.637500,0.100000,0.100000},{0.562500,0.637500,0.200000,0.200000},{0.587500,0.637500,0.100000,0.100000},{0.587500,0.637500,0.200000,0.200000},{0.612500,0.637500,0.100000,0.100000},{0.612500,0.637500,0.200000,0.200000},{0.637500,0.637500,0.100000,0.100000},{0.637500,0.637500,0.200000,0.200000},{0.662500,0.637500,0.100000,0.100000},{0.662500,0.637500,0.200000,0.200000},{0.687500,0.637500,0.100000,0.100000},{0.687500,0.637500,0.200000,0.200000},{0.712500,0.637500,0.100000,0.100000},{0.712500,0.637500,0.200000,0.200000},{0.737500,0.637500,0.100000,0.100000},{0.737500,0.637500,0.200000,0.200000},{0.762500,0.637500,0.100000,0.100000},{0.762500,0.637500,0.200000,0.200000},{0.787500,0.637500,0.100000,0.100000},{0.787500,0.637500,0.200000,0.200000},{0.812500,0.637500,0.100000,0.100000},{0.812500,0.637500,0.200000,0.200000},{0.837500,0.637500,0.100000,0.100000},{0.837500,0.637500,0.200000,0.200000},{0.862500,0.637500,0.100000,0.100000},{0.862500,0.637500,0.200000,0.200000},{0.887500,0.637500,0.100000,0.100000},{0.887500,0.637500,0.200000,0.200000},{0.912500,0.637500,0.100000,0.100000},{0.912500,0.637500,0.200000,0.200000},{0.937500,0.637500,0.100000,0.100000},{0.937500,0.637500,0.200000,0.200000},{0.962500,0.637500,0.100000,0.100000},{0.962500,0.637500,0.200000,0.200000},{0.987500,0.637500,0.100000,0.100000},{0.987500,0.637500,0.200000,0.200000},{0.012500,0.662500,0.100000,0.100000},{0.012500,0.662500,0.200000,0.200000},{0.037500,0.662500,0.100000,0.100000},{0.037500,0.662500,0.200000,0.200000},{0.062500,0.662500,0.100000,0.100000},{0.062500,0.662500,0.200000,0.200000},{0.087500,0.662500,0.100000,0.100000},{0.087500,0.662500,0.200000,0.200000},{0.112500,0.662500,0.100000,0.100000},{0.112500,0.662500,0.200000,0.200000},{0.137500,0.662500,0.100000,0.100000},{0.137500,0.662500,0.200000,0.200000},{0.162500,0.662500,0.100000,0.100000},{0.162500,0.662500,0.200000,0.200000},{0.187500,0.662500,0.100000,0.100000},{0.187500,0.662500,0.200000,0.200000},{0.212500,0.662500,0.100000,0.100000},{0.212500,0.662500,0.200000,0.200000},{0.237500,0.662500,0.100000,0.100000},{0.237500,0.662500,0.200000,0.200000},{0.262500,0.662500,0.100000,0.100000},{0.262500,0.662500,0.200000,0.200000},{0.287500,0.662500,0.100000,0.100000},{0.287500,0.662500,0.200000,0.200000},{0.312500,0.662500,0.100000,0.100000},{0.312500,0.662500,0.200000,0.200000},{0.337500,0.662500,0.100000,0.100000},{0.337500,0.662500,0.200000,0.200000},{0.362500,0.662500,0.100000,0.100000},{0.362500,0.662500,0.200000,0.200000},{0.387500,0.662500,0.100000,0.100000},{0.387500,0.662500,0.200000,0.200000},{0.412500,0.662500,0.100000,0.100000},{0.412500,0.662500,0.200000,0.200000},{0.437500,0.662500,0.100000,0.100000},{0.437500,0.662500,0.200000,0.200000},{0.462500,0.662500,0.100000,0.100000},{0.462500,0.662500,0.200000,0.200000},{0.487500,0.662500,0.100000,0.100000},{0.487500,0.662500,0.200000,0.200000},{0.512500,0.662500,0.100000,0.100000},{0.512500,0.662500,0.200000,0.200000},{0.537500,0.662500,0.100000,0.100000},{0.537500,0.662500,0.200000,0.200000},{0.562500,0.662500,0.100000,0.100000},{0.562500,0.662500,0.200000,0.200000},{0.587500,0.662500,0.100000,0.100000},{0.587500,0.662500,0.200000,0.200000},{0.612500,0.662500,0.100000,0.100000},{0.612500,0.662500,0.200000,0.200000},{0.637500,0.662500,0.100000,0.100000},{0.637500,0.662500,0.200000,0.200000},{0.662500,0.662500,0.100000,0.100000},{0.662500,0.662500,0.200000,0.200000},{0.687500,0.662500,0.100000,0.100000},{0.687500,0.662500,0.200000,0.200000},{0.712500,0.662500,0.100000,0.100000},{0.712500,0.662500,0.200000,0.200000},{0.737500,0.662500,0.100000,0.100000},{0.737500,0.662500,0.200000,0.200000},{0.762500,0.662500,0.100000,0.100000},{0.762500,0.662500,0.200000,0.200000},{0.787500,0.662500,0.100000,0.100000},{0.787500,0.662500,0.200000,0.200000},{0.812500,0.662500,0.100000,0.100000},{0.812500,0.662500,0.200000,0.200000},{0.837500,0.662500,0.100000,0.100000},{0.837500,0.662500,0.200000,0.200000},{0.862500,0.662500,0.100000,0.100000},{0.862500,0.662500,0.200000,0.200000},{0.887500,0.662500,0.100000,0.100000},{0.887500,0.662500,0.200000,0.200000},{0.912500,0.662500,0.100000,0.100000},{0.912500,0.662500,0.200000,0.200000},{0.937500,0.662500,0.100000,0.100000},{0.937500,0.662500,0.200000,0.200000},{0.962500,0.662500,0.100000,0.100000},{0.962500,0.662500,0.200000,0.200000},{0.987500,0.662500,0.100000,0.100000},{0.987500,0.662500,0.200000,0.200000},{0.012500,0.687500,0.100000,0.100000},{0.012500,0.687500,0.200000,0.200000},{0.037500,0.687500,0.100000,0.100000},{0.037500,0.687500,0.200000,0.200000},{0.062500,0.687500,0.100000,0.100000},{0.062500,0.687500,0.200000,0.200000},{0.087500,0.687500,0.100000,0.100000},{0.087500,0.687500,0.200000,0.200000},{0.112500,0.687500,0.100000,0.100000},{0.112500,0.687500,0.200000,0.200000},{0.137500,0.687500,0.100000,0.100000},{0.137500,0.687500,0.200000,0.200000},{0.162500,0.687500,0.100000,0.100000},{0.162500,0.687500,0.200000,0.200000},{0.187500,0.687500,0.100000,0.100000},{0.187500,0.687500,0.200000,0.200000},{0.212500,0.687500,0.100000,0.100000},{0.212500,0.687500,0.200000,0.200000},{0.237500,0.687500,0.100000,0.100000},{0.237500,0.687500,0.200000,0.200000},{0.262500,0.687500,0.100000,0.100000},{0.262500,0.687500,0.200000,0.200000},{0.287500,0.687500,0.100000,0.100000},{0.287500,0.687500,0.200000,0.200000},{0.312500,0.687500,0.100000,0.100000},{0.312500,0.687500,0.200000,0.200000},{0.337500,0.687500,0.100000,0.100000},{0.337500,0.687500,0.200000,0.200000},{0.362500,0.687500,0.100000,0.100000},{0.362500,0.687500,0.200000,0.200000},{0.387500,0.687500,0.100000,0.100000},{0.387500,0.687500,0.200000,0.200000},{0.412500,0.687500,0.100000,0.100000},{0.412500,0.687500,0.200000,0.200000},{0.437500,0.687500,0.100000,0.100000},{0.437500,0.687500,0.200000,0.200000},{0.462500,0.687500,0.100000,0.100000},{0.462500,0.687500,0.200000,0.200000},{0.487500,0.687500,0.100000,0.100000},{0.487500,0.687500,0.200000,0.200000},{0.512500,0.687500,0.100000,0.100000},{0.512500,0.687500,0.200000,0.200000},{0.537500,0.687500,0.100000,0.100000},{0.537500,0.687500,0.200000,0.200000},{0.562500,0.687500,0.100000,0.100000},{0.562500,0.687500,0.200000,0.200000},{0.587500,0.687500,0.100000,0.100000},{0.587500,0.687500,0.200000,0.200000},{0.612500,0.687500,0.100000,0.100000},{0.612500,0.687500,0.200000,0.200000},{0.637500,0.687500,0.100000,0.100000},{0.637500,0.687500,0.200000,0.200000},{0.662500,0.687500,0.100000,0.100000},{0.662500,0.687500,0.200000,0.200000},{0.687500,0.687500,0.100000,0.100000},{0.687500,0.687500,0.200000,0.200000},{0.712500,0.687500,0.100000,0.100000},{0.712500,0.687500,0.200000,0.200000},{0.737500,0.687500,0.100000,0.100000},{0.737500,0.687500,0.200000,0.200000},{0.762500,0.687500,0.100000,0.100000},{0.762500,0.687500,0.200000,0.200000},{0.787500,0.687500,0.100000,0.100000},{0.787500,0.687500,0.200000,0.200000},{0.812500,0.687500,0.100000,0.100000},{0.812500,0.687500,0.200000,0.200000},{0.837500,0.687500,0.100000,0.100000},{0.837500,0.687500,0.200000,0.200000},{0.862500,0.687500,0.100000,0.100000},{0.862500,0.687500,0.200000,0.200000},{0.887500,0.687500,0.100000,0.100000},{0.887500,0.687500,0.200000,0.200000},{0.912500,0.687500,0.100000,0.100000},{0.912500,0.687500,0.200000,0.200000},{0.937500,0.687500,0.100000,0.100000},{0.937500,0.687500,0.200000,0.200000},{0.962500,0.687500,0.100000,0.100000},{0.962500,0.687500,0.200000,0.200000},{0.987500,0.687500,0.100000,0.100000},{0.987500,0.687500,0.200000,0.200000},{0.012500,0.712500,0.100000,0.100000},{0.012500,0.712500,0.200000,0.200000},{0.037500,0.712500,0.100000,0.100000},{0.037500,0.712500,0.200000,0.200000},{0.062500,0.712500,0.100000,0.100000},{0.062500,0.712500,0.200000,0.200000},{0.087500,0.712500,0.100000,0.100000},{0.087500,0.712500,0.200000,0.200000},{0.112500,0.712500,0.100000,0.100000},{0.112500,0.712500,0.200000,0.200000},{0.137500,0.712500,0.100000,0.100000},{0.137500,0.712500,0.200000,0.200000},{0.162500,0.712500,0.100000,0.100000},{0.162500,0.712500,0.200000,0.200000},{0.187500,0.712500,0.100000,0.100000},{0.187500,0.712500,0.200000,0.200000},{0.212500,0.712500,0.100000,0.100000},{0.212500,0.712500,0.200000,0.200000},{0.237500,0.712500,0.100000,0.100000},{0.237500,0.712500,0.200000,0.200000},{0.262500,0.712500,0.100000,0.100000},{0.262500,0.712500,0.200000,0.200000},{0.287500,0.712500,0.100000,0.100000},{0.287500,0.712500,0.200000,0.200000},{0.312500,0.712500,0.100000,0.100000},{0.312500,0.712500,0.200000,0.200000},{0.337500,0.712500,0.100000,0.100000},{0.337500,0.712500,0.200000,0.200000},{0.362500,0.712500,0.100000,0.100000},{0.362500,0.712500,0.200000,0.200000},{0.387500,0.712500,0.100000,0.100000},{0.387500,0.712500,0.200000,0.200000},{0.412500,0.712500,0.100000,0.100000},{0.412500,0.712500,0.200000,0.200000},{0.437500,0.712500,0.100000,0.100000},{0.437500,0.712500,0.200000,0.200000},{0.462500,0.712500,0.100000,0.100000},{0.462500,0.712500,0.200000,0.200000},{0.487500,0.712500,0.100000,0.100000},{0.487500,0.712500,0.200000,0.200000},{0.512500,0.712500,0.100000,0.100000},{0.512500,0.712500,0.200000,0.200000},{0.537500,0.712500,0.100000,0.100000},{0.537500,0.712500,0.200000,0.200000},{0.562500,0.712500,0.100000,0.100000},{0.562500,0.712500,0.200000,0.200000},{0.587500,0.712500,0.100000,0.100000},{0.587500,0.712500,0.200000,0.200000},{0.612500,0.712500,0.100000,0.100000},{0.612500,0.712500,0.200000,0.200000},{0.637500,0.712500,0.100000,0.100000},{0.637500,0.712500,0.200000,0.200000},{0.662500,0.712500,0.100000,0.100000},{0.662500,0.712500,0.200000,0.200000},{0.687500,0.712500,0.100000,0.100000},{0.687500,0.712500,0.200000,0.200000},{0.712500,0.712500,0.100000,0.100000},{0.712500,0.712500,0.200000,0.200000},{0.737500,0.712500,0.100000,0.100000},{0.737500,0.712500,0.200000,0.200000},{0.762500,0.712500,0.100000,0.100000},{0.762500,0.712500,0.200000,0.200000},{0.787500,0.712500,0.100000,0.100000},{0.787500,0.712500,0.200000,0.200000},{0.812500,0.712500,0.100000,0.100000},{0.812500,0.712500,0.200000,0.200000},{0.837500,0.712500,0.100000,0.100000},{0.837500,0.712500,0.200000,0.200000},{0.862500,0.712500,0.100000,0.100000},{0.862500,0.712500,0.200000,0.200000},{0.887500,0.712500,0.100000,0.100000},{0.887500,0.712500,0.200000,0.200000},{0.912500,0.712500,0.100000,0.100000},{0.912500,0.712500,0.200000,0.200000},{0.937500,0.712500,0.100000,0.100000},{0.937500,0.712500,0.200000,0.200000},{0.962500,0.712500,0.100000,0.100000},{0.962500,0.712500,0.200000,0.200000},{0.987500,0.712500,0.100000,0.100000},{0.987500,0.712500,0.200000,0.200000},{0.012500,0.737500,0.100000,0.100000},{0.012500,0.737500,0.200000,0.200000},{0.037500,0.737500,0.100000,0.100000},{0.037500,0.737500,0.200000,0.200000},{0.062500,0.737500,0.100000,0.100000},{0.062500,0.737500,0.200000,0.200000},{0.087500,0.737500,0.100000,0.100000},{0.087500,0.737500,0.200000,0.200000},{0.112500,0.737500,0.100000,0.100000},{0.112500,0.737500,0.200000,0.200000},{0.137500,0.737500,0.100000,0.100000},{0.137500,0.737500,0.200000,0.200000},{0.162500,0.737500,0.100000,0.100000},{0.162500,0.737500,0.200000,0.200000},{0.187500,0.737500,0.100000,0.100000},{0.187500,0.737500,0.200000,0.200000},{0.212500,0.737500,0.100000,0.100000},{0.212500,0.737500,0.200000,0.200000},{0.237500,0.737500,0.100000,0.100000},{0.237500,0.737500,0.200000,0.200000},{0.262500,0.737500,0.100000,0.100000},{0.262500,0.737500,0.200000,0.200000},{0.287500,0.737500,0.100000,0.100000},{0.287500,0.737500,0.200000,0.200000},{0.312500,0.737500,0.100000,0.100000},{0.312500,0.737500,0.200000,0.200000},{0.337500,0.737500,0.100000,0.100000},{0.337500,0.737500,0.200000,0.200000},{0.362500,0.737500,0.100000,0.100000},{0.362500,0.737500,0.200000,0.200000},{0.387500,0.737500,0.100000,0.100000},{0.387500,0.737500,0.200000,0.200000},{0.412500,0.737500,0.100000,0.100000},{0.412500,0.737500,0.200000,0.200000},{0.437500,0.737500,0.100000,0.100000},{0.437500,0.737500,0.200000,0.200000},{0.462500,0.737500,0.100000,0.100000},{0.462500,0.737500,0.200000,0.200000},{0.487500,0.737500,0.100000,0.100000},{0.487500,0.737500,0.200000,0.200000},{0.512500,0.737500,0.100000,0.100000},{0.512500,0.737500,0.200000,0.200000},{0.537500,0.737500,0.100000,0.100000},{0.537500,0.737500,0.200000,0.200000},{0.562500,0.737500,0.100000,0.100000},{0.562500,0.737500,0.200000,0.200000},{0.587500,0.737500,0.100000,0.100000},{0.587500,0.737500,0.200000,0.200000},{0.612500,0.737500,0.100000,0.100000},{0.612500,0.737500,0.200000,0.200000},{0.637500,0.737500,0.100000,0.100000},{0.637500,0.737500,0.200000,0.200000},{0.662500,0.737500,0.100000,0.100000},{0.662500,0.737500,0.200000,0.200000},{0.687500,0.737500,0.100000,0.100000},{0.687500,0.737500,0.200000,0.200000},{0.712500,0.737500,0.100000,0.100000},{0.712500,0.737500,0.200000,0.200000},{0.737500,0.737500,0.100000,0.100000},{0.737500,0.737500,0.200000,0.200000},{0.762500,0.737500,0.100000,0.100000},{0.762500,0.737500,0.200000,0.200000},{0.787500,0.737500,0.100000,0.100000},{0.787500,0.737500,0.200000,0.200000},{0.812500,0.737500,0.100000,0.100000},{0.812500,0.737500,0.200000,0.200000},{0.837500,0.737500,0.100000,0.100000},{0.837500,0.737500,0.200000,0.200000},{0.862500,0.737500,0.100000,0.100000},{0.862500,0.737500,0.200000,0.200000},{0.887500,0.737500,0.100000,0.100000},{0.887500,0.737500,0.200000,0.200000},{0.912500,0.737500,0.100000,0.100000},{0.912500,0.737500,0.200000,0.200000},{0.937500,0.737500,0.100000,0.100000},{0.937500,0.737500,0.200000,0.200000},{0.962500,0.737500,0.100000,0.100000},{0.962500,0.737500,0.200000,0.200000},{0.987500,0.737500,0.100000,0.100000},{0.987500,0.737500,0.200000,0.200000},{0.012500,0.762500,0.100000,0.100000},{0.012500,0.762500,0.200000,0.200000},{0.037500,0.762500,0.100000,0.100000},{0.037500,0.762500,0.200000,0.200000},{0.062500,0.762500,0.100000,0.100000},{0.062500,0.762500,0.200000,0.200000},{0.087500,0.762500,0.100000,0.100000},{0.087500,0.762500,0.200000,0.200000},{0.112500,0.762500,0.100000,0.100000},{0.112500,0.762500,0.200000,0.200000},{0.137500,0.762500,0.100000,0.100000},{0.137500,0.762500,0.200000,0.200000},{0.162500,0.762500,0.100000,0.100000},{0.162500,0.762500,0.200000,0.200000},{0.187500,0.762500,0.100000,0.100000},{0.187500,0.762500,0.200000,0.200000},{0.212500,0.762500,0.100000,0.100000},{0.212500,0.762500,0.200000,0.200000},{0.237500,0.762500,0.100000,0.100000},{0.237500,0.762500,0.200000,0.200000},{0.262500,0.762500,0.100000,0.100000},{0.262500,0.762500,0.200000,0.200000},{0.287500,0.762500,0.100000,0.100000},{0.287500,0.762500,0.200000,0.200000},{0.312500,0.762500,0.100000,0.100000},{0.312500,0.762500,0.200000,0.200000},{0.337500,0.762500,0.100000,0.100000},{0.337500,0.762500,0.200000,0.200000},{0.362500,0.762500,0.100000,0.100000},{0.362500,0.762500,0.200000,0.200000},{0.387500,0.762500,0.100000,0.100000},{0.387500,0.762500,0.200000,0.200000},{0.412500,0.762500,0.100000,0.100000},{0.412500,0.762500,0.200000,0.200000},{0.437500,0.762500,0.100000,0.100000},{0.437500,0.762500,0.200000,0.200000},{0.462500,0.762500,0.100000,0.100000},{0.462500,0.762500,0.200000,0.200000},{0.487500,0.762500,0.100000,0.100000},{0.487500,0.762500,0.200000,0.200000},{0.512500,0.762500,0.100000,0.100000},{0.512500,0.762500,0.200000,0.200000},{0.537500,0.762500,0.100000,0.100000},{0.537500,0.762500,0.200000,0.200000},{0.562500,0.762500,0.100000,0.100000},{0.562500,0.762500,0.200000,0.200000},{0.587500,0.762500,0.100000,0.100000},{0.587500,0.762500,0.200000,0.200000},{0.612500,0.762500,0.100000,0.100000},{0.612500,0.762500,0.200000,0.200000},{0.637500,0.762500,0.100000,0.100000},{0.637500,0.762500,0.200000,0.200000},{0.662500,0.762500,0.100000,0.100000},{0.662500,0.762500,0.200000,0.200000},{0.687500,0.762500,0.100000,0.100000},{0.687500,0.762500,0.200000,0.200000},{0.712500,0.762500,0.100000,0.100000},{0.712500,0.762500,0.200000,0.200000},{0.737500,0.762500,0.100000,0.100000},{0.737500,0.762500,0.200000,0.200000},{0.762500,0.762500,0.100000,0.100000},{0.762500,0.762500,0.200000,0.200000},{0.787500,0.762500,0.100000,0.100000},{0.787500,0.762500,0.200000,0.200000},{0.812500,0.762500,0.100000,0.100000},{0.812500,0.762500,0.200000,0.200000},{0.837500,0.762500,0.100000,0.100000},{0.837500,0.762500,0.200000,0.200000},{0.862500,0.762500,0.100000,0.100000},{0.862500,0.762500,0.200000,0.200000},{0.887500,0.762500,0.100000,0.100000},{0.887500,0.762500,0.200000,0.200000},{0.912500,0.762500,0.100000,0.100000},{0.912500,0.762500,0.200000,0.200000},{0.937500,0.762500,0.100000,0.100000},{0.937500,0.762500,0.200000,0.200000},{0.962500,0.762500,0.100000,0.100000},{0.962500,0.762500,0.200000,0.200000},{0.987500,0.762500,0.100000,0.100000},{0.987500,0.762500,0.200000,0.200000},{0.012500,0.787500,0.100000,0.100000},{0.012500,0.787500,0.200000,0.200000},{0.037500,0.787500,0.100000,0.100000},{0.037500,0.787500,0.200000,0.200000},{0.062500,0.787500,0.100000,0.100000},{0.062500,0.787500,0.200000,0.200000},{0.087500,0.787500,0.100000,0.100000},{0.087500,0.787500,0.200000,0.200000},{0.112500,0.787500,0.100000,0.100000},{0.112500,0.787500,0.200000,0.200000},{0.137500,0.787500,0.100000,0.100000},{0.137500,0.787500,0.200000,0.200000},{0.162500,0.787500,0.100000,0.100000},{0.162500,0.787500,0.200000,0.200000},{0.187500,0.787500,0.100000,0.100000},{0.187500,0.787500,0.200000,0.200000},{0.212500,0.787500,0.100000,0.100000},{0.212500,0.787500,0.200000,0.200000},{0.237500,0.787500,0.100000,0.100000},{0.237500,0.787500,0.200000,0.200000},{0.262500,0.787500,0.100000,0.100000},{0.262500,0.787500,0.200000,0.200000},{0.287500,0.787500,0.100000,0.100000},{0.287500,0.787500,0.200000,0.200000},{0.312500,0.787500,0.100000,0.100000},{0.312500,0.787500,0.200000,0.200000},{0.337500,0.787500,0.100000,0.100000},{0.337500,0.787500,0.200000,0.200000},{0.362500,0.787500,0.100000,0.100000},{0.362500,0.787500,0.200000,0.200000},{0.387500,0.787500,0.100000,0.100000},{0.387500,0.787500,0.200000,0.200000},{0.412500,0.787500,0.100000,0.100000},{0.412500,0.787500,0.200000,0.200000},{0.437500,0.787500,0.100000,0.100000},{0.437500,0.787500,0.200000,0.200000},{0.462500,0.787500,0.100000,0.100000},{0.462500,0.787500,0.200000,0.200000},{0.487500,0.787500,0.100000,0.100000},{0.487500,0.787500,0.200000,0.200000},{0.512500,0.787500,0.100000,0.100000},{0.512500,0.787500,0.200000,0.200000},{0.537500,0.787500,0.100000,0.100000},{0.537500,0.787500,0.200000,0.200000},{0.562500,0.787500,0.100000,0.100000},{0.562500,0.787500,0.200000,0.200000},{0.587500,0.787500,0.100000,0.100000},{0.587500,0.787500,0.200000,0.200000},{0.612500,0.787500,0.100000,0.100000},{0.612500,0.787500,0.200000,0.200000},{0.637500,0.787500,0.100000,0.100000},{0.637500,0.787500,0.200000,0.200000},{0.662500,0.787500,0.100000,0.100000},{0.662500,0.787500,0.200000,0.200000},{0.687500,0.787500,0.100000,0.100000},{0.687500,0.787500,0.200000,0.200000},{0.712500,0.787500,0.100000,0.100000},{0.712500,0.787500,0.200000,0.200000},{0.737500,0.787500,0.100000,0.100000},{0.737500,0.787500,0.200000,0.200000},{0.762500,0.787500,0.100000,0.100000},{0.762500,0.787500,0.200000,0.200000},{0.787500,0.787500,0.100000,0.100000},{0.787500,0.787500,0.200000,0.200000},{0.812500,0.787500,0.100000,0.100000},{0.812500,0.787500,0.200000,0.200000},{0.837500,0.787500,0.100000,0.100000},{0.837500,0.787500,0.200000,0.200000},{0.862500,0.787500,0.100000,0.100000},{0.862500,0.787500,0.200000,0.200000},{0.887500,0.787500,0.100000,0.100000},{0.887500,0.787500,0.200000,0.200000},{0.912500,0.787500,0.100000,0.100000},{0.912500,0.787500,0.200000,0.200000},{0.937500,0.787500,0.100000,0.100000},{0.937500,0.787500,0.200000,0.200000},{0.962500,0.787500,0.100000,0.100000},{0.962500,0.787500,0.200000,0.200000},{0.987500,0.787500,0.100000,0.100000},{0.987500,0.787500,0.200000,0.200000},{0.012500,0.812500,0.100000,0.100000},{0.012500,0.812500,0.200000,0.200000},{0.037500,0.812500,0.100000,0.100000},{0.037500,0.812500,0.200000,0.200000},{0.062500,0.812500,0.100000,0.100000},{0.062500,0.812500,0.200000,0.200000},{0.087500,0.812500,0.100000,0.100000},{0.087500,0.812500,0.200000,0.200000},{0.112500,0.812500,0.100000,0.100000},{0.112500,0.812500,0.200000,0.200000},{0.137500,0.812500,0.100000,0.100000},{0.137500,0.812500,0.200000,0.200000},{0.162500,0.812500,0.100000,0.100000},{0.162500,0.812500,0.200000,0.200000},{0.187500,0.812500,0.100000,0.100000},{0.187500,0.812500,0.200000,0.200000},{0.212500,0.812500,0.100000,0.100000},{0.212500,0.812500,0.200000,0.200000},{0.237500,0.812500,0.100000,0.100000},{0.237500,0.812500,0.200000,0.200000},{0.262500,0.812500,0.100000,0.100000},{0.262500,0.812500,0.200000,0.200000},{0.287500,0.812500,0.100000,0.100000},{0.287500,0.812500,0.200000,0.200000},{0.312500,0.812500,0.100000,0.100000},{0.312500,0.812500,0.200000,0.200000},{0.337500,0.812500,0.100000,0.100000},{0.337500,0.812500,0.200000,0.200000},{0.362500,0.812500,0.100000,0.100000},{0.362500,0.812500,0.200000,0.200000},{0.387500,0.812500,0.100000,0.100000},{0.387500,0.812500,0.200000,0.200000},{0.412500,0.812500,0.100000,0.100000},{0.412500,0.812500,0.200000,0.200000},{0.437500,0.812500,0.100000,0.100000},{0.437500,0.812500,0.200000,0.200000},{0.462500,0.812500,0.100000,0.100000},{0.462500,0.812500,0.200000,0.200000},{0.487500,0.812500,0.100000,0.100000},{0.487500,0.812500,0.200000,0.200000},{0.512500,0.812500,0.100000,0.100000},{0.512500,0.812500,0.200000,0.200000},{0.537500,0.812500,0.100000,0.100000},{0.537500,0.812500,0.200000,0.200000},{0.562500,0.812500,0.100000,0.100000},{0.562500,0.812500,0.200000,0.200000},{0.587500,0.812500,0.100000,0.100000},{0.587500,0.812500,0.200000,0.200000},{0.612500,0.812500,0.100000,0.100000},{0.612500,0.812500,0.200000,0.200000},{0.637500,0.812500,0.100000,0.100000},{0.637500,0.812500,0.200000,0.200000},{0.662500,0.812500,0.100000,0.100000},{0.662500,0.812500,0.200000,0.200000},{0.687500,0.812500,0.100000,0.100000},{0.687500,0.812500,0.200000,0.200000},{0.712500,0.812500,0.100000,0.100000},{0.712500,0.812500,0.200000,0.200000},{0.737500,0.812500,0.100000,0.100000},{0.737500,0.812500,0.200000,0.200000},{0.762500,0.812500,0.100000,0.100000},{0.762500,0.812500,0.200000,0.200000},{0.787500,0.812500,0.100000,0.100000},{0.787500,0.812500,0.200000,0.200000},{0.812500,0.812500,0.100000,0.100000},{0.812500,0.812500,0.200000,0.200000},{0.837500,0.812500,0.100000,0.100000},{0.837500,0.812500,0.200000,0.200000},{0.862500,0.812500,0.100000,0.100000},{0.862500,0.812500,0.200000,0.200000},{0.887500,0.812500,0.100000,0.100000},{0.887500,0.812500,0.200000,0.200000},{0.912500,0.812500,0.100000,0.100000},{0.912500,0.812500,0.200000,0.200000},{0.937500,0.812500,0.100000,0.100000},{0.937500,0.812500,0.200000,0.200000},{0.962500,0.812500,0.100000,0.100000},{0.962500,0.812500,0.200000,0.200000},{0.987500,0.812500,0.100000,0.100000},{0.987500,0.812500,0.200000,0.200000},{0.012500,0.837500,0.100000,0.100000},{0.012500,0.837500,0.200000,0.200000},{0.037500,0.837500,0.100000,0.100000},{0.037500,0.837500,0.200000,0.200000},{0.062500,0.837500,0.100000,0.100000},{0.062500,0.837500,0.200000,0.200000},{0.087500,0.837500,0.100000,0.100000},{0.087500,0.837500,0.200000,0.200000},{0.112500,0.837500,0.100000,0.100000},{0.112500,0.837500,0.200000,0.200000},{0.137500,0.837500,0.100000,0.100000},{0.137500,0.837500,0.200000,0.200000},{0.162500,0.837500,0.100000,0.100000},{0.162500,0.837500,0.200000,0.200000},{0.187500,0.837500,0.100000,0.100000},{0.187500,0.837500,0.200000,0.200000},{0.212500,0.837500,0.100000,0.100000},{0.212500,0.837500,0.200000,0.200000},{0.237500,0.837500,0.100000,0.100000},{0.237500,0.837500,0.200000,0.200000},{0.262500,0.837500,0.100000,0.100000},{0.262500,0.837500,0.200000,0.200000},{0.287500,0.837500,0.100000,0.100000},{0.287500,0.837500,0.200000,0.200000},{0.312500,0.837500,0.100000,0.100000},{0.312500,0.837500,0.200000,0.200000},{0.337500,0.837500,0.100000,0.100000},{0.337500,0.837500,0.200000,0.200000},{0.362500,0.837500,0.100000,0.100000},{0.362500,0.837500,0.200000,0.200000},{0.387500,0.837500,0.100000,0.100000},{0.387500,0.837500,0.200000,0.200000},{0.412500,0.837500,0.100000,0.100000},{0.412500,0.837500,0.200000,0.200000},{0.437500,0.837500,0.100000,0.100000},{0.437500,0.837500,0.200000,0.200000},{0.462500,0.837500,0.100000,0.100000},{0.462500,0.837500,0.200000,0.200000},{0.487500,0.837500,0.100000,0.100000},{0.487500,0.837500,0.200000,0.200000},{0.512500,0.837500,0.100000,0.100000},{0.512500,0.837500,0.200000,0.200000},{0.537500,0.837500,0.100000,0.100000},{0.537500,0.837500,0.200000,0.200000},{0.562500,0.837500,0.100000,0.100000},{0.562500,0.837500,0.200000,0.200000},{0.587500,0.837500,0.100000,0.100000},{0.587500,0.837500,0.200000,0.200000},{0.612500,0.837500,0.100000,0.100000},{0.612500,0.837500,0.200000,0.200000},{0.637500,0.837500,0.100000,0.100000},{0.637500,0.837500,0.200000,0.200000},{0.662500,0.837500,0.100000,0.100000},{0.662500,0.837500,0.200000,0.200000},{0.687500,0.837500,0.100000,0.100000},{0.687500,0.837500,0.200000,0.200000},{0.712500,0.837500,0.100000,0.100000},{0.712500,0.837500,0.200000,0.200000},{0.737500,0.837500,0.100000,0.100000},{0.737500,0.837500,0.200000,0.200000},{0.762500,0.837500,0.100000,0.100000},{0.762500,0.837500,0.200000,0.200000},{0.787500,0.837500,0.100000,0.100000},{0.787500,0.837500,0.200000,0.200000},{0.812500,0.837500,0.100000,0.100000},{0.812500,0.837500,0.200000,0.200000},{0.837500,0.837500,0.100000,0.100000},{0.837500,0.837500,0.200000,0.200000},{0.862500,0.837500,0.100000,0.100000},{0.862500,0.837500,0.200000,0.200000},{0.887500,0.837500,0.100000,0.100000},{0.887500,0.837500,0.200000,0.200000},{0.912500,0.837500,0.100000,0.100000},{0.912500,0.837500,0.200000,0.200000},{0.937500,0.837500,0.100000,0.100000},{0.937500,0.837500,0.200000,0.200000},{0.962500,0.837500,0.100000,0.100000},{0.962500,0.837500,0.200000,0.200000},{0.987500,0.837500,0.100000,0.100000},{0.987500,0.837500,0.200000,0.200000},{0.012500,0.862500,0.100000,0.100000},{0.012500,0.862500,0.200000,0.200000},{0.037500,0.862500,0.100000,0.100000},{0.037500,0.862500,0.200000,0.200000},{0.062500,0.862500,0.100000,0.100000},{0.062500,0.862500,0.200000,0.200000},{0.087500,0.862500,0.100000,0.100000},{0.087500,0.862500,0.200000,0.200000},{0.112500,0.862500,0.100000,0.100000},{0.112500,0.862500,0.200000,0.200000},{0.137500,0.862500,0.100000,0.100000},{0.137500,0.862500,0.200000,0.200000},{0.162500,0.862500,0.100000,0.100000},{0.162500,0.862500,0.200000,0.200000},{0.187500,0.862500,0.100000,0.100000},{0.187500,0.862500,0.200000,0.200000},{0.212500,0.862500,0.100000,0.100000},{0.212500,0.862500,0.200000,0.200000},{0.237500,0.862500,0.100000,0.100000},{0.237500,0.862500,0.200000,0.200000},{0.262500,0.862500,0.100000,0.100000},{0.262500,0.862500,0.200000,0.200000},{0.287500,0.862500,0.100000,0.100000},{0.287500,0.862500,0.200000,0.200000},{0.312500,0.862500,0.100000,0.100000},{0.312500,0.862500,0.200000,0.200000},{0.337500,0.862500,0.100000,0.100000},{0.337500,0.862500,0.200000,0.200000},{0.362500,0.862500,0.100000,0.100000},{0.362500,0.862500,0.200000,0.200000},{0.387500,0.862500,0.100000,0.100000},{0.387500,0.862500,0.200000,0.200000},{0.412500,0.862500,0.100000,0.100000},{0.412500,0.862500,0.200000,0.200000},{0.437500,0.862500,0.100000,0.100000},{0.437500,0.862500,0.200000,0.200000},{0.462500,0.862500,0.100000,0.100000},{0.462500,0.862500,0.200000,0.200000},{0.487500,0.862500,0.100000,0.100000},{0.487500,0.862500,0.200000,0.200000},{0.512500,0.862500,0.100000,0.100000},{0.512500,0.862500,0.200000,0.200000},{0.537500,0.862500,0.100000,0.100000},{0.537500,0.862500,0.200000,0.200000},{0.562500,0.862500,0.100000,0.100000},{0.562500,0.862500,0.200000,0.200000},{0.587500,0.862500,0.100000,0.100000},{0.587500,0.862500,0.200000,0.200000},{0.612500,0.862500,0.100000,0.100000},{0.612500,0.862500,0.200000,0.200000},{0.637500,0.862500,0.100000,0.100000},{0.637500,0.862500,0.200000,0.200000},{0.662500,0.862500,0.100000,0.100000},{0.662500,0.862500,0.200000,0.200000},{0.687500,0.862500,0.100000,0.100000},{0.687500,0.862500,0.200000,0.200000},{0.712500,0.862500,0.100000,0.100000},{0.712500,0.862500,0.200000,0.200000},{0.737500,0.862500,0.100000,0.100000},{0.737500,0.862500,0.200000,0.200000},{0.762500,0.862500,0.100000,0.100000},{0.762500,0.862500,0.200000,0.200000},{0.787500,0.862500,0.100000,0.100000},{0.787500,0.862500,0.200000,0.200000},{0.812500,0.862500,0.100000,0.100000},{0.812500,0.862500,0.200000,0.200000},{0.837500,0.862500,0.100000,0.100000},{0.837500,0.862500,0.200000,0.200000},{0.862500,0.862500,0.100000,0.100000},{0.862500,0.862500,0.200000,0.200000},{0.887500,0.862500,0.100000,0.100000},{0.887500,0.862500,0.200000,0.200000},{0.912500,0.862500,0.100000,0.100000},{0.912500,0.862500,0.200000,0.200000},{0.937500,0.862500,0.100000,0.100000},{0.937500,0.862500,0.200000,0.200000},{0.962500,0.862500,0.100000,0.100000},{0.962500,0.862500,0.200000,0.200000},{0.987500,0.862500,0.100000,0.100000},{0.987500,0.862500,0.200000,0.200000},{0.012500,0.887500,0.100000,0.100000},{0.012500,0.887500,0.200000,0.200000},{0.037500,0.887500,0.100000,0.100000},{0.037500,0.887500,0.200000,0.200000},{0.062500,0.887500,0.100000,0.100000},{0.062500,0.887500,0.200000,0.200000},{0.087500,0.887500,0.100000,0.100000},{0.087500,0.887500,0.200000,0.200000},{0.112500,0.887500,0.100000,0.100000},{0.112500,0.887500,0.200000,0.200000},{0.137500,0.887500,0.100000,0.100000},{0.137500,0.887500,0.200000,0.200000},{0.162500,0.887500,0.100000,0.100000},{0.162500,0.887500,0.200000,0.200000},{0.187500,0.887500,0.100000,0.100000},{0.187500,0.887500,0.200000,0.200000},{0.212500,0.887500,0.100000,0.100000},{0.212500,0.887500,0.200000,0.200000},{0.237500,0.887500,0.100000,0.100000},{0.237500,0.887500,0.200000,0.200000},{0.262500,0.887500,0.100000,0.100000},{0.262500,0.887500,0.200000,0.200000},{0.287500,0.887500,0.100000,0.100000},{0.287500,0.887500,0.200000,0.200000},{0.312500,0.887500,0.100000,0.100000},{0.312500,0.887500,0.200000,0.200000},{0.337500,0.887500,0.100000,0.100000},{0.337500,0.887500,0.200000,0.200000},{0.362500,0.887500,0.100000,0.100000},{0.362500,0.887500,0.200000,0.200000},{0.387500,0.887500,0.100000,0.100000},{0.387500,0.887500,0.200000,0.200000},{0.412500,0.887500,0.100000,0.100000},{0.412500,0.887500,0.200000,0.200000},{0.437500,0.887500,0.100000,0.100000},{0.437500,0.887500,0.200000,0.200000},{0.462500,0.887500,0.100000,0.100000},{0.462500,0.887500,0.200000,0.200000},{0.487500,0.887500,0.100000,0.100000},{0.487500,0.887500,0.200000,0.200000},{0.512500,0.887500,0.100000,0.100000},{0.512500,0.887500,0.200000,0.200000},{0.537500,0.887500,0.100000,0.100000},{0.537500,0.887500,0.200000,0.200000},{0.562500,0.887500,0.100000,0.100000},{0.562500,0.887500,0.200000,0.200000},{0.587500,0.887500,0.100000,0.100000},{0.587500,0.887500,0.200000,0.200000},{0.612500,0.887500,0.100000,0.100000},{0.612500,0.887500,0.200000,0.200000},{0.637500,0.887500,0.100000,0.100000},{0.637500,0.887500,0.200000,0.200000},{0.662500,0.887500,0.100000,0.100000},{0.662500,0.887500,0.200000,0.200000},{0.687500,0.887500,0.100000,0.100000},{0.687500,0.887500,0.200000,0.200000},{0.712500,0.887500,0.100000,0.100000},{0.712500,0.887500,0.200000,0.200000},{0.737500,0.887500,0.100000,0.100000},{0.737500,0.887500,0.200000,0.200000},{0.762500,0.887500,0.100000,0.100000},{0.762500,0.887500,0.200000,0.200000},{0.787500,0.887500,0.100000,0.100000},{0.787500,0.887500,0.200000,0.200000},{0.812500,0.887500,0.100000,0.100000},{0.812500,0.887500,0.200000,0.200000},{0.837500,0.887500,0.100000,0.100000},{0.837500,0.887500,0.200000,0.200000},{0.862500,0.887500,0.100000,0.100000},{0.862500,0.887500,0.200000,0.200000},{0.887500,0.887500,0.100000,0.100000},{0.887500,0.887500,0.200000,0.200000},{0.912500,0.887500,0.100000,0.100000},{0.912500,0.887500,0.200000,0.200000},{0.937500,0.887500,0.100000,0.100000},{0.937500,0.887500,0.200000,0.200000},{0.962500,0.887500,0.100000,0.100000},{0.962500,0.887500,0.200000,0.200000},{0.987500,0.887500,0.100000,0.100000},{0.987500,0.887500,0.200000,0.200000},{0.012500,0.912500,0.100000,0.100000},{0.012500,0.912500,0.200000,0.200000},{0.037500,0.912500,0.100000,0.100000},{0.037500,0.912500,0.200000,0.200000},{0.062500,0.912500,0.100000,0.100000},{0.062500,0.912500,0.200000,0.200000},{0.087500,0.912500,0.100000,0.100000},{0.087500,0.912500,0.200000,0.200000},{0.112500,0.912500,0.100000,0.100000},{0.112500,0.912500,0.200000,0.200000},{0.137500,0.912500,0.100000,0.100000},{0.137500,0.912500,0.200000,0.200000},{0.162500,0.912500,0.100000,0.100000},{0.162500,0.912500,0.200000,0.200000},{0.187500,0.912500,0.100000,0.100000},{0.187500,0.912500,0.200000,0.200000},{0.212500,0.912500,0.100000,0.100000},{0.212500,0.912500,0.200000,0.200000},{0.237500,0.912500,0.100000,0.100000},{0.237500,0.912500,0.200000,0.200000},{0.262500,0.912500,0.100000,0.100000},{0.262500,0.912500,0.200000,0.200000},{0.287500,0.912500,0.100000,0.100000},{0.287500,0.912500,0.200000,0.200000},{0.312500,0.912500,0.100000,0.100000},{0.312500,0.912500,0.200000,0.200000},{0.337500,0.912500,0.100000,0.100000},{0.337500,0.912500,0.200000,0.200000},{0.362500,0.912500,0.100000,0.100000},{0.362500,0.912500,0.200000,0.200000},{0.387500,0.912500,0.100000,0.100000},{0.387500,0.912500,0.200000,0.200000},{0.412500,0.912500,0.100000,0.100000},{0.412500,0.912500,0.200000,0.200000},{0.437500,0.912500,0.100000,0.100000},{0.437500,0.912500,0.200000,0.200000},{0.462500,0.912500,0.100000,0.100000},{0.462500,0.912500,0.200000,0.200000},{0.487500,0.912500,0.100000,0.100000},{0.487500,0.912500,0.200000,0.200000},{0.512500,0.912500,0.100000,0.100000},{0.512500,0.912500,0.200000,0.200000},{0.537500,0.912500,0.100000,0.100000},{0.537500,0.912500,0.200000,0.200000},{0.562500,0.912500,0.100000,0.100000},{0.562500,0.912500,0.200000,0.200000},{0.587500,0.912500,0.100000,0.100000},{0.587500,0.912500,0.200000,0.200000},{0.612500,0.912500,0.100000,0.100000},{0.612500,0.912500,0.200000,0.200000},{0.637500,0.912500,0.100000,0.100000},{0.637500,0.912500,0.200000,0.200000},{0.662500,0.912500,0.100000,0.100000},{0.662500,0.912500,0.200000,0.200000},{0.687500,0.912500,0.100000,0.100000},{0.687500,0.912500,0.200000,0.200000},{0.712500,0.912500,0.100000,0.100000},{0.712500,0.912500,0.200000,0.200000},{0.737500,0.912500,0.100000,0.100000},{0.737500,0.912500,0.200000,0.200000},{0.762500,0.912500,0.100000,0.100000},{0.762500,0.912500,0.200000,0.200000},{0.787500,0.912500,0.100000,0.100000},{0.787500,0.912500,0.200000,0.200000},{0.812500,0.912500,0.100000,0.100000},{0.812500,0.912500,0.200000,0.200000},{0.837500,0.912500,0.100000,0.100000},{0.837500,0.912500,0.200000,0.200000},{0.862500,0.912500,0.100000,0.100000},{0.862500,0.912500,0.200000,0.200000},{0.887500,0.912500,0.100000,0.100000},{0.887500,0.912500,0.200000,0.200000},{0.912500,0.912500,0.100000,0.100000},{0.912500,0.912500,0.200000,0.200000},{0.937500,0.912500,0.100000,0.100000},{0.937500,0.912500,0.200000,0.200000},{0.962500,0.912500,0.100000,0.100000},{0.962500,0.912500,0.200000,0.200000},{0.987500,0.912500,0.100000,0.100000},{0.987500,0.912500,0.200000,0.200000},{0.012500,0.937500,0.100000,0.100000},{0.012500,0.937500,0.200000,0.200000},{0.037500,0.937500,0.100000,0.100000},{0.037500,0.937500,0.200000,0.200000},{0.062500,0.937500,0.100000,0.100000},{0.062500,0.937500,0.200000,0.200000},{0.087500,0.937500,0.100000,0.100000},{0.087500,0.937500,0.200000,0.200000},{0.112500,0.937500,0.100000,0.100000},{0.112500,0.937500,0.200000,0.200000},{0.137500,0.937500,0.100000,0.100000},{0.137500,0.937500,0.200000,0.200000},{0.162500,0.937500,0.100000,0.100000},{0.162500,0.937500,0.200000,0.200000},{0.187500,0.937500,0.100000,0.100000},{0.187500,0.937500,0.200000,0.200000},{0.212500,0.937500,0.100000,0.100000},{0.212500,0.937500,0.200000,0.200000},{0.237500,0.937500,0.100000,0.100000},{0.237500,0.937500,0.200000,0.200000},{0.262500,0.937500,0.100000,0.100000},{0.262500,0.937500,0.200000,0.200000},{0.287500,0.937500,0.100000,0.100000},{0.287500,0.937500,0.200000,0.200000},{0.312500,0.937500,0.100000,0.100000},{0.312500,0.937500,0.200000,0.200000},{0.337500,0.937500,0.100000,0.100000},{0.337500,0.937500,0.200000,0.200000},{0.362500,0.937500,0.100000,0.100000},{0.362500,0.937500,0.200000,0.200000},{0.387500,0.937500,0.100000,0.100000},{0.387500,0.937500,0.200000,0.200000},{0.412500,0.937500,0.100000,0.100000},{0.412500,0.937500,0.200000,0.200000},{0.437500,0.937500,0.100000,0.100000},{0.437500,0.937500,0.200000,0.200000},{0.462500,0.937500,0.100000,0.100000},{0.462500,0.937500,0.200000,0.200000},{0.487500,0.937500,0.100000,0.100000},{0.487500,0.937500,0.200000,0.200000},{0.512500,0.937500,0.100000,0.100000},{0.512500,0.937500,0.200000,0.200000},{0.537500,0.937500,0.100000,0.100000},{0.537500,0.937500,0.200000,0.200000},{0.562500,0.937500,0.100000,0.100000},{0.562500,0.937500,0.200000,0.200000},{0.587500,0.937500,0.100000,0.100000},{0.587500,0.937500,0.200000,0.200000},{0.612500,0.937500,0.100000,0.100000},{0.612500,0.937500,0.200000,0.200000},{0.637500,0.937500,0.100000,0.100000},{0.637500,0.937500,0.200000,0.200000},{0.662500,0.937500,0.100000,0.100000},{0.662500,0.937500,0.200000,0.200000},{0.687500,0.937500,0.100000,0.100000},{0.687500,0.937500,0.200000,0.200000},{0.712500,0.937500,0.100000,0.100000},{0.712500,0.937500,0.200000,0.200000},{0.737500,0.937500,0.100000,0.100000},{0.737500,0.937500,0.200000,0.200000},{0.762500,0.937500,0.100000,0.100000},{0.762500,0.937500,0.200000,0.200000},{0.787500,0.937500,0.100000,0.100000},{0.787500,0.937500,0.200000,0.200000},{0.812500,0.937500,0.100000,0.100000},{0.812500,0.937500,0.200000,0.200000},{0.837500,0.937500,0.100000,0.100000},{0.837500,0.937500,0.200000,0.200000},{0.862500,0.937500,0.100000,0.100000},{0.862500,0.937500,0.200000,0.200000},{0.887500,0.937500,0.100000,0.100000},{0.887500,0.937500,0.200000,0.200000},{0.912500,0.937500,0.100000,0.100000},{0.912500,0.937500,0.200000,0.200000},{0.937500,0.937500,0.100000,0.100000},{0.937500,0.937500,0.200000,0.200000},{0.962500,0.937500,0.100000,0.100000},{0.962500,0.937500,0.200000,0.200000},{0.987500,0.937500,0.100000,0.100000},{0.987500,0.937500,0.200000,0.200000},{0.012500,0.962500,0.100000,0.100000},{0.012500,0.962500,0.200000,0.200000},{0.037500,0.962500,0.100000,0.100000},{0.037500,0.962500,0.200000,0.200000},{0.062500,0.962500,0.100000,0.100000},{0.062500,0.962500,0.200000,0.200000},{0.087500,0.962500,0.100000,0.100000},{0.087500,0.962500,0.200000,0.200000},{0.112500,0.962500,0.100000,0.100000},{0.112500,0.962500,0.200000,0.200000},{0.137500,0.962500,0.100000,0.100000},{0.137500,0.962500,0.200000,0.200000},{0.162500,0.962500,0.100000,0.100000},{0.162500,0.962500,0.200000,0.200000},{0.187500,0.962500,0.100000,0.100000},{0.187500,0.962500,0.200000,0.200000},{0.212500,0.962500,0.100000,0.100000},{0.212500,0.962500,0.200000,0.200000},{0.237500,0.962500,0.100000,0.100000},{0.237500,0.962500,0.200000,0.200000},{0.262500,0.962500,0.100000,0.100000},{0.262500,0.962500,0.200000,0.200000},{0.287500,0.962500,0.100000,0.100000},{0.287500,0.962500,0.200000,0.200000},{0.312500,0.962500,0.100000,0.100000},{0.312500,0.962500,0.200000,0.200000},{0.337500,0.962500,0.100000,0.100000},{0.337500,0.962500,0.200000,0.200000},{0.362500,0.962500,0.100000,0.100000},{0.362500,0.962500,0.200000,0.200000},{0.387500,0.962500,0.100000,0.100000},{0.387500,0.962500,0.200000,0.200000},{0.412500,0.962500,0.100000,0.100000},{0.412500,0.962500,0.200000,0.200000},{0.437500,0.962500,0.100000,0.100000},{0.437500,0.962500,0.200000,0.200000},{0.462500,0.962500,0.100000,0.100000},{0.462500,0.962500,0.200000,0.200000},{0.487500,0.962500,0.100000,0.100000},{0.487500,0.962500,0.200000,0.200000},{0.512500,0.962500,0.100000,0.100000},{0.512500,0.962500,0.200000,0.200000},{0.537500,0.962500,0.100000,0.100000},{0.537500,0.962500,0.200000,0.200000},{0.562500,0.962500,0.100000,0.100000},{0.562500,0.962500,0.200000,0.200000},{0.587500,0.962500,0.100000,0.100000},{0.587500,0.962500,0.200000,0.200000},{0.612500,0.962500,0.100000,0.100000},{0.612500,0.962500,0.200000,0.200000},{0.637500,0.962500,0.100000,0.100000},{0.637500,0.962500,0.200000,0.200000},{0.662500,0.962500,0.100000,0.100000},{0.662500,0.962500,0.200000,0.200000},{0.687500,0.962500,0.100000,0.100000},{0.687500,0.962500,0.200000,0.200000},{0.712500,0.962500,0.100000,0.100000},{0.712500,0.962500,0.200000,0.200000},{0.737500,0.962500,0.100000,0.100000},{0.737500,0.962500,0.200000,0.200000},{0.762500,0.962500,0.100000,0.100000},{0.762500,0.962500,0.200000,0.200000},{0.787500,0.962500,0.100000,0.100000},{0.787500,0.962500,0.200000,0.200000},{0.812500,0.962500,0.100000,0.100000},{0.812500,0.962500,0.200000,0.200000},{0.837500,0.962500,0.100000,0.100000},{0.837500,0.962500,0.200000,0.200000},{0.862500,0.962500,0.100000,0.100000},{0.862500,0.962500,0.200000,0.200000},{0.887500,0.962500,0.100000,0.100000},{0.887500,0.962500,0.200000,0.200000},{0.912500,0.962500,0.100000,0.100000},{0.912500,0.962500,0.200000,0.200000},{0.937500,0.962500,0.100000,0.100000},{0.937500,0.962500,0.200000,0.200000},{0.962500,0.962500,0.100000,0.100000},{0.962500,0.962500,0.200000,0.200000},{0.987500,0.962500,0.100000,0.100000},{0.987500,0.962500,0.200000,0.200000},{0.012500,0.987500,0.100000,0.100000},{0.012500,0.987500,0.200000,0.200000},{0.037500,0.987500,0.100000,0.100000},{0.037500,0.987500,0.200000,0.200000},{0.062500,0.987500,0.100000,0.100000},{0.062500,0.987500,0.200000,0.200000},{0.087500,0.987500,0.100000,0.100000},{0.087500,0.987500,0.200000,0.200000},{0.112500,0.987500,0.100000,0.100000},{0.112500,0.987500,0.200000,0.200000},{0.137500,0.987500,0.100000,0.100000},{0.137500,0.987500,0.200000,0.200000},{0.162500,0.987500,0.100000,0.100000},{0.162500,0.987500,0.200000,0.200000},{0.187500,0.987500,0.100000,0.100000},{0.187500,0.987500,0.200000,0.200000},{0.212500,0.987500,0.100000,0.100000},{0.212500,0.987500,0.200000,0.200000},{0.237500,0.987500,0.100000,0.100000},{0.237500,0.987500,0.200000,0.200000},{0.262500,0.987500,0.100000,0.100000},{0.262500,0.987500,0.200000,0.200000},{0.287500,0.987500,0.100000,0.100000},{0.287500,0.987500,0.200000,0.200000},{0.312500,0.987500,0.100000,0.100000},{0.312500,0.987500,0.200000,0.200000},{0.337500,0.987500,0.100000,0.100000},{0.337500,0.987500,0.200000,0.200000},{0.362500,0.987500,0.100000,0.100000},{0.362500,0.987500,0.200000,0.200000},{0.387500,0.987500,0.100000,0.100000},{0.387500,0.987500,0.200000,0.200000},{0.412500,0.987500,0.100000,0.100000},{0.412500,0.987500,0.200000,0.200000},{0.437500,0.987500,0.100000,0.100000},{0.437500,0.987500,0.200000,0.200000},{0.462500,0.987500,0.100000,0.100000},{0.462500,0.987500,0.200000,0.200000},{0.487500,0.987500,0.100000,0.100000},{0.487500,0.987500,0.200000,0.200000},{0.512500,0.987500,0.100000,0.100000},{0.512500,0.987500,0.200000,0.200000},{0.537500,0.987500,0.100000,0.100000},{0.537500,0.987500,0.200000,0.200000},{0.562500,0.987500,0.100000,0.100000},{0.562500,0.987500,0.200000,0.200000},{0.587500,0.987500,0.100000,0.100000},{0.587500,0.987500,0.200000,0.200000},{0.612500,0.987500,0.100000,0.100000},{0.612500,0.987500,0.200000,0.200000},{0.637500,0.987500,0.100000,0.100000},{0.637500,0.987500,0.200000,0.200000},{0.662500,0.987500,0.100000,0.100000},{0.662500,0.987500,0.200000,0.200000},{0.687500,0.987500,0.100000,0.100000},{0.687500,0.987500,0.200000,0.200000},{0.712500,0.987500,0.100000,0.100000},{0.712500,0.987500,0.200000,0.200000},{0.737500,0.987500,0.100000,0.100000},{0.737500,0.987500,0.200000,0.200000},{0.762500,0.987500,0.100000,0.100000},{0.762500,0.987500,0.200000,0.200000},{0.787500,0.987500,0.100000,0.100000},{0.787500,0.987500,0.200000,0.200000},{0.812500,0.987500,0.100000,0.100000},{0.812500,0.987500,0.200000,0.200000},{0.837500,0.987500,0.100000,0.100000},{0.837500,0.987500,0.200000,0.200000},{0.862500,0.987500,0.100000,0.100000},{0.862500,0.987500,0.200000,0.200000},{0.887500,0.987500,0.100000,0.100000},{0.887500,0.987500,0.200000,0.200000},{0.912500,0.987500,0.100000,0.100000},{0.912500,0.987500,0.200000,0.200000},{0.937500,0.987500,0.100000,0.100000},{0.937500,0.987500,0.200000,0.200000},{0.962500,0.987500,0.100000,0.100000},{0.962500,0.987500,0.200000,0.200000},{0.987500,0.987500,0.100000,0.100000},{0.987500,0.987500,0.200000,0.200000},{0.025000,0.025000,0.400000,0.400000},{0.025000,0.025000,0.800000,0.800000},{0.075000,0.025000,0.400000,0.400000},{0.075000,0.025000,0.800000,0.800000},{0.125000,0.025000,0.400000,0.400000},{0.125000,0.025000,0.800000,0.800000},{0.175000,0.025000,0.400000,0.400000},{0.175000,0.025000,0.800000,0.800000},{0.225000,0.025000,0.400000,0.400000},{0.225000,0.025000,0.800000,0.800000},{0.275000,0.025000,0.400000,0.400000},{0.275000,0.025000,0.800000,0.800000},{0.325000,0.025000,0.400000,0.400000},{0.325000,0.025000,0.800000,0.800000},{0.375000,0.025000,0.400000,0.400000},{0.375000,0.025000,0.800000,0.800000},{0.425000,0.025000,0.400000,0.400000},{0.425000,0.025000,0.800000,0.800000},{0.475000,0.025000,0.400000,0.400000},{0.475000,0.025000,0.800000,0.800000},{0.525000,0.025000,0.400000,0.400000},{0.525000,0.025000,0.800000,0.800000},{0.575000,0.025000,0.400000,0.400000},{0.575000,0.025000,0.800000,0.800000},{0.625000,0.025000,0.400000,0.400000},{0.625000,0.025000,0.800000,0.800000},{0.675000,0.025000,0.400000,0.400000},{0.675000,0.025000,0.800000,0.800000},{0.725000,0.025000,0.400000,0.400000},{0.725000,0.025000,0.800000,0.800000},{0.775000,0.025000,0.400000,0.400000},{0.775000,0.025000,0.800000,0.800000},{0.825000,0.025000,0.400000,0.400000},{0.825000,0.025000,0.800000,0.800000},{0.875000,0.025000,0.400000,0.400000},{0.875000,0.025000,0.800000,0.800000},{0.925000,0.025000,0.400000,0.400000},{0.925000,0.025000,0.800000,0.800000},{0.975000,0.025000,0.400000,0.400000},{0.975000,0.025000,0.800000,0.800000},{0.025000,0.075000,0.400000,0.400000},{0.025000,0.075000,0.800000,0.800000},{0.075000,0.075000,0.400000,0.400000},{0.075000,0.075000,0.800000,0.800000},{0.125000,0.075000,0.400000,0.400000},{0.125000,0.075000,0.800000,0.800000},{0.175000,0.075000,0.400000,0.400000},{0.175000,0.075000,0.800000,0.800000},{0.225000,0.075000,0.400000,0.400000},{0.225000,0.075000,0.800000,0.800000},{0.275000,0.075000,0.400000,0.400000},{0.275000,0.075000,0.800000,0.800000},{0.325000,0.075000,0.400000,0.400000},{0.325000,0.075000,0.800000,0.800000},{0.375000,0.075000,0.400000,0.400000},{0.375000,0.075000,0.800000,0.800000},{0.425000,0.075000,0.400000,0.400000},{0.425000,0.075000,0.800000,0.800000},{0.475000,0.075000,0.400000,0.400000},{0.475000,0.075000,0.800000,0.800000},{0.525000,0.075000,0.400000,0.400000},{0.525000,0.075000,0.800000,0.800000},{0.575000,0.075000,0.400000,0.400000},{0.575000,0.075000,0.800000,0.800000},{0.625000,0.075000,0.400000,0.400000},{0.625000,0.075000,0.800000,0.800000},{0.675000,0.075000,0.400000,0.400000},{0.675000,0.075000,0.800000,0.800000},{0.725000,0.075000,0.400000,0.400000},{0.725000,0.075000,0.800000,0.800000},{0.775000,0.075000,0.400000,0.400000},{0.775000,0.075000,0.800000,0.800000},{0.825000,0.075000,0.400000,0.400000},{0.825000,0.075000,0.800000,0.800000},{0.875000,0.075000,0.400000,0.400000},{0.875000,0.075000,0.800000,0.800000},{0.925000,0.075000,0.400000,0.400000},{0.925000,0.075000,0.800000,0.800000},{0.975000,0.075000,0.400000,0.400000},{0.975000,0.075000,0.800000,0.800000},{0.025000,0.125000,0.400000,0.400000},{0.025000,0.125000,0.800000,0.800000},{0.075000,0.125000,0.400000,0.400000},{0.075000,0.125000,0.800000,0.800000},{0.125000,0.125000,0.400000,0.400000},{0.125000,0.125000,0.800000,0.800000},{0.175000,0.125000,0.400000,0.400000},{0.175000,0.125000,0.800000,0.800000},{0.225000,0.125000,0.400000,0.400000},{0.225000,0.125000,0.800000,0.800000},{0.275000,0.125000,0.400000,0.400000},{0.275000,0.125000,0.800000,0.800000},{0.325000,0.125000,0.400000,0.400000},{0.325000,0.125000,0.800000,0.800000},{0.375000,0.125000,0.400000,0.400000},{0.375000,0.125000,0.800000,0.800000},{0.425000,0.125000,0.400000,0.400000},{0.425000,0.125000,0.800000,0.800000},{0.475000,0.125000,0.400000,0.400000},{0.475000,0.125000,0.800000,0.800000},{0.525000,0.125000,0.400000,0.400000},{0.525000,0.125000,0.800000,0.800000},{0.575000,0.125000,0.400000,0.400000},{0.575000,0.125000,0.800000,0.800000},{0.625000,0.125000,0.400000,0.400000},{0.625000,0.125000,0.800000,0.800000},{0.675000,0.125000,0.400000,0.400000},{0.675000,0.125000,0.800000,0.800000},{0.725000,0.125000,0.400000,0.400000},{0.725000,0.125000,0.800000,0.800000},{0.775000,0.125000,0.400000,0.400000},{0.775000,0.125000,0.800000,0.800000},{0.825000,0.125000,0.400000,0.400000},{0.825000,0.125000,0.800000,0.800000},{0.875000,0.125000,0.400000,0.400000},{0.875000,0.125000,0.800000,0.800000},{0.925000,0.125000,0.400000,0.400000},{0.925000,0.125000,0.800000,0.800000},{0.975000,0.125000,0.400000,0.400000},{0.975000,0.125000,0.800000,0.800000},{0.025000,0.175000,0.400000,0.400000},{0.025000,0.175000,0.800000,0.800000},{0.075000,0.175000,0.400000,0.400000},{0.075000,0.175000,0.800000,0.800000},{0.125000,0.175000,0.400000,0.400000},{0.125000,0.175000,0.800000,0.800000},{0.175000,0.175000,0.400000,0.400000},{0.175000,0.175000,0.800000,0.800000},{0.225000,0.175000,0.400000,0.400000},{0.225000,0.175000,0.800000,0.800000},{0.275000,0.175000,0.400000,0.400000},{0.275000,0.175000,0.800000,0.800000},{0.325000,0.175000,0.400000,0.400000},{0.325000,0.175000,0.800000,0.800000},{0.375000,0.175000,0.400000,0.400000},{0.375000,0.175000,0.800000,0.800000},{0.425000,0.175000,0.400000,0.400000},{0.425000,0.175000,0.800000,0.800000},{0.475000,0.175000,0.400000,0.400000},{0.475000,0.175000,0.800000,0.800000},{0.525000,0.175000,0.400000,0.400000},{0.525000,0.175000,0.800000,0.800000},{0.575000,0.175000,0.400000,0.400000},{0.575000,0.175000,0.800000,0.800000},{0.625000,0.175000,0.400000,0.400000},{0.625000,0.175000,0.800000,0.800000},{0.675000,0.175000,0.400000,0.400000},{0.675000,0.175000,0.800000,0.800000},{0.725000,0.175000,0.400000,0.400000},{0.725000,0.175000,0.800000,0.800000},{0.775000,0.175000,0.400000,0.400000},{0.775000,0.175000,0.800000,0.800000},{0.825000,0.175000,0.400000,0.400000},{0.825000,0.175000,0.800000,0.800000},{0.875000,0.175000,0.400000,0.400000},{0.875000,0.175000,0.800000,0.800000},{0.925000,0.175000,0.400000,0.400000},{0.925000,0.175000,0.800000,0.800000},{0.975000,0.175000,0.400000,0.400000},{0.975000,0.175000,0.800000,0.800000},{0.025000,0.225000,0.400000,0.400000},{0.025000,0.225000,0.800000,0.800000},{0.075000,0.225000,0.400000,0.400000},{0.075000,0.225000,0.800000,0.800000},{0.125000,0.225000,0.400000,0.400000},{0.125000,0.225000,0.800000,0.800000},{0.175000,0.225000,0.400000,0.400000},{0.175000,0.225000,0.800000,0.800000},{0.225000,0.225000,0.400000,0.400000},{0.225000,0.225000,0.800000,0.800000},{0.275000,0.225000,0.400000,0.400000},{0.275000,0.225000,0.800000,0.800000},{0.325000,0.225000,0.400000,0.400000},{0.325000,0.225000,0.800000,0.800000},{0.375000,0.225000,0.400000,0.400000},{0.375000,0.225000,0.800000,0.800000},{0.425000,0.225000,0.400000,0.400000},{0.425000,0.225000,0.800000,0.800000},{0.475000,0.225000,0.400000,0.400000},{0.475000,0.225000,0.800000,0.800000},{0.525000,0.225000,0.400000,0.400000},{0.525000,0.225000,0.800000,0.800000},{0.575000,0.225000,0.400000,0.400000},{0.575000,0.225000,0.800000,0.800000},{0.625000,0.225000,0.400000,0.400000},{0.625000,0.225000,0.800000,0.800000},{0.675000,0.225000,0.400000,0.400000},{0.675000,0.225000,0.800000,0.800000},{0.725000,0.225000,0.400000,0.400000},{0.725000,0.225000,0.800000,0.800000},{0.775000,0.225000,0.400000,0.400000},{0.775000,0.225000,0.800000,0.800000},{0.825000,0.225000,0.400000,0.400000},{0.825000,0.225000,0.800000,0.800000},{0.875000,0.225000,0.400000,0.400000},{0.875000,0.225000,0.800000,0.800000},{0.925000,0.225000,0.400000,0.400000},{0.925000,0.225000,0.800000,0.800000},{0.975000,0.225000,0.400000,0.400000},{0.975000,0.225000,0.800000,0.800000},{0.025000,0.275000,0.400000,0.400000},{0.025000,0.275000,0.800000,0.800000},{0.075000,0.275000,0.400000,0.400000},{0.075000,0.275000,0.800000,0.800000},{0.125000,0.275000,0.400000,0.400000},{0.125000,0.275000,0.800000,0.800000},{0.175000,0.275000,0.400000,0.400000},{0.175000,0.275000,0.800000,0.800000},{0.225000,0.275000,0.400000,0.400000},{0.225000,0.275000,0.800000,0.800000},{0.275000,0.275000,0.400000,0.400000},{0.275000,0.275000,0.800000,0.800000},{0.325000,0.275000,0.400000,0.400000},{0.325000,0.275000,0.800000,0.800000},{0.375000,0.275000,0.400000,0.400000},{0.375000,0.275000,0.800000,0.800000},{0.425000,0.275000,0.400000,0.400000},{0.425000,0.275000,0.800000,0.800000},{0.475000,0.275000,0.400000,0.400000},{0.475000,0.275000,0.800000,0.800000},{0.525000,0.275000,0.400000,0.400000},{0.525000,0.275000,0.800000,0.800000},{0.575000,0.275000,0.400000,0.400000},{0.575000,0.275000,0.800000,0.800000},{0.625000,0.275000,0.400000,0.400000},{0.625000,0.275000,0.800000,0.800000},{0.675000,0.275000,0.400000,0.400000},{0.675000,0.275000,0.800000,0.800000},{0.725000,0.275000,0.400000,0.400000},{0.725000,0.275000,0.800000,0.800000},{0.775000,0.275000,0.400000,0.400000},{0.775000,0.275000,0.800000,0.800000},{0.825000,0.275000,0.400000,0.400000},{0.825000,0.275000,0.800000,0.800000},{0.875000,0.275000,0.400000,0.400000},{0.875000,0.275000,0.800000,0.800000},{0.925000,0.275000,0.400000,0.400000},{0.925000,0.275000,0.800000,0.800000},{0.975000,0.275000,0.400000,0.400000},{0.975000,0.275000,0.800000,0.800000},{0.025000,0.325000,0.400000,0.400000},{0.025000,0.325000,0.800000,0.800000},{0.075000,0.325000,0.400000,0.400000},{0.075000,0.325000,0.800000,0.800000},{0.125000,0.325000,0.400000,0.400000},{0.125000,0.325000,0.800000,0.800000},{0.175000,0.325000,0.400000,0.400000},{0.175000,0.325000,0.800000,0.800000},{0.225000,0.325000,0.400000,0.400000},{0.225000,0.325000,0.800000,0.800000},{0.275000,0.325000,0.400000,0.400000},{0.275000,0.325000,0.800000,0.800000},{0.325000,0.325000,0.400000,0.400000},{0.325000,0.325000,0.800000,0.800000},{0.375000,0.325000,0.400000,0.400000},{0.375000,0.325000,0.800000,0.800000},{0.425000,0.325000,0.400000,0.400000},{0.425000,0.325000,0.800000,0.800000},{0.475000,0.325000,0.400000,0.400000},{0.475000,0.325000,0.800000,0.800000},{0.525000,0.325000,0.400000,0.400000},{0.525000,0.325000,0.800000,0.800000},{0.575000,0.325000,0.400000,0.400000},{0.575000,0.325000,0.800000,0.800000},{0.625000,0.325000,0.400000,0.400000},{0.625000,0.325000,0.800000,0.800000},{0.675000,0.325000,0.400000,0.400000},{0.675000,0.325000,0.800000,0.800000},{0.725000,0.325000,0.400000,0.400000},{0.725000,0.325000,0.800000,0.800000},{0.775000,0.325000,0.400000,0.400000},{0.775000,0.325000,0.800000,0.800000},{0.825000,0.325000,0.400000,0.400000},{0.825000,0.325000,0.800000,0.800000},{0.875000,0.325000,0.400000,0.400000},{0.875000,0.325000,0.800000,0.800000},{0.925000,0.325000,0.400000,0.400000},{0.925000,0.325000,0.800000,0.800000},{0.975000,0.325000,0.400000,0.400000},{0.975000,0.325000,0.800000,0.800000},{0.025000,0.375000,0.400000,0.400000},{0.025000,0.375000,0.800000,0.800000},{0.075000,0.375000,0.400000,0.400000},{0.075000,0.375000,0.800000,0.800000},{0.125000,0.375000,0.400000,0.400000},{0.125000,0.375000,0.800000,0.800000},{0.175000,0.375000,0.400000,0.400000},{0.175000,0.375000,0.800000,0.800000},{0.225000,0.375000,0.400000,0.400000},{0.225000,0.375000,0.800000,0.800000},{0.275000,0.375000,0.400000,0.400000},{0.275000,0.375000,0.800000,0.800000},{0.325000,0.375000,0.400000,0.400000},{0.325000,0.375000,0.800000,0.800000},{0.375000,0.375000,0.400000,0.400000},{0.375000,0.375000,0.800000,0.800000},{0.425000,0.375000,0.400000,0.400000},{0.425000,0.375000,0.800000,0.800000},{0.475000,0.375000,0.400000,0.400000},{0.475000,0.375000,0.800000,0.800000},{0.525000,0.375000,0.400000,0.400000},{0.525000,0.375000,0.800000,0.800000},{0.575000,0.375000,0.400000,0.400000},{0.575000,0.375000,0.800000,0.800000},{0.625000,0.375000,0.400000,0.400000},{0.625000,0.375000,0.800000,0.800000},{0.675000,0.375000,0.400000,0.400000},{0.675000,0.375000,0.800000,0.800000},{0.725000,0.375000,0.400000,0.400000},{0.725000,0.375000,0.800000,0.800000},{0.775000,0.375000,0.400000,0.400000},{0.775000,0.375000,0.800000,0.800000},{0.825000,0.375000,0.400000,0.400000},{0.825000,0.375000,0.800000,0.800000},{0.875000,0.375000,0.400000,0.400000},{0.875000,0.375000,0.800000,0.800000},{0.925000,0.375000,0.400000,0.400000},{0.925000,0.375000,0.800000,0.800000},{0.975000,0.375000,0.400000,0.400000},{0.975000,0.375000,0.800000,0.800000},{0.025000,0.425000,0.400000,0.400000},{0.025000,0.425000,0.800000,0.800000},{0.075000,0.425000,0.400000,0.400000},{0.075000,0.425000,0.800000,0.800000},{0.125000,0.425000,0.400000,0.400000},{0.125000,0.425000,0.800000,0.800000},{0.175000,0.425000,0.400000,0.400000},{0.175000,0.425000,0.800000,0.800000},{0.225000,0.425000,0.400000,0.400000},{0.225000,0.425000,0.800000,0.800000},{0.275000,0.425000,0.400000,0.400000},{0.275000,0.425000,0.800000,0.800000},{0.325000,0.425000,0.400000,0.400000},{0.325000,0.425000,0.800000,0.800000},{0.375000,0.425000,0.400000,0.400000},{0.375000,0.425000,0.800000,0.800000},{0.425000,0.425000,0.400000,0.400000},{0.425000,0.425000,0.800000,0.800000},{0.475000,0.425000,0.400000,0.400000},{0.475000,0.425000,0.800000,0.800000},{0.525000,0.425000,0.400000,0.400000},{0.525000,0.425000,0.800000,0.800000},{0.575000,0.425000,0.400000,0.400000},{0.575000,0.425000,0.800000,0.800000},{0.625000,0.425000,0.400000,0.400000},{0.625000,0.425000,0.800000,0.800000},{0.675000,0.425000,0.400000,0.400000},{0.675000,0.425000,0.800000,0.800000},{0.725000,0.425000,0.400000,0.400000},{0.725000,0.425000,0.800000,0.800000},{0.775000,0.425000,0.400000,0.400000},{0.775000,0.425000,0.800000,0.800000},{0.825000,0.425000,0.400000,0.400000},{0.825000,0.425000,0.800000,0.800000},{0.875000,0.425000,0.400000,0.400000},{0.875000,0.425000,0.800000,0.800000},{0.925000,0.425000,0.400000,0.400000},{0.925000,0.425000,0.800000,0.800000},{0.975000,0.425000,0.400000,0.400000},{0.975000,0.425000,0.800000,0.800000},{0.025000,0.475000,0.400000,0.400000},{0.025000,0.475000,0.800000,0.800000},{0.075000,0.475000,0.400000,0.400000},{0.075000,0.475000,0.800000,0.800000},{0.125000,0.475000,0.400000,0.400000},{0.125000,0.475000,0.800000,0.800000},{0.175000,0.475000,0.400000,0.400000},{0.175000,0.475000,0.800000,0.800000},{0.225000,0.475000,0.400000,0.400000},{0.225000,0.475000,0.800000,0.800000},{0.275000,0.475000,0.400000,0.400000},{0.275000,0.475000,0.800000,0.800000},{0.325000,0.475000,0.400000,0.400000},{0.325000,0.475000,0.800000,0.800000},{0.375000,0.475000,0.400000,0.400000},{0.375000,0.475000,0.800000,0.800000},{0.425000,0.475000,0.400000,0.400000},{0.425000,0.475000,0.800000,0.800000},{0.475000,0.475000,0.400000,0.400000},{0.475000,0.475000,0.800000,0.800000},{0.525000,0.475000,0.400000,0.400000},{0.525000,0.475000,0.800000,0.800000},{0.575000,0.475000,0.400000,0.400000},{0.575000,0.475000,0.800000,0.800000},{0.625000,0.475000,0.400000,0.400000},{0.625000,0.475000,0.800000,0.800000},{0.675000,0.475000,0.400000,0.400000},{0.675000,0.475000,0.800000,0.800000},{0.725000,0.475000,0.400000,0.400000},{0.725000,0.475000,0.800000,0.800000},{0.775000,0.475000,0.400000,0.400000},{0.775000,0.475000,0.800000,0.800000},{0.825000,0.475000,0.400000,0.400000},{0.825000,0.475000,0.800000,0.800000},{0.875000,0.475000,0.400000,0.400000},{0.875000,0.475000,0.800000,0.800000},{0.925000,0.475000,0.400000,0.400000},{0.925000,0.475000,0.800000,0.800000},{0.975000,0.475000,0.400000,0.400000},{0.975000,0.475000,0.800000,0.800000},{0.025000,0.525000,0.400000,0.400000},{0.025000,0.525000,0.800000,0.800000},{0.075000,0.525000,0.400000,0.400000},{0.075000,0.525000,0.800000,0.800000},{0.125000,0.525000,0.400000,0.400000},{0.125000,0.525000,0.800000,0.800000},{0.175000,0.525000,0.400000,0.400000},{0.175000,0.525000,0.800000,0.800000},{0.225000,0.525000,0.400000,0.400000},{0.225000,0.525000,0.800000,0.800000},{0.275000,0.525000,0.400000,0.400000},{0.275000,0.525000,0.800000,0.800000},{0.325000,0.525000,0.400000,0.400000},{0.325000,0.525000,0.800000,0.800000},{0.375000,0.525000,0.400000,0.400000},{0.375000,0.525000,0.800000,0.800000},{0.425000,0.525000,0.400000,0.400000},{0.425000,0.525000,0.800000,0.800000},{0.475000,0.525000,0.400000,0.400000},{0.475000,0.525000,0.800000,0.800000},{0.525000,0.525000,0.400000,0.400000},{0.525000,0.525000,0.800000,0.800000},{0.575000,0.525000,0.400000,0.400000},{0.575000,0.525000,0.800000,0.800000},{0.625000,0.525000,0.400000,0.400000},{0.625000,0.525000,0.800000,0.800000},{0.675000,0.525000,0.400000,0.400000},{0.675000,0.525000,0.800000,0.800000},{0.725000,0.525000,0.400000,0.400000},{0.725000,0.525000,0.800000,0.800000},{0.775000,0.525000,0.400000,0.400000},{0.775000,0.525000,0.800000,0.800000},{0.825000,0.525000,0.400000,0.400000},{0.825000,0.525000,0.800000,0.800000},{0.875000,0.525000,0.400000,0.400000},{0.875000,0.525000,0.800000,0.800000},{0.925000,0.525000,0.400000,0.400000},{0.925000,0.525000,0.800000,0.800000},{0.975000,0.525000,0.400000,0.400000},{0.975000,0.525000,0.800000,0.800000},{0.025000,0.575000,0.400000,0.400000},{0.025000,0.575000,0.800000,0.800000},{0.075000,0.575000,0.400000,0.400000},{0.075000,0.575000,0.800000,0.800000},{0.125000,0.575000,0.400000,0.400000},{0.125000,0.575000,0.800000,0.800000},{0.175000,0.575000,0.400000,0.400000},{0.175000,0.575000,0.800000,0.800000},{0.225000,0.575000,0.400000,0.400000},{0.225000,0.575000,0.800000,0.800000},{0.275000,0.575000,0.400000,0.400000},{0.275000,0.575000,0.800000,0.800000},{0.325000,0.575000,0.400000,0.400000},{0.325000,0.575000,0.800000,0.800000},{0.375000,0.575000,0.400000,0.400000},{0.375000,0.575000,0.800000,0.800000},{0.425000,0.575000,0.400000,0.400000},{0.425000,0.575000,0.800000,0.800000},{0.475000,0.575000,0.400000,0.400000},{0.475000,0.575000,0.800000,0.800000},{0.525000,0.575000,0.400000,0.400000},{0.525000,0.575000,0.800000,0.800000},{0.575000,0.575000,0.400000,0.400000},{0.575000,0.575000,0.800000,0.800000},{0.625000,0.575000,0.400000,0.400000},{0.625000,0.575000,0.800000,0.800000},{0.675000,0.575000,0.400000,0.400000},{0.675000,0.575000,0.800000,0.800000},{0.725000,0.575000,0.400000,0.400000},{0.725000,0.575000,0.800000,0.800000},{0.775000,0.575000,0.400000,0.400000},{0.775000,0.575000,0.800000,0.800000},{0.825000,0.575000,0.400000,0.400000},{0.825000,0.575000,0.800000,0.800000},{0.875000,0.575000,0.400000,0.400000},{0.875000,0.575000,0.800000,0.800000},{0.925000,0.575000,0.400000,0.400000},{0.925000,0.575000,0.800000,0.800000},{0.975000,0.575000,0.400000,0.400000},{0.975000,0.575000,0.800000,0.800000},{0.025000,0.625000,0.400000,0.400000},{0.025000,0.625000,0.800000,0.800000},{0.075000,0.625000,0.400000,0.400000},{0.075000,0.625000,0.800000,0.800000},{0.125000,0.625000,0.400000,0.400000},{0.125000,0.625000,0.800000,0.800000},{0.175000,0.625000,0.400000,0.400000},{0.175000,0.625000,0.800000,0.800000},{0.225000,0.625000,0.400000,0.400000},{0.225000,0.625000,0.800000,0.800000},{0.275000,0.625000,0.400000,0.400000},{0.275000,0.625000,0.800000,0.800000},{0.325000,0.625000,0.400000,0.400000},{0.325000,0.625000,0.800000,0.800000},{0.375000,0.625000,0.400000,0.400000},{0.375000,0.625000,0.800000,0.800000},{0.425000,0.625000,0.400000,0.400000},{0.425000,0.625000,0.800000,0.800000},{0.475000,0.625000,0.400000,0.400000},{0.475000,0.625000,0.800000,0.800000},{0.525000,0.625000,0.400000,0.400000},{0.525000,0.625000,0.800000,0.800000},{0.575000,0.625000,0.400000,0.400000},{0.575000,0.625000,0.800000,0.800000},{0.625000,0.625000,0.400000,0.400000},{0.625000,0.625000,0.800000,0.800000},{0.675000,0.625000,0.400000,0.400000},{0.675000,0.625000,0.800000,0.800000},{0.725000,0.625000,0.400000,0.400000},{0.725000,0.625000,0.800000,0.800000},{0.775000,0.625000,0.400000,0.400000},{0.775000,0.625000,0.800000,0.800000},{0.825000,0.625000,0.400000,0.400000},{0.825000,0.625000,0.800000,0.800000},{0.875000,0.625000,0.400000,0.400000},{0.875000,0.625000,0.800000,0.800000},{0.925000,0.625000,0.400000,0.400000},{0.925000,0.625000,0.800000,0.800000},{0.975000,0.625000,0.400000,0.400000},{0.975000,0.625000,0.800000,0.800000},{0.025000,0.675000,0.400000,0.400000},{0.025000,0.675000,0.800000,0.800000},{0.075000,0.675000,0.400000,0.400000},{0.075000,0.675000,0.800000,0.800000},{0.125000,0.675000,0.400000,0.400000},{0.125000,0.675000,0.800000,0.800000},{0.175000,0.675000,0.400000,0.400000},{0.175000,0.675000,0.800000,0.800000},{0.225000,0.675000,0.400000,0.400000},{0.225000,0.675000,0.800000,0.800000},{0.275000,0.675000,0.400000,0.400000},{0.275000,0.675000,0.800000,0.800000},{0.325000,0.675000,0.400000,0.400000},{0.325000,0.675000,0.800000,0.800000},{0.375000,0.675000,0.400000,0.400000},{0.375000,0.675000,0.800000,0.800000},{0.425000,0.675000,0.400000,0.400000},{0.425000,0.675000,0.800000,0.800000},{0.475000,0.675000,0.400000,0.400000},{0.475000,0.675000,0.800000,0.800000},{0.525000,0.675000,0.400000,0.400000},{0.525000,0.675000,0.800000,0.800000},{0.575000,0.675000,0.400000,0.400000},{0.575000,0.675000,0.800000,0.800000},{0.625000,0.675000,0.400000,0.400000},{0.625000,0.675000,0.800000,0.800000},{0.675000,0.675000,0.400000,0.400000},{0.675000,0.675000,0.800000,0.800000},{0.725000,0.675000,0.400000,0.400000},{0.725000,0.675000,0.800000,0.800000},{0.775000,0.675000,0.400000,0.400000},{0.775000,0.675000,0.800000,0.800000},{0.825000,0.675000,0.400000,0.400000},{0.825000,0.675000,0.800000,0.800000},{0.875000,0.675000,0.400000,0.400000},{0.875000,0.675000,0.800000,0.800000},{0.925000,0.675000,0.400000,0.400000},{0.925000,0.675000,0.800000,0.800000},{0.975000,0.675000,0.400000,0.400000},{0.975000,0.675000,0.800000,0.800000},{0.025000,0.725000,0.400000,0.400000},{0.025000,0.725000,0.800000,0.800000},{0.075000,0.725000,0.400000,0.400000},{0.075000,0.725000,0.800000,0.800000},{0.125000,0.725000,0.400000,0.400000},{0.125000,0.725000,0.800000,0.800000},{0.175000,0.725000,0.400000,0.400000},{0.175000,0.725000,0.800000,0.800000},{0.225000,0.725000,0.400000,0.400000},{0.225000,0.725000,0.800000,0.800000},{0.275000,0.725000,0.400000,0.400000},{0.275000,0.725000,0.800000,0.800000},{0.325000,0.725000,0.400000,0.400000},{0.325000,0.725000,0.800000,0.800000},{0.375000,0.725000,0.400000,0.400000},{0.375000,0.725000,0.800000,0.800000},{0.425000,0.725000,0.400000,0.400000},{0.425000,0.725000,0.800000,0.800000},{0.475000,0.725000,0.400000,0.400000},{0.475000,0.725000,0.800000,0.800000},{0.525000,0.725000,0.400000,0.400000},{0.525000,0.725000,0.800000,0.800000},{0.575000,0.725000,0.400000,0.400000},{0.575000,0.725000,0.800000,0.800000},{0.625000,0.725000,0.400000,0.400000},{0.625000,0.725000,0.800000,0.800000},{0.675000,0.725000,0.400000,0.400000},{0.675000,0.725000,0.800000,0.800000},{0.725000,0.725000,0.400000,0.400000},{0.725000,0.725000,0.800000,0.800000},{0.775000,0.725000,0.400000,0.400000},{0.775000,0.725000,0.800000,0.800000},{0.825000,0.725000,0.400000,0.400000},{0.825000,0.725000,0.800000,0.800000},{0.875000,0.725000,0.400000,0.400000},{0.875000,0.725000,0.800000,0.800000},{0.925000,0.725000,0.400000,0.400000},{0.925000,0.725000,0.800000,0.800000},{0.975000,0.725000,0.400000,0.400000},{0.975000,0.725000,0.800000,0.800000},{0.025000,0.775000,0.400000,0.400000},{0.025000,0.775000,0.800000,0.800000},{0.075000,0.775000,0.400000,0.400000},{0.075000,0.775000,0.800000,0.800000},{0.125000,0.775000,0.400000,0.400000},{0.125000,0.775000,0.800000,0.800000},{0.175000,0.775000,0.400000,0.400000},{0.175000,0.775000,0.800000,0.800000},{0.225000,0.775000,0.400000,0.400000},{0.225000,0.775000,0.800000,0.800000},{0.275000,0.775000,0.400000,0.400000},{0.275000,0.775000,0.800000,0.800000},{0.325000,0.775000,0.400000,0.400000},{0.325000,0.775000,0.800000,0.800000},{0.375000,0.775000,0.400000,0.400000},{0.375000,0.775000,0.800000,0.800000},{0.425000,0.775000,0.400000,0.400000},{0.425000,0.775000,0.800000,0.800000},{0.475000,0.775000,0.400000,0.400000},{0.475000,0.775000,0.800000,0.800000},{0.525000,0.775000,0.400000,0.400000},{0.525000,0.775000,0.800000,0.800000},{0.575000,0.775000,0.400000,0.400000},{0.575000,0.775000,0.800000,0.800000},{0.625000,0.775000,0.400000,0.400000},{0.625000,0.775000,0.800000,0.800000},{0.675000,0.775000,0.400000,0.400000},{0.675000,0.775000,0.800000,0.800000},{0.725000,0.775000,0.400000,0.400000},{0.725000,0.775000,0.800000,0.800000},{0.775000,0.775000,0.400000,0.400000},{0.775000,0.775000,0.800000,0.800000},{0.825000,0.775000,0.400000,0.400000},{0.825000,0.775000,0.800000,0.800000},{0.875000,0.775000,0.400000,0.400000},{0.875000,0.775000,0.800000,0.800000},{0.925000,0.775000,0.400000,0.400000},{0.925000,0.775000,0.800000,0.800000},{0.975000,0.775000,0.400000,0.400000},{0.975000,0.775000,0.800000,0.800000},{0.025000,0.825000,0.400000,0.400000},{0.025000,0.825000,0.800000,0.800000},{0.075000,0.825000,0.400000,0.400000},{0.075000,0.825000,0.800000,0.800000},{0.125000,0.825000,0.400000,0.400000},{0.125000,0.825000,0.800000,0.800000},{0.175000,0.825000,0.400000,0.400000},{0.175000,0.825000,0.800000,0.800000},{0.225000,0.825000,0.400000,0.400000},{0.225000,0.825000,0.800000,0.800000},{0.275000,0.825000,0.400000,0.400000},{0.275000,0.825000,0.800000,0.800000},{0.325000,0.825000,0.400000,0.400000},{0.325000,0.825000,0.800000,0.800000},{0.375000,0.825000,0.400000,0.400000},{0.375000,0.825000,0.800000,0.800000},{0.425000,0.825000,0.400000,0.400000},{0.425000,0.825000,0.800000,0.800000},{0.475000,0.825000,0.400000,0.400000},{0.475000,0.825000,0.800000,0.800000},{0.525000,0.825000,0.400000,0.400000},{0.525000,0.825000,0.800000,0.800000},{0.575000,0.825000,0.400000,0.400000},{0.575000,0.825000,0.800000,0.800000},{0.625000,0.825000,0.400000,0.400000},{0.625000,0.825000,0.800000,0.800000},{0.675000,0.825000,0.400000,0.400000},{0.675000,0.825000,0.800000,0.800000},{0.725000,0.825000,0.400000,0.400000},{0.725000,0.825000,0.800000,0.800000},{0.775000,0.825000,0.400000,0.400000},{0.775000,0.825000,0.800000,0.800000},{0.825000,0.825000,0.400000,0.400000},{0.825000,0.825000,0.800000,0.800000},{0.875000,0.825000,0.400000,0.400000},{0.875000,0.825000,0.800000,0.800000},{0.925000,0.825000,0.400000,0.400000},{0.925000,0.825000,0.800000,0.800000},{0.975000,0.825000,0.400000,0.400000},{0.975000,0.825000,0.800000,0.800000},{0.025000,0.875000,0.400000,0.400000},{0.025000,0.875000,0.800000,0.800000},{0.075000,0.875000,0.400000,0.400000},{0.075000,0.875000,0.800000,0.800000},{0.125000,0.875000,0.400000,0.400000},{0.125000,0.875000,0.800000,0.800000},{0.175000,0.875000,0.400000,0.400000},{0.175000,0.875000,0.800000,0.800000},{0.225000,0.875000,0.400000,0.400000},{0.225000,0.875000,0.800000,0.800000},{0.275000,0.875000,0.400000,0.400000},{0.275000,0.875000,0.800000,0.800000},{0.325000,0.875000,0.400000,0.400000},{0.325000,0.875000,0.800000,0.800000},{0.375000,0.875000,0.400000,0.400000},{0.375000,0.875000,0.800000,0.800000},{0.425000,0.875000,0.400000,0.400000},{0.425000,0.875000,0.800000,0.800000},{0.475000,0.875000,0.400000,0.400000},{0.475000,0.875000,0.800000,0.800000},{0.525000,0.875000,0.400000,0.400000},{0.525000,0.875000,0.800000,0.800000},{0.575000,0.875000,0.400000,0.400000},{0.575000,0.875000,0.800000,0.800000},{0.625000,0.875000,0.400000,0.400000},{0.625000,0.875000,0.800000,0.800000},{0.675000,0.875000,0.400000,0.400000},{0.675000,0.875000,0.800000,0.800000},{0.725000,0.875000,0.400000,0.400000},{0.725000,0.875000,0.800000,0.800000},{0.775000,0.875000,0.400000,0.400000},{0.775000,0.875000,0.800000,0.800000},{0.825000,0.875000,0.400000,0.400000},{0.825000,0.875000,0.800000,0.800000},{0.875000,0.875000,0.400000,0.400000},{0.875000,0.875000,0.800000,0.800000},{0.925000,0.875000,0.400000,0.400000},{0.925000,0.875000,0.800000,0.800000},{0.975000,0.875000,0.400000,0.400000},{0.975000,0.875000,0.800000,0.800000},{0.025000,0.925000,0.400000,0.400000},{0.025000,0.925000,0.800000,0.800000},{0.075000,0.925000,0.400000,0.400000},{0.075000,0.925000,0.800000,0.800000},{0.125000,0.925000,0.400000,0.400000},{0.125000,0.925000,0.800000,0.800000},{0.175000,0.925000,0.400000,0.400000},{0.175000,0.925000,0.800000,0.800000},{0.225000,0.925000,0.400000,0.400000},{0.225000,0.925000,0.800000,0.800000},{0.275000,0.925000,0.400000,0.400000},{0.275000,0.925000,0.800000,0.800000},{0.325000,0.925000,0.400000,0.400000},{0.325000,0.925000,0.800000,0.800000},{0.375000,0.925000,0.400000,0.400000},{0.375000,0.925000,0.800000,0.800000},{0.425000,0.925000,0.400000,0.400000},{0.425000,0.925000,0.800000,0.800000},{0.475000,0.925000,0.400000,0.400000},{0.475000,0.925000,0.800000,0.800000},{0.525000,0.925000,0.400000,0.400000},{0.525000,0.925000,0.800000,0.800000},{0.575000,0.925000,0.400000,0.400000},{0.575000,0.925000,0.800000,0.800000},{0.625000,0.925000,0.400000,0.400000},{0.625000,0.925000,0.800000,0.800000},{0.675000,0.925000,0.400000,0.400000},{0.675000,0.925000,0.800000,0.800000},{0.725000,0.925000,0.400000,0.400000},{0.725000,0.925000,0.800000,0.800000},{0.775000,0.925000,0.400000,0.400000},{0.775000,0.925000,0.800000,0.800000},{0.825000,0.925000,0.400000,0.400000},{0.825000,0.925000,0.800000,0.800000},{0.875000,0.925000,0.400000,0.400000},{0.875000,0.925000,0.800000,0.800000},{0.925000,0.925000,0.400000,0.400000},{0.925000,0.925000,0.800000,0.800000},{0.975000,0.925000,0.400000,0.400000},{0.975000,0.925000,0.800000,0.800000},{0.025000,0.975000,0.400000,0.400000},{0.025000,0.975000,0.800000,0.800000},{0.075000,0.975000,0.400000,0.400000},{0.075000,0.975000,0.800000,0.800000},{0.125000,0.975000,0.400000,0.400000},{0.125000,0.975000,0.800000,0.800000},{0.175000,0.975000,0.400000,0.400000},{0.175000,0.975000,0.800000,0.800000},{0.225000,0.975000,0.400000,0.400000},{0.225000,0.975000,0.800000,0.800000},{0.275000,0.975000,0.400000,0.400000},{0.275000,0.975000,0.800000,0.800000},{0.325000,0.975000,0.400000,0.400000},{0.325000,0.975000,0.800000,0.800000},{0.375000,0.975000,0.400000,0.400000},{0.375000,0.975000,0.800000,0.800000},{0.425000,0.975000,0.400000,0.400000},{0.425000,0.975000,0.800000,0.800000},{0.475000,0.975000,0.400000,0.400000},{0.475000,0.975000,0.800000,0.800000},{0.525000,0.975000,0.400000,0.400000},{0.525000,0.975000,0.800000,0.800000},{0.575000,0.975000,0.400000,0.400000},{0.575000,0.975000,0.800000,0.800000},{0.625000,0.975000,0.400000,0.400000},{0.625000,0.975000,0.800000,0.800000},{0.675000,0.975000,0.400000,0.400000},{0.675000,0.975000,0.800000,0.800000},{0.725000,0.975000,0.400000,0.400000},{0.725000,0.975000,0.800000,0.800000},{0.775000,0.975000,0.400000,0.400000},{0.775000,0.975000,0.800000,0.800000},{0.825000,0.975000,0.400000,0.400000},{0.825000,0.975000,0.800000,0.800000},{0.875000,0.975000,0.400000,0.400000},{0.875000,0.975000,0.800000,0.800000},{0.925000,0.975000,0.400000,0.400000},{0.925000,0.975000,0.800000,0.800000},{0.975000,0.975000,0.400000,0.400000},{0.975000,0.975000,0.800000,0.800000}}; \ No newline at end of file diff --git a/src/reference/ai_poc/face_mesh/constant.h b/src/reference/ai_poc/face_mesh/constant.h new file mode 100644 index 000000000..f78720ce2 --- /dev/null +++ b/src/reference/ai_poc/face_mesh/constant.h @@ -0,0 +1,32 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _CONSTANT_H +#define _CONSTANT_H + +//params normalization config +const float param_mean[62]={0.0003492636315058917,2.52790130161884e-07,-6.875197868794203e-07,60.1679573059082,-6.295513230725192e-07,0.0005757200415246189,-5.085391239845194e-05,74.2781982421875,5.400917189035681e-07,6.574138387804851e-05,0.0003442012530285865,-66.67157745361328,-346603.6875,-67468.234375,46822.265625,-15262.046875,4350.5888671875,-54261.453125,-18328.033203125,-1584.328857421875,-84566.34375,3835.960693359375,-20811.361328125,38094.9296875,-19967.85546875,-9241.3701171875,-19600.71484375,13168.08984375,-5259.14404296875,1848.6478271484375,-13030.662109375,-2435.55615234375,-2254.20654296875,-14396.5615234375,-6176.3291015625,-25621.919921875,226.39447021484375,-6326.12353515625,-10867.2509765625,868.465087890625,-5831.14794921875,2705.123779296875,-3629.417724609375,2043.9901123046875,-2446.6162109375,3658.697021484375,-7645.98974609375,-6674.45263671875,116.38838958740234,7185.59716796875,-1429.48681640625,2617.366455078125,-1.2070955038070679,0.6690792441368103,-0.17760828137397766,0.056725528091192245,0.03967815637588501,-0.13586315512657166,-0.09223993122577667,-0.1726071834564209,-0.015804484486579895,-0.1416848599910736}; +const float param_std[62]={0.00017632152594160289,6.737943476764485e-05,0.00044708489440381527,26.55023193359375,0.0001231376954820007,4.493021697271615e-05,7.923670636955649e-05,6.982563018798828,0.0004350444069132209,0.00012314890045672655,0.00017400001524947584,20.80303955078125,575421.125,277649.0625,258336.84375,255163.125,150994.375,160086.109375,111277.3046875,97311.78125,117198.453125,89317.3671875,88493.5546875,72229.9296875,71080.2109375,50013.953125,55968.58203125,47525.50390625,49515.06640625,38161.48046875,44872.05859375,46273.23828125,38116.76953125,28191.162109375,32191.4375,36006.171875,32559.892578125,25551.1171875,24267.509765625,27521.3984375,23166.53125,21101.576171875,19412.32421875,19452.203125,17454.984375,22537.623046875,16174.28125,14671.640625,15115.6884765625,13870.0732421875,13746.3125,12663.1337890625,1.5870834589004517,1.5077009201049805,0.5881357789039612,0.5889744758605957,0.21327851712703705,0.2630201280117035,0.2796429395675659,0.38030216097831726,0.16162841022014618,0.2559692859649658}; + +#endif \ No newline at end of file diff --git a/src/reference/ai_poc/face_mesh/face_detection.cc b/src/reference/ai_poc/face_mesh/face_detection.cc new file mode 100755 index 000000000..e3d83c567 --- /dev/null +++ b/src/reference/ai_poc/face_mesh/face_detection.cc @@ -0,0 +1,419 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "face_detection.h" +#include "k230_math.h" + +extern float kAnchors320[4200][4]; +extern float kAnchors640[16800][4]; +static float (*g_anchors)[4]; + +cv::Scalar color_list_for_det[] = { + cv::Scalar(0, 0, 255), + cv::Scalar(0, 255, 255), + cv::Scalar(255, 0, 255), + cv::Scalar(0, 255, 0), + cv::Scalar(255, 0, 0) +}; + +cv::Scalar color_list_for_osd_det[] = { + cv::Scalar(255, 0, 0, 255), + cv::Scalar(255, 0, 255, 255), + cv::Scalar(255, 255, 0, 255), + cv::Scalar(255, 0, 255, 0), + cv::Scalar(255, 255, 0, 0) +}; + +int nms_comparator(const void *pa, const void *pb) +{ + NMSRoiObj a = *(NMSRoiObj *)pa; + NMSRoiObj b = *(NMSRoiObj *)pb; + float diff = a.confidence - b.confidence; + + if (diff < 0) + return 1; + else if (diff > 0) + return -1; + return 0; +} + +// for image +FaceDetection::FaceDetection(const char *kmodel_file, float obj_thresh,float nms_thresh, const int debug_mode) : obj_thresh_(obj_thresh), AIBase(kmodel_file,"FaceDetection", debug_mode) +{ + model_name_ = "FaceDetection"; + nms_thresh_ = nms_thresh; + + int net_len = input_shapes_[0][2]; // input_shapes_[0][2]==input_shapes_[0][3] + min_size_ = (net_len == 320 ? 200 : 800); + g_anchors = (net_len == 320 ? kAnchors320 : kAnchors640); + objs_num_ = min_size_ * (1 + 4 + 16); + + so_ = new NMSRoiObj[objs_num_]; + boxes_ = new float[objs_num_ * LOC_SIZE]; + landmarks_ = new float[objs_num_ * LAND_SIZE]; + + ai2d_out_tensor_ = get_input_tensor(0); +} + +// for video +FaceDetection::FaceDetection(const char *kmodel_file, float obj_thresh,float nms_thresh, FrameCHWSize isp_shape, uintptr_t vaddr, uintptr_t paddr, const int debug_mode) : obj_thresh_(obj_thresh), AIBase(kmodel_file,"FaceDetection", debug_mode) +{ + model_name_ = "FaceDetection"; + nms_thresh_ = nms_thresh; + int net_len = input_shapes_[0][2]; // input_shapes_[0][2]==input_shapes_[0][3] + min_size_ = (net_len == 320 ? 200 : 800); + g_anchors = (net_len == 320 ? kAnchors320 : kAnchors640); + objs_num_ = min_size_ * (1 + 4 + 16); + vaddr_ = vaddr; + + so_ = new NMSRoiObj[objs_num_]; + boxes_ = new float[objs_num_ * LOC_SIZE]; + landmarks_ = new float[objs_num_ * LAND_SIZE]; + + // ai2d_in_tensor to isp + isp_shape_ = isp_shape; + dims_t in_shape{1, isp_shape.channel, isp_shape.height, isp_shape.width}; + int isp_size = isp_shape.channel * isp_shape.height * isp_shape.width; +#if 0 + ai2d_in_tensor_ = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, { (gsl::byte *)vaddr, isp_size }, + true, hrt::pool_shared).expect("cannot create input tensor"); +#else + ai2d_in_tensor_ = hrt::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("create ai2d input tensor failed"); +#endif + + ai2d_out_tensor_ = get_input_tensor(0); + + // fixed padding resize param + Utils::padding_resize_one_side(isp_shape, {input_shapes_[0][3], input_shapes_[0][2]}, ai2d_builder_, ai2d_in_tensor_, ai2d_out_tensor_, cv::Scalar(104, 117, 123)); +} + +// opencv for image +void FaceDetection::pre_process(cv::Mat ori_img, std::vector &dst) +{ + ScopedTiming st(model_name_ + " pre_process", debug_mode_); + cv::Mat padding_resize_img = Utils::padding_resize(ori_img, {input_shapes_[0][3], input_shapes_[0][2]}); + Utils::bgr2rgb_and_hwc2chw(padding_resize_img,dst); +} + +// ai2d for image +void FaceDetection::pre_process(cv::Mat ori_img) +{ + ScopedTiming st(model_name_ + " pre_process image", debug_mode_); + std::vector chw_vec; + Utils::bgr2rgb_and_hwc2chw(ori_img,chw_vec); + Utils::padding_resize_one_side({ori_img.channels(), ori_img.rows, ori_img.cols}, chw_vec, {input_shapes_[0][3], input_shapes_[0][2]}, ai2d_out_tensor_, cv::Scalar(104, 117, 123)); +} + +// ai2d for video +void FaceDetection::pre_process() +{ + ScopedTiming st(model_name_ + " pre_process video", debug_mode_); +#if 0 + ai2d_builder_->invoke(ai2d_in_tensor_,ai2d_out_tensor_).expect("error occurred in ai2d running"); +#else + size_t isp_size = isp_shape_.channel * isp_shape_.height * isp_shape_.width; + auto buf = ai2d_in_tensor_.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(buf.data()), (void *)vaddr_, isp_size); + hrt::sync(ai2d_in_tensor_, sync_op_t::sync_write_back, true).expect("sync write_back failed"); + ai2d_builder_->invoke(ai2d_in_tensor_,ai2d_out_tensor_).expect("error occurred in ai2d running"); +#endif + static int aa = 0; + if(aa==50) + { + auto vaddr_out_buf = ai2d_in_tensor_.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_read).unwrap().buffer(); + unsigned char *output = reinterpret_cast(vaddr_out_buf.data()); + Utils::dump_color_image("FaceDetection_input_ori_50.png",{isp_shape_.width,isp_shape_.height},output); + } + aa += 1; +} + +void FaceDetection::inference() +{ + this->run(); + this->get_output(); +} + +void FaceDetection::post_process(FrameSize frame_size, vector &results) +{ + ScopedTiming st(model_name_ + " post_process", debug_mode_); + int obj_cnt = 0; + deal_conf(p_outputs_[3], so_, 16 * min_size_ / 2, obj_cnt); + deal_conf(p_outputs_[4], so_, 4 * min_size_ / 2, obj_cnt); + deal_conf(p_outputs_[5], so_, 1 * min_size_ / 2, obj_cnt); + obj_cnt = 0; + deal_loc(p_outputs_[0], boxes_, 16 * min_size_ / 2, obj_cnt); + deal_loc(p_outputs_[1], boxes_, 4 * min_size_ / 2, obj_cnt); + deal_loc(p_outputs_[2], boxes_, 1 * min_size_ / 2, obj_cnt); + obj_cnt = 0; + deal_landms(p_outputs_[6], landmarks_, 16 * min_size_ / 2, obj_cnt); + deal_landms(p_outputs_[7], landmarks_, 4 * min_size_ / 2, obj_cnt); + deal_landms(p_outputs_[8], landmarks_, 1 * min_size_ / 2, obj_cnt); + qsort(so_, objs_num_, sizeof(NMSRoiObj), nms_comparator); + + get_final_box(frame_size, results); +} + +void FaceDetection::draw_result(cv::Mat& src_img,vector& results, bool pic_mode) +{ + int src_w = src_img.cols; + int src_h = src_img.rows; + int max_src_size = std::max(src_w,src_h); + for (int i = 0; i < results.size(); ++i) + { + auto& l = results[i].sparse_kps; + for (uint32_t ll = 0; ll < 5; ll++) + { + if(pic_mode) + { + int32_t x0 = l.points[2 * ll + 0]; + int32_t y0 = l.points[2 * ll + 1]; + cv::circle(src_img, cv::Point(x0, y0), 2, color_list_for_det[ll], 4); + } + else + { + int32_t x0 = l.points[2 * ll]/isp_shape_.width*src_w; + int32_t y0 = l.points[2 * ll+1]/isp_shape_.height*src_h; + cv::circle(src_img, cv::Point(x0, y0), 4, color_list_for_osd_det[ll], 8); + } + } + + auto& b = results[i].bbox; + char text[10]; + sprintf(text, "%.2f", results[i].score); + if(pic_mode) + { + cv::rectangle(src_img, cv::Rect(b.x, b.y , b.w, b.h), cv::Scalar(255, 255, 255), 2, 2, 0); + cv::putText(src_img, text , {b.x,b.y}, cv::FONT_HERSHEY_COMPLEX, 0.5, cv::Scalar(0, 255, 255), 1, 8, 0); + } + else + { + int x = b.x / isp_shape_.width * src_w; + int y = b.y / isp_shape_.height * src_h; + int w = b.w / isp_shape_.width * src_w; + int h = b.h / isp_shape_.height * src_h; + cv::rectangle(src_img, cv::Rect(x, y , w, h), cv::Scalar(255,255, 255, 255), 6, 2, 0); + } + } +} + +void FaceDetection::get_final_box(FrameSize &frame_size, vector &results) +{ + int iou_cal_times = 0; + int i, j, obj_index; + for (i = 0; i < objs_num_; ++i) + { + obj_index = so_[i].index; + if (so_[i].confidence < obj_thresh_) + continue; + FaceDetectionInfo obj; + obj.bbox = get_box(boxes_, obj_index); + obj.sparse_kps = get_landmark(landmarks_, obj_index); + + for (j = i + 1; j < objs_num_; ++j) + { + obj_index = so_[j].index; + if (so_[j].confidence < obj_thresh_) + continue; + Bbox b = get_box(boxes_, obj_index); + iou_cal_times += 1; + if (box_iou(obj.bbox, b) >= nms_thresh_) // thres + so_[j].confidence = 0; + } + obj.score = so_[i].confidence; + results.push_back(obj); + } + + // for src img + int max_src_size = std::max(frame_size.width, frame_size.height); + for (int i = 0; i < results.size(); ++i) + { + auto &l = results[i].sparse_kps; + for (uint32_t ll = 0; ll < 5; ll++) + { + l.points[2 * ll + 0] = l.points[2 * ll + 0] * max_src_size; + l.points[2 * ll + 1] = l.points[2 * ll + 1] * max_src_size; + } + + auto &b = results[i].bbox; + float x1 = (b.x + b.w / 2) * max_src_size; + float x0 = (b.x - b.w / 2) * max_src_size; + float y0 = (b.y - b.h / 2) * max_src_size; + float y1 = (b.y + b.h / 2) * max_src_size; + x1 = std::max(float(0), std::min(x1, float(frame_size.width))); + x0 = std::max(float(0), std::min(x0, float(frame_size.width))); + y0 = std::max(float(0), std::min(y0, float(frame_size.height))); + y1 = std::max(float(0), std::min(y1, float(frame_size.height))); + b.x = x0; + b.y = y0; + b.w = x1 - x0; + b.h = y1 - y0; + } +} + +void FaceDetection::local_softmax(float *x, float *dx, uint32_t len) +{ + float max_value = x[0]; + for (uint32_t i = 0; i < len; i++) + { + if (max_value < x[i]) + { + max_value = x[i]; + } + } + for (uint32_t i = 0; i < len; i++) + { + x[i] -= max_value; + x[i] = expf(x[i]); + } + float sum_value = 0.0f; + for (uint32_t i = 0; i < len; i++) + { + sum_value += x[i]; + } + for (uint32_t i = 0; i < len; i++) + { + dx[i] = x[i] / sum_value; + } +} + +void FaceDetection::deal_conf(float *conf, NMSRoiObj *so, int size, int &obj_cnt) +{ + float confidence[CONF_SIZE] = {0.0}; + for (uint32_t ww = 0; ww < size; ww++) + { + for (uint32_t hh = 0; hh < 2; hh++) + { + for (uint32_t cc = 0; cc < CONF_SIZE; cc++) + { + confidence[cc] = conf[(hh * CONF_SIZE + cc) * size + ww]; + } + local_softmax(confidence, confidence, 2); + so_[obj_cnt].index = obj_cnt; + so_[obj_cnt].confidence = confidence[1]; + obj_cnt += 1; + } + } +} + +void FaceDetection::deal_loc(float *loc, float *boxes, int size, int &obj_cnt) +{ + for (uint32_t ww = 0; ww < size; ww++) + { + for (uint32_t hh = 0; hh < 2; hh++) + { + for (uint32_t cc = 0; cc < LOC_SIZE; cc++) + { + boxes_[obj_cnt * LOC_SIZE + cc] = loc[(hh * LOC_SIZE + cc) * size + ww]; + } + obj_cnt += 1; + } + } +} + +void FaceDetection::deal_landms(float *landms, float *landmarks, int size, int &obj_cnt) +{ + // chw->hwc + for (uint32_t ww = 0; ww < size; ww++) + { + for (uint32_t hh = 0; hh < 2; hh++) + { + for (uint32_t cc = 0; cc < LAND_SIZE; cc++) + { + landmarks_[obj_cnt * LAND_SIZE + cc] = landms[(hh * LAND_SIZE + cc) * size + ww]; + } + obj_cnt += 1; + } + } +} + +Bbox FaceDetection::get_box(float *boxes, int obj_index) +{ + float cx, cy, w, h; + cx = boxes_[obj_index * LOC_SIZE + 0]; + cy = boxes_[obj_index * LOC_SIZE + 1]; + w = boxes_[obj_index * LOC_SIZE + 2]; + h = boxes_[obj_index * LOC_SIZE + 3]; + cx = g_anchors[obj_index][0] + cx * 0.1 * g_anchors[obj_index][2]; + cy = g_anchors[obj_index][1] + cy * 0.1 * g_anchors[obj_index][3]; + w = g_anchors[obj_index][2] * k230_expf(w * 0.2); + h = g_anchors[obj_index][3] * k230_expf(h * 0.2); + Bbox box; + box.x = cx; + box.y = cy; + box.w = w; + box.h = h; + return box; +} + +SparseLandmarks FaceDetection::get_landmark(float *landmarks, int obj_index) +{ + SparseLandmarks landmark; + for (uint32_t ll = 0; ll < 5; ll++) + { + landmark.points[2 * ll + 0] = g_anchors[obj_index][0] + landmarks_[obj_index * LAND_SIZE + 2 * ll + 0] * 0.1 * g_anchors[obj_index][2]; + landmark.points[2 * ll + 1] = g_anchors[obj_index][1] + landmarks_[obj_index * LAND_SIZE + 2 * ll + 1] * 0.1 * g_anchors[obj_index][3]; + } + return landmark; +} + +float FaceDetection::overlap(float x1, float w1, float x2, float w2) +{ + float l1 = x1 - w1 / 2; + float l2 = x2 - w2 / 2; + float left = l1 > l2 ? l1 : l2; + float r1 = x1 + w1 / 2; + float r2 = x2 + w2 / 2; + float right = r1 < r2 ? r1 : r2; + return right - left; +} + +float FaceDetection::box_intersection(Bbox a, Bbox b) +{ + float w = overlap(a.x, a.w, b.x, b.w); + float h = overlap(a.y, a.h, b.y, b.h); + + if (w < 0 || h < 0) + return 0; + return w * h; +} + +float FaceDetection::box_union(Bbox a, Bbox b) +{ + float i = box_intersection(a, b); + float u = a.w * a.h + b.w * b.h - i; + + return u; +} + +float FaceDetection::box_iou(Bbox a, Bbox b) +{ + return box_intersection(a, b) / box_union(a, b); +} + +FaceDetection::~FaceDetection() +{ + delete[] so_; + delete[] boxes_; + delete[] landmarks_; +} \ No newline at end of file diff --git a/src/reference/ai_poc/face_mesh/face_detection.h b/src/reference/ai_poc/face_mesh/face_detection.h new file mode 100755 index 000000000..1dad3b63b --- /dev/null +++ b/src/reference/ai_poc/face_mesh/face_detection.h @@ -0,0 +1,253 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FACE_DETECTION_H +#define _FACE_DETECTION_H + +#include +#include + +#include "utils.h" +#include "ai_base.h" + +using std::vector; + +#define LOC_SIZE 4 +#define CONF_SIZE 2 +#define LAND_SIZE 10 +#define PI 3.1415926 + +/** + * @brief 用于NMS排序的roi对象 + */ +typedef struct NMSRoiObj +{ + int index; // roi对象所在原列表的索引 + float confidence; // roi对象的置信度 +} NMSRoiObj; + +/** + * @brief 预测人脸roi信息 + */ +typedef struct FaceDetectionInfo +{ + Bbox bbox; // 人脸检测框 + SparseLandmarks sparse_kps; // 人脸五官关键点 + float score; // 人脸检测框置信度 +} FaceDetectionInfo; + +/** + * @brief 人脸检测 + * 主要封装了对于每一帧图片,从预处理、运行到后处理给出结果的过程 + */ +class FaceDetection : public AIBase +{ +public: + /** + * @brief FaceDetection构造函数,加载kmodel,并初始化kmodel输入、输出和人脸检测阈值 + * @param kmodel_file kmodel文件路径 + * @param obj_thresh 人脸检测阈值,用于过滤roi + * @param nms_thresh 人脸检测nms阈值 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + FaceDetection(const char *kmodel_file, float obj_thresh,float nms_thresh, const int debug_mode = 1); + + /** + * @brief FaceDetection构造函数,加载kmodel,并初始化kmodel输入、输出和人脸检测阈值 + * @param kmodel_file kmodel文件路径 + * @param obj_thresh 人脸检测阈值,用于过滤roi + * @param nms_thresh 人脸检测nms阈值 + * @param isp_shape isp输入大小(chw) + * @param vaddr isp对应虚拟地址 + * @param paddr isp对应物理地址 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + FaceDetection(const char *kmodel_file, float obj_thresh,float nms_thresh, FrameCHWSize isp_shape, uintptr_t vaddr, uintptr_t paddr, const int debug_mode); + + /** + * @brief FaceDetection析构函数 + * @return None + */ + ~FaceDetection(); + + /** + * @brief 图片预处理 + * @param ori_img 原始图片 + * @param dst 处理后NCHW的图像数据 + * @return None + */ + void pre_process(cv::Mat ori_img, std::vector &dst); + + /** + * @brief 图片预处理,(ai2d for image) + * @param ori_img 原始图片 + * @return None + */ + void pre_process(cv::Mat ori_img); + + /** + * @brief 视频流预处理(ai2d for isp) + * @return None + */ + void pre_process(); + + /** + * @brief kmodel推理 + * @return None + */ + void inference(); + + /** + * @brief kmodel推理结果后处理 + * @param frame_size 原始图像/帧宽高,用于将结果放到原始图像大小 + * @param results 后处理之后的基于原始图像的{检测框、五官点和得分}集合 + * @return None + */ + void post_process(FrameSize frame_size, vector &results); + + /** + * @brief 将检测结果画到原图 + * @param src_img 原图 + * @param pic_mode ture(原图片),false(osd) + * @return None + */ + void draw_result(cv::Mat& src_img,vector& results, bool pic_mode = true); + +private: + /** + * @brief softmax操作 + * @param x 需要处理数据指针 + * @param dx 处理数据后的指针 + * @param len 需要处理数据长度 + * @return None + */ + void local_softmax(float *x, float *dx, uint32_t len); + + /** + * @brief roi置信度后处理 + * @param conf 指向模型推理得到的首个roi置信度的指针 + * @param so 指向经过softmax之后首个roi置信度的指针 + * @param size 需要处理roi个数 + * @param obj_cnt 已经处理的roi个数,deal_conf会被调用多次 + * @return None + */ + void deal_conf(float *conf, NMSRoiObj *so, int size, int &obj_cnt); + + /** + * @brief roi位置(location)后处理 + * @param loc 模型推理后,指向首个roi位置的指针 + * @param boxes 经过NCHW-NHWC之后,指向首个roi位置的指针 + * @param size 需要处理roi个数 + * @param obj_cnt 已经处理的roi个数,deal_loc会被调用多次 + * @return None + */ + void deal_loc(float *loc, float *boxes, int size, int &obj_cnt); + + /** + * @brief roi五官关键点后处理 + * @param landms 模型推理后,指向首个roi对应的五官关键点的指针 + * @param boxes 经过NCHW-NHWC之后,指向首个roi对应的五官关键点的指针 + * @param size 需要处理roi个数 + * @param obj_cnt 已经处理的roi个数,deal_landms会被调用多次 + * @return None + */ + void deal_landms(float *landms, float *landmarks, int size, int &obj_cnt); + + /** + * @brief 根据索引值得到单个roi检测框 + * @param boxes 指向首个roi的检测框的指针 + * @param obj_index 需要获取的roi索引 + * @return None + */ + Bbox get_box(float *boxes, int obj_index); + + /** + * @brief 根据索引值得到单个roi对应的五官关键点 + * @param landmarks 指向首个roi对应的五官关键点指针 + * @param obj_index 需要获取的roi索引 + * @return None + */ + SparseLandmarks get_landmark(float *landmarks, int obj_index); + + /** + * @brief 获取2个检测框重叠区域的左上角或右下角 + * @param x1 第1个检测框的中心点x或y坐标 + * @param w1 第1个检测框的宽(w)或高(h) + * @param x2 第2个检测框的中心点x或y坐标 + * @param w2 第2个检测框的宽(w)或高(h) + * @return 2个检测框重叠区域的宽或高 + */ + float overlap(float x1, float w1, float x2, float w2); + + /** + * @brief 获取2个检测框重叠区域的面积 + * @param a 第1个检测框 + * @param b 第2个检测框 + * @return 2个检测框重叠区域的面积 + */ + float box_intersection(Bbox a, Bbox b); + + /** + * @brief 获取2个检测框联合区域的面积 + * @param a 第1个检测框 + * @param b 第2个检测框 + * @return 2个检测框重叠联合区域的面积 + */ + float box_union(Bbox a, Bbox b); + + /** + * @brief 获取2个检测框的iou + * @param a 第1个检测框 + * @param b 第2个检测框 + * @return 2个检测框的iou + */ + float box_iou(Bbox a, Bbox b); + + /** + * @brief 获取2个检测框的iou + * @param frame_size 原始图像/帧宽高,用于将结果放到原始图像大小 + * @param results 后处理之后的基于原始图像的{检测框、五官点和得分}集合 + * @return None + */ + void get_final_box(FrameSize &frame_size, vector &results); + + std::unique_ptr ai2d_builder_; // ai2d构建器 + runtime_tensor ai2d_in_tensor_; // ai2d输入tensor + runtime_tensor ai2d_out_tensor_; // ai2d输出tensor + uintptr_t vaddr_; // isp的虚拟地址 + FrameCHWSize isp_shape_; // isp对应的地址大小 + + int min_size_; + float obj_thresh_; // 人脸检测阈值 + float nms_thresh_; // nms阈值 + int objs_num_; // roi个数 + + NMSRoiObj *so_; // 指向经过softmax之后首个roi置信度的指针 + float *boxes_; // 指向首个roi检测框的指针 + float *landmarks_; // 指向首个roi对应五官关键点的指针 +}; + +#endif \ No newline at end of file diff --git a/src/reference/ai_poc/face_mesh/face_mesh.cc b/src/reference/ai_poc/face_mesh/face_mesh.cc new file mode 100755 index 000000000..69c306ca3 --- /dev/null +++ b/src/reference/ai_poc/face_mesh/face_mesh.cc @@ -0,0 +1,228 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "face_mesh.h" +#include "k230_math.h" +#include "constant.h" + +// for image +FaceMesh::FaceMesh(const char *kmodel_file,const char *post_kmodel_file, const int debug_mode) : AIBase(kmodel_file,"FaceMesh", debug_mode),post_obj_(post_kmodel_file,debug_mode) +{ + model_name_ = "FaceMesh"; + constant_init(); + ai2d_out_tensor_ = get_input_tensor(0); + post_ver_dim_ = post_obj_.output_shapes_[0][1]; +} + +// for video +FaceMesh::FaceMesh(const char *kmodel_file,const char *post_kmodel_file, FrameCHWSize isp_shape, uintptr_t vaddr, uintptr_t paddr, const int debug_mode) : AIBase(kmodel_file,"FaceMesh", debug_mode),post_obj_(post_kmodel_file,debug_mode) +{ + model_name_ = "FaceMesh"; + constant_init(); + post_ver_dim_ = post_obj_.output_shapes_[0][1]; + vaddr_ = vaddr; + + // ai2d_in_tensor to isp + isp_shape_ = isp_shape; + dims_t in_shape{1, isp_shape.channel, isp_shape.height, isp_shape.width}; + int isp_size = isp_shape.channel * isp_shape.height * isp_shape.width; +#if 0 + ai2d_in_tensor_ = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, { (gsl::byte *)vaddr, isp_size }, + true, hrt::pool_shared).expect("cannot create input tensor"); +#else + ai2d_in_tensor_ = hrt::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("create ai2d input tensor failed"); +#endif + + ai2d_out_tensor_ = get_input_tensor(0); +} + +// ai2d for image +void FaceMesh::pre_process(cv::Mat ori_img,Bbox &bbox) +{ + ScopedTiming st(model_name_ + " pre_process image", debug_mode_); + + Bbox roi_b; + roi = parse_roi_box_from_bbox({ori_img.cols,ori_img.rows},bbox,roi_b); + std::vector chw_vec; + Utils::bgr2rgb_and_hwc2chw(ori_img,chw_vec); + Utils::crop_resize({ori_img.channels(), ori_img.rows, ori_img.cols}, chw_vec, roi_b, ai2d_out_tensor_); +} + +// ai2d for video +void FaceMesh::pre_process(Bbox &bbox) +{ + ScopedTiming st(model_name_ + " pre_process video", debug_mode_); + size_t isp_size = isp_shape_.channel * isp_shape_.height * isp_shape_.width; + auto buf = ai2d_in_tensor_.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(buf.data()), (void *)vaddr_, isp_size); + hrt::sync(ai2d_in_tensor_, sync_op_t::sync_write_back, true).expect("sync write_back failed"); + + Bbox roi_b; + roi = parse_roi_box_from_bbox({isp_shape_.width,isp_shape_.height},bbox,roi_b); + Utils::crop_resize(roi_b,ai2d_builder_, ai2d_in_tensor_, ai2d_out_tensor_); +} + +void FaceMesh::inference() +{ + this->run(); + this->get_output(); +} + +void FaceMesh::post_process(FrameSize frame_size,vector& vertices,bool pic_mode) +{ + ScopedTiming st(model_name_ + " post_process", debug_mode_); + vector param(p_outputs_[0],p_outputs_[0] + output_shapes_[0][1]); + param_normalized(param); + + post_obj_.pre_process(param); + post_obj_.inference(); + post_obj_.post_process(vertices); + + if(pic_mode==false) + { + //因为要在osd上画图,故需要把返回值变换到osd的长、宽 + roi.x0 = roi.x0 / isp_shape_.width * frame_size.width; + roi.y0 = roi.y0 / isp_shape_.height * frame_size.height; + roi.x1 = roi.x1 / isp_shape_.width * frame_size.width; + roi.y1 = roi.y1 / isp_shape_.height * frame_size.height; + } + recon_vers(roi, vertices); +} + +void FaceMesh::get_mesh(cv::Mat &src_img, vector& vertices,bool pic_mode) +{ + int x,y; + for(int ver_index =0;ver_index < post_ver_dim_;ver_index = ver_index + 6) + { + x = vertices[ver_index]; + y = vertices[ver_index + post_ver_dim_]; + if(pic_mode) + cv::circle(src_img, cv::Point(x, y), 1, cv::Scalar(255, 0, 0), 1); + else + cv::circle(src_img, cv::Point(x, y), 2, cv::Scalar(200, 0, 0, 255), 4); + } +} + +/*************************常量操作********************/ +void FaceMesh::constant_init() +{ + bfm_tri = Utils::read_binary_file("bfm_tri.bin"); + ncc_code = Utils::read_binary_file("ncc_code.bin"); +} +/*************************前处理********************/ +LeftTopRightBottom FaceMesh::parse_roi_box_from_bbox(FrameSize frame_size,Bbox& b,Bbox& roi_b) +{ + float old_size = ( b.w + b.h) / 2; + float center_x = b.x + b.w / 2; + float center_y = b.y + b.h / 2 + old_size * 0.14; + int size = int(old_size * 1.58); + + float x0 = center_x - float(size) / 2; + float y0 = center_y - float(size) / 2; + float x1 = x0 + size; + float y1 = y0 + size; + + x0 = std::max(float(0), std::min(x0, float(frame_size.width))); + y0 = std::max(float(0), std::min(y0, float(frame_size.height))); + x1 = std::max(float(0), std::min(x1, float(frame_size.width))); + y1 = std::max(float(0), std::min(y1, float(frame_size.height))); + + roi_b.x = x0; + roi_b.y = y0; + roi_b.w = x1 - x0; + roi_b.h = y1 - y0; + return {x0,y0,x1,y1}; +} + +/*************************后处理********************/ + +void FaceMesh::param_normalized(vector& param) +{ + for (int param_index = 0; param_index < param.size(); ++param_index) + { + param[param_index] = param[param_index] * param_std[param_index] + param_mean[param_index]; + } +} + +void FaceMesh::recon_vers(LeftTopRightBottom& roi_box_lst,vector &vertices) +{ + similar_transform(roi_box_lst,vertices); +} + +void FaceMesh::similar_transform(LeftTopRightBottom& roi_box,vector &vertices) +{ + double scale_x = (roi_box.x1 - roi_box.x0) / input_shapes_[0][3]; + double scale_y = (roi_box.y1 - roi_box.y0) / input_shapes_[0][3]; + double s = (scale_x + scale_y) / 2; + + for (int row_index = 0; row_index < 3; ++row_index) + { + if (row_index == 0) + { + int index = 0; + for (int col_index = 0; col_index < post_ver_dim_; ++col_index) + { + index = row_index * post_ver_dim_ + col_index; + vertices[index] -= 1; + vertices[index] = vertices[index] * scale_x + roi_box.x0; + } + } + else if (row_index == 2) + { + int index = 0; + float min_dim2 = 0; + for (int col_index = 0; col_index < post_ver_dim_; ++col_index) + { + index = row_index * post_ver_dim_ + col_index; + vertices[index] -= 1; + vertices[index] *= s; + if (col_index == 0) + min_dim2 = vertices[index]; + else + { + if (vertices[index] < min_dim2) + min_dim2 = vertices[index]; + } + } + for (int col_index = 0; col_index < post_ver_dim_; ++col_index) + { + vertices[row_index * post_ver_dim_ + col_index] -= min_dim2; + } + } + else + { + int index = 0; + for (int col_index = 0; col_index < post_ver_dim_; ++col_index) + { + index = row_index * post_ver_dim_ + col_index; + vertices[index] = input_shapes_[0][3] - vertices[index]; + vertices[index] = vertices[index] * scale_y + roi_box.y0; + } + } + } +} + +FaceMesh::~FaceMesh() +{ +} \ No newline at end of file diff --git a/src/reference/ai_poc/face_mesh/face_mesh.h b/src/reference/ai_poc/face_mesh/face_mesh.h new file mode 100755 index 000000000..f01002cb1 --- /dev/null +++ b/src/reference/ai_poc/face_mesh/face_mesh.h @@ -0,0 +1,180 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FACE_MESH_H +#define _FACE_MESH_H + +#include +#include + +#include "utils.h" +#include "ai_base.h" +#include "face_mesh_post.h" + +using std::vector; + +#define LOC_SIZE 4 +#define CONF_SIZE 2 +#define LAND_SIZE 10 +#define PI 3.1415926 + +/** + * @brief 人脸检测框 + */ +typedef struct LeftTopRightBottom +{ + float x0; // 人脸检测框的左上角x坐标 + float y0; // 人脸检测框的左上角y坐标 + float x1; // 人脸检测框的右下角x坐标 + float y1; // 人脸检测框的右下角y坐标 +} LeftTopRightBottom; + +/** + * @brief 人脸Mesh + * 主要封装了对于每一帧图片,从预处理、运行到后处理给出结果的过程 + */ +class FaceMesh : public AIBase +{ +public: + /** + * @brief FaceMesh构造函数 + * @param kmodel_file kmodel文件路径 + * @param post_kmodel_file 后处理kmodel文件路径 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + FaceMesh(const char *kmodel_file,const char *post_kmodel_file, const int debug_mode = 1); + + /** + * @brief FaceMesh构造函数 + * @param kmodel_file kmodel文件路径 + * @param post_kmodel_file 后处理kmodel文件路径 + * @param isp_shape isp输入大小 + * @param vaddr isp对应虚拟地址 + * @param paddr isp对应物理地址 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + FaceMesh(const char *kmodel_file,const char *post_kmodel_file, FrameCHWSize isp_shape, uintptr_t vaddr, uintptr_t paddr, const int debug_mode); + + /** + * @brief FaceMesh析构函数 + * @return None + */ + ~FaceMesh(); + + /** + * @brief 图片预处理,(ai2d for image) + * @param ori_img 原始图片 + * @param bbox 人脸检测框 + * @return None + */ + void pre_process(cv::Mat ori_img,Bbox &bbox); + + /** + * @brief 视频流预处理(ai2d for isp) + * @param bbox 人脸检测框 + * @return None + */ + void pre_process(Bbox &bbox); + + /** + * @brief kmodel推理 + * @return None + */ + void inference(); + + /** + * @brief kmodel推理结果后处理 + * @param frame_size 原始图像/帧宽高,用于将结果放到原始图像大小 + * @param vertices 后处理后3d点 + * @return None + */ + void post_process(FrameSize frame_size, vector& vertices,bool pic_mode); + + /** + * @brief 获取mesh + * @param img 展示的图片或图层 + * @param vertices 后处理后3d点 + * @param pic_mode ture(原图片),false(osd) + * @return None + */ + void get_mesh(cv::Mat &img, vector& vertices, bool pic_mode); +private: + + /** + * @brief face_mesh常量初始化 + * @return None + */ + void constant_init(); + + /** + * @brief 根据人脸检测框获取face_alignment roi + * @param frame_size 原图尺寸,用于防止roi越界 + * @param b 人脸检测框 + * @param roi_b roi(x,y,w,h) + * @return roi(x1,y1,x2,y2) + */ + LeftTopRightBottom parse_roi_box_from_bbox(FrameSize frame_size,Bbox& b,Bbox& roi_b); + + /** + * @brief 参数归一化 + * @param 模型输出参数 + * @return None + */ + void param_normalized(vector& param); + + /** + * @brief 3d关键点渲染 + * @param roi_box_lst roi(x1,y1,x2,y2) + * @param vertices 3d关键点 + * @return None + */ + void recon_vers(LeftTopRightBottom& roi_box_lst,vector &vertices); + + /** + * @brief 3d关键点映射,将3d关键点映射roi尺寸 + * @param roi_box roi(x1,y1,x2,y2) + * @param vertices 3d关键点 + * @return None + */ + void similar_transform(LeftTopRightBottom& roi_box,vector &vertices); + + std::unique_ptr ai2d_builder_; // ai2d构建器 + runtime_tensor ai2d_in_tensor_; // ai2d输入tensor + runtime_tensor ai2d_out_tensor_; // ai2d输出tensor + uintptr_t vaddr_; // isp的虚拟地址 + FrameCHWSize isp_shape_; // isp对应的地址大小 + + FaceMeshPost post_obj_; // 人脸mesh后处理对象 + + int post_ver_dim_; // 3d点个数 + vector bfm_u; + vector bfm_w; + vector bfm_tri; + vector ncc_code; + LeftTopRightBottom roi; // roi(x1,y1,x2,y2) +}; + +#endif \ No newline at end of file diff --git a/src/reference/ai_poc/face_mesh/face_mesh_post.cc b/src/reference/ai_poc/face_mesh/face_mesh_post.cc new file mode 100755 index 000000000..3faebb16e --- /dev/null +++ b/src/reference/ai_poc/face_mesh/face_mesh_post.cc @@ -0,0 +1,89 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "face_mesh_post.h" +#include "k230_math.h" +#include "constant.h" + +// for image +FaceMeshPost::FaceMeshPost(const char *kmodel_file, const int debug_mode) : AIBase(kmodel_file,"FaceMeshPost", debug_mode) +{ + model_name_ = "FaceMeshPost"; +} + +// ai2d for video +void FaceMeshPost::pre_process(vector& param) +{ + ScopedTiming st(model_name_ + " pre_process", debug_mode_); + int offset = 0; + for(int i =0;ito_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + float *buf_data = reinterpret_cast(buf.data()); + if(i==0) + { + int in_shape_row = input_shapes_[0][0],in_shape_col = input_shapes_[0][1]; + for(int j = 0;jrun(); + this->get_output(); +} + +void FaceMeshPost::post_process(vector& vertices) +{ + ScopedTiming st(model_name_ + " post_process", debug_mode_); + int out_size = (each_output_size_by_byte_[1]-each_output_size_by_byte_[0])/sizeof(float); + vertices.insert(vertices.end(),p_outputs_[0],p_outputs_[0]+out_size); +} + +FaceMeshPost::~FaceMeshPost() +{ +} \ No newline at end of file diff --git a/src/reference/ai_poc/face_mesh/face_mesh_post.h b/src/reference/ai_poc/face_mesh/face_mesh_post.h new file mode 100755 index 000000000..4315ae4a7 --- /dev/null +++ b/src/reference/ai_poc/face_mesh/face_mesh_post.h @@ -0,0 +1,85 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FACE_MESH_POST_H +#define _FACE_MESH_POST_H + +#include +#include + +#include "utils.h" +#include "ai_base.h" + +using std::vector; + +#define LOC_SIZE 4 +#define CONF_SIZE 2 +#define LAND_SIZE 10 +#define PI 3.1415926 + +/** + * @brief 人脸对齐后处理 + * 主要封装了对于每一帧图片,从预处理、运行到后处理给出结果的过程 + */ +class FaceMeshPost : public AIBase +{ +public: + /** + * @brief FaceMeshPost构造函数 + * @param kmodel_file kmodel文件路径 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + FaceMeshPost(const char *kmodel_file, const int debug_mode = 1); + + /** + * @brief FaceMeshPost析构函数 + * @return None + */ + ~FaceMeshPost(); + + /** + * @brief 预处理 + * @param param 人脸对齐3d关键点 + * @return None + */ + void pre_process(vector& param); + + /** + * @brief kmodel推理 + * @return None + */ + void inference(); + + /** + * @brief kmodel推理结果后处理 + * @param vertices 人脸3d点 + * @return None + */ + void post_process(vector& vertices); +private: + friend class FaceMesh; +}; + +#endif \ No newline at end of file diff --git a/src/reference/ai_poc/face_mesh/main.cc b/src/reference/ai_poc/face_mesh/main.cc new file mode 100644 index 000000000..db4c65bec --- /dev/null +++ b/src/reference/ai_poc/face_mesh/main.cc @@ -0,0 +1,191 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include "utils.h" +#include "vi_vo.h" +#include "face_detection.h" +#include "face_mesh.h" +#include "face_mesh_post.h" + +using std::cerr; +using std::cout; +using std::endl; + +std::atomic isp_stop(false); + +void print_usage(const char *name) +{ + cout << "Usage: " << name << " " << endl + << "Options:" << endl + << " kmodel_det 人脸检测kmodel路径\n" + << " obj_thres 人脸检测阈值\n" + << " nms_thres 人脸检测nms阈值\n" + << " kmodel_mesh 人脸mesh kmodel路径\n" + << " kmodel_mesh_post 人脸mesh后处理kmodel路径\n" + << " input_mode 本地图片(图片路径)/ 摄像头(None) \n" + << " debug_mode 是否需要调试,0、1、2分别表示不调试、简单调试、详细调试\n" + << "\n" + << endl; +} + +void video_proc(char *argv[]) +{ + vivcap_start(); + // 设置osd参数 + k_video_frame_info vf_info; + void *pic_vaddr = NULL; //osd + memset(&vf_info, 0, sizeof(vf_info)); + vf_info.v_frame.width = osd_width; + vf_info.v_frame.height = osd_height; + vf_info.v_frame.stride[0] = osd_width; + vf_info.v_frame.pixel_format = PIXEL_FORMAT_ARGB_8888; + block = vo_insert_frame(&vf_info, &pic_vaddr); + + // alloc memory,get isp memory + size_t paddr = 0; + void *vaddr = nullptr; + size_t size = SENSOR_CHANNEL * SENSOR_HEIGHT * SENSOR_WIDTH; + int ret = kd_mpi_sys_mmz_alloc_cached(&paddr, &vaddr, "allocate", "anonymous", size); + if (ret) + { + std::cerr << "physical_memory_block::allocate failed: ret = " << ret << ", errno = " << strerror(errno) << std::endl; + std::abort(); + } + + FaceDetection face_det(argv[1], atof(argv[2]),atof(argv[3]), {SENSOR_CHANNEL, SENSOR_HEIGHT, SENSOR_WIDTH}, reinterpret_cast(vaddr), reinterpret_cast(paddr), atoi(argv[7])); + FaceMesh face_mesh(argv[4],argv[5], {SENSOR_CHANNEL, SENSOR_HEIGHT, SENSOR_WIDTH}, reinterpret_cast(vaddr), reinterpret_cast(paddr), atoi(argv[7])); + + vector det_results; + while (!isp_stop) + { + ScopedTiming st("total time", 1); + + { + ScopedTiming st("read capture", atoi(argv[7])); + // 从vivcap中读取一帧图像到dump_info + memset(&dump_info, 0, sizeof(k_video_frame_info)); + ret = kd_mpi_vicap_dump_frame(vicap_dev, VICAP_CHN_ID_1, VICAP_DUMP_YUV, &dump_info, 1000); + if (ret) + { + printf("sample_vicap...kd_mpi_vicap_dump_frame failed.\n"); + continue; + } + } + + { + ScopedTiming st("isp copy", atoi(argv[7])); + auto vbvaddr = kd_mpi_sys_mmap_cached(dump_info.v_frame.phys_addr[0], size); + memcpy(vaddr, (void *)vbvaddr, SENSOR_HEIGHT * SENSOR_WIDTH * 3); // 这里以后可以去掉,不用copy + kd_mpi_sys_munmap(vbvaddr, size); + } + + det_results.clear(); + + face_det.pre_process(); + face_det.inference(); + // 旋转后图像 + face_det.post_process({SENSOR_WIDTH, SENSOR_HEIGHT}, det_results); + cv::Mat osd_frame(osd_height, osd_width, CV_8UC4, cv::Scalar(0, 0, 0, 0)); + + for (int i = 0; i < det_results.size(); ++i) + { + face_mesh.pre_process(det_results[i].bbox); + face_mesh.inference(); + vector vertices; + face_mesh.post_process({osd_width, osd_height},vertices,false); + face_mesh.get_mesh(osd_frame,vertices,false); + } + + { + ScopedTiming st("osd copy", atoi(argv[7])); + memcpy(pic_vaddr, osd_frame.data, osd_width * osd_height * 4); + kd_mpi_vo_chn_insert_frame(osd_id + 3, &vf_info); // K_VO_OSD0 + ret = kd_mpi_vicap_dump_release(vicap_dev, VICAP_CHN_ID_1, &dump_info); + if (ret) + { + printf("sample_vicap...kd_mpi_vicap_dump_release failed.\n"); + } + } + } + + vo_osd_release_block(); + vivcap_stop(); + + // free memory + ret = kd_mpi_sys_mmz_free(paddr, vaddr); + if (ret) + { + std::cerr << "free failed: ret = " << ret << ", errno = " << strerror(errno) << std::endl; + std::abort(); + } +} + +int main(int argc, char *argv[]) +{ + std::cout << "case " << argv[0] << " built at " << __DATE__ << " " << __TIME__ << std::endl; + if (argc != 8) + { + print_usage(argv[0]); + return -1; + } + + if (strcmp(argv[6], "None") == 0) + { + std::thread thread_isp(video_proc, argv); + while (getchar() != 'q') + { + usleep(10000); + } + + isp_stop = true; + thread_isp.join(); + } + else + { + cv::Mat ori_img = cv::imread(argv[6]); + int ori_w = ori_img.cols; + int ori_h = ori_img.rows; + FaceDetection face_det(argv[1], atof(argv[2]),atof(argv[3]), atoi(argv[7])); + face_det.pre_process(ori_img); + face_det.inference(); + + vector det_results; + face_det.post_process({ori_w, ori_h}, det_results); + + FaceMesh face_mesh(argv[4],argv[5],atoi(argv[7])); + + for (int i = 0; i < det_results.size(); ++i) + { + face_mesh.pre_process(ori_img, det_results[i].bbox); + face_mesh.inference(); + vector vertices; + face_mesh.post_process({ori_w, ori_h},vertices,true); + face_mesh.get_mesh(ori_img,vertices,true); + } + cv::imwrite("face_mesh_result.jpg", ori_img); + } + return 0; +} \ No newline at end of file diff --git a/src/reference/ai_poc/face_mesh/scoped_timing.hpp b/src/reference/ai_poc/face_mesh/scoped_timing.hpp new file mode 100644 index 000000000..874ff1b17 --- /dev/null +++ b/src/reference/ai_poc/face_mesh/scoped_timing.hpp @@ -0,0 +1,70 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include + +/** + * @brief 计时类 + * 统计在该类实例生命周期内的耗时 + */ +class ScopedTiming +{ +public: + /** + * @brief ScopedTiming构造函数,初始化计时对象名称并开始计时 + * @param info 计时对象名称 + * @param enable_profile 是否开始计时 + * @return None + */ + ScopedTiming(std::string info = "ScopedTiming", int enable_profile = 1) + : m_info(info), enable_profile(enable_profile) + { + if (enable_profile) + { + m_start = std::chrono::steady_clock::now(); + } + } + + /** + * @brief ScopedTiming析构,结束计时,并打印耗时 + * @return None + */ + ~ScopedTiming() + { + if (enable_profile) + { + m_stop = std::chrono::steady_clock::now(); + double elapsed_ms = std::chrono::duration(m_stop - m_start).count(); + std::cout << m_info << " took " << elapsed_ms << " ms" << std::endl; + } + } + +private: + int enable_profile; // 是否统计时间 + std::string m_info; // 计时对象名称 + std::chrono::steady_clock::time_point m_start; // 计时开始时间 + std::chrono::steady_clock::time_point m_stop; // 计时结束时间 +}; \ No newline at end of file diff --git a/src/reference/ai_poc/face_mesh/utils.cc b/src/reference/ai_poc/face_mesh/utils.cc new file mode 100755 index 000000000..15332261d --- /dev/null +++ b/src/reference/ai_poc/face_mesh/utils.cc @@ -0,0 +1,402 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +// utils.cpp +#include +#include "utils.h" + +using std::ofstream; +using std::vector; +auto cache = cv::Mat::zeros(1, 1, CV_32FC1); +void Utils::dump_binary_file(const char *file_name, char *data, const size_t size) +{ + // eg:Utils::dump_binary_file(out_name.c_str(),reinterpret_cast(p_outputs_[i]),each_output_size_by_byte_[i+1]-each_output_size_by_byte_[i]); + std::ofstream outf; + outf.open(file_name, std::ofstream::binary); + outf.write(data, size); + outf.close(); +} + +void Utils::dump_gray_image(const char *file_name, const FrameSize &frame_size, unsigned char *data) +{ + cv::Mat gray_image = cv::Mat(frame_size.height, frame_size.width, CV_8UC1, data); + cv::imwrite(file_name, gray_image); +} + +void Utils::dump_color_image(const char *file_name, const FrameSize &frame_size, unsigned char *data) +{ + cv::Mat image_r = cv::Mat(frame_size.height, frame_size.width, CV_8UC1, data); + cv::Mat image_g = cv::Mat(frame_size.height, frame_size.width, CV_8UC1, data+frame_size.height*frame_size.width); + cv::Mat image_b = cv::Mat(frame_size.height, frame_size.width, CV_8UC1, data+2*frame_size.height*frame_size.width); + + std::vector color_vec(3); + color_vec.clear(); + color_vec.push_back(image_b); + color_vec.push_back(image_g); + color_vec.push_back(image_r); + + cv::Mat color_img; + cv::merge(color_vec, color_img); + cv::imwrite(file_name, color_img); +} + +cv::Mat Utils::padding_resize(const cv::Mat img, const FrameSize &frame_size, const cv::Scalar &padding) +{ + // width:dst_width + int ori_w = img.cols; + int ori_h = img.rows; + float ratiow = (float)frame_size.width / ori_w; + float ratioh = (float)frame_size.height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(frame_size.width - new_w) / 2; + float dh = (float)(frame_size.height - new_h) / 2; + int top = (int)(roundf(0 - 0.1)); + int bottom = (int)(roundf(dh * 2 + 0.1)); + int left = (int)(roundf(0 - 0.1)); + int right = (int)(roundf(dw * 2 - 0.1)); + cv::Mat cropped_img; + { + if ((new_w != frame_size.width) || (new_h != frame_size.height)) + { + cv::resize(img, cropped_img, cv::Size(new_w, new_h), cv::INTER_AREA); + } + } + { + // 104, 117, 123,BGR + cv::copyMakeBorder(cropped_img, cropped_img, top, bottom, left, right, cv::BORDER_CONSTANT, padding); + } + return cropped_img; +} + +cv::Mat Utils::resize(const cv::Mat img, const FrameSize &frame_size) +{ + cv::Mat cropped_img; + cv::resize(img, cropped_img, cv::Size(frame_size.width, frame_size.height), cv::INTER_LINEAR); + return cropped_img; +} + +cv::Mat Utils::bgr_to_rgb(cv::Mat ori_img) +{ + cv::Mat rgb_img; + cv::cvtColor(ori_img, rgb_img, cv::COLOR_BGR2RGB); + return rgb_img; +} + +void Utils::hwc_to_chw(cv::Mat &ori_img, std::vector &chw_vec) +{ + // for rgb format + std::vector rgbChannels(3); + cv::split(ori_img, rgbChannels); + for (auto i = 0; i < rgbChannels.size(); i++) + { + std::vector data = std::vector(rgbChannels[i].reshape(1, 1)); + chw_vec.insert(chw_vec.end(), data.begin(), data.end()); + } +} + +void Utils::bgr2rgb_and_hwc2chw(cv::Mat &ori_img, std::vector &chw_vec) +{ + // for bgr format + std::vector bgrChannels(3); + cv::split(ori_img, bgrChannels); + for (auto i = 2; i > -1; i--) + { + std::vector data = std::vector(bgrChannels[i].reshape(1, 1)); + chw_vec.insert(chw_vec.end(), data.begin(), data.end()); + } +} + +void Utils::resize(FrameCHWSize ori_shape, std::vector &chw_vec, runtime_tensor &ai2d_out_tensor) +{ + // build ai2d_in_tensor + dims_t in_shape{1, ori_shape.channel, ori_shape.height, ori_shape.width}; + runtime_tensor ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), chw_vec.data(), chw_vec.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + // ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, typecode_t::dt_uint8, typecode_t::dt_uint8}; + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param { false, 30, 20, 400, 600 }; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, ai2d_pad_mode::constant, {114, 114, 114}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::resize(std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor) +{ + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param { false, 30, 20, 400, 600 }; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, ai2d_pad_mode::constant, {114, 114, 114}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::crop_resize(FrameCHWSize ori_shape, std::vector &chw_vec, Bbox &crop_info, runtime_tensor &ai2d_out_tensor) +{ + // build ai2d_in_tensor + dims_t in_shape{1, ori_shape.channel, ori_shape.height, ori_shape.width}; + runtime_tensor ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), chw_vec.data(), chw_vec.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{true, crop_info.x, crop_info.y, crop_info.w, crop_info.h}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, ai2d_pad_mode::constant, {114, 114, 114}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::crop_resize(Bbox &crop_info, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor) +{ + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{true, crop_info.x, crop_info.y, crop_info.w, crop_info.h}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, ai2d_pad_mode::constant, {114, 114, 114}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::padding_resize(FrameCHWSize ori_shape, std::vector &chw_vec, FrameSize resize_shape, runtime_tensor &ai2d_out_tensor, cv::Scalar padding) +{ + int ori_w = ori_shape.width; + int ori_h = ori_shape.height; + int width = resize_shape.width; + int height = resize_shape.height; + float ratiow = (float)width / ori_w; + float ratioh = (float)height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(width - new_w) / 2; + float dh = (float)(height - new_h) / 2; + int top = (int)(roundf(dh - 0.1)); + int bottom = (int)(roundf(dh + 0.1)); + int left = (int)(roundf(dw - 0.1)); + int right = (int)(roundf(dw - 0.1)); + + // create input + dims_t in_shape{1, ori_shape.channel, ori_h, ori_w}; + auto ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), chw_vec.data(), chw_vec.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{true, {{0, 0}, {0, 0}, {top, bottom}, {left, right}}, ai2d_pad_mode::constant, {padding[0], padding[1], padding[2]}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::padding_resize_one_side(FrameCHWSize ori_shape, std::vector &chw_vec, FrameSize resize_shape, runtime_tensor &ai2d_out_tensor, cv::Scalar padding) +{ + int ori_w = ori_shape.width; + int ori_h = ori_shape.height; + int width = resize_shape.width; + int height = resize_shape.height; + float ratiow = (float)width / ori_w; + float ratioh = (float)height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(width - new_w) / 2; + float dh = (float)(height - new_h) / 2; + int top = (int)(roundf(0)); + int bottom = (int)(roundf(dh * 2 + 0.1)); + int left = (int)(roundf(0)); + int right = (int)(roundf(dw * 2 - 0.1)); + + // create input + dims_t in_shape{1, ori_shape.channel, ori_h, ori_w}; + auto ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), chw_vec.data(), chw_vec.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{true, {{0, 0}, {0, 0}, {top, bottom}, {left, right}}, ai2d_pad_mode::constant, {padding[0], padding[1], padding[2]}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::padding_resize(FrameCHWSize ori_shape, FrameSize resize_shape, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor, const cv::Scalar padding) +{ + int ori_w = ori_shape.width; + int ori_h = ori_shape.height; + int width = resize_shape.width; + int height = resize_shape.height; + float ratiow = (float)width / ori_w; + float ratioh = (float)height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(width - new_w) / 2; + float dh = (float)(height - new_h) / 2; + int top = (int)(roundf(dh - 0.1)); + int bottom = (int)(roundf(dh + 0.1)); + int left = (int)(roundf(dw - 0.1)); + int right = (int)(roundf(dw - 0.1)); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{true, {{0, 0}, {0, 0}, {top, bottom}, {left, right}}, ai2d_pad_mode::constant, {padding[0], padding[1], padding[2]}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::padding_resize_one_side(FrameCHWSize ori_shape, FrameSize resize_shape, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor, const cv::Scalar padding) +{ + int ori_w = ori_shape.width; + int ori_h = ori_shape.height; + int width = resize_shape.width; + int height = resize_shape.height; + float ratiow = (float)width / ori_w; + float ratioh = (float)height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(width - new_w) / 2; + float dh = (float)(height - new_h) / 2; + int top = (int)(roundf(0)); + int bottom = (int)(roundf(dh * 2 + 0.1)); + int left = (int)(roundf(0)); + int right = (int)(roundf(dw * 2 - 0.1)); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{true, {{0, 0}, {0, 0}, {top, bottom}, {left, right}}, ai2d_pad_mode::constant, {padding[0], padding[1], padding[2]}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::affine(FrameCHWSize ori_shape, std::vector &ori_data, float *affine_matrix, runtime_tensor &ai2d_out_tensor) +{ + runtime_tensor ai2d_in_tensor; + // init ai2d in/out + dims_t in_shape{1, ori_shape.channel, ori_shape.height, ori_shape.width}; + ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + + // ai2d input + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), ori_data.data(), ori_data.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {10, 0}}, ai2d_pad_mode::constant, {255, 10, 5}}; + ai2d_resize_param_t resize_param{false, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{true, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {affine_matrix[0], affine_matrix[1], affine_matrix[2], affine_matrix[3], affine_matrix[4], affine_matrix[5]}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +// for video(只算一次即可) +void Utils::affine(float *affine_matrix, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor) +{ + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {10, 0}}, ai2d_pad_mode::constant, {255, 10, 5}}; + ai2d_resize_param_t resize_param{false, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{true, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {affine_matrix[0], affine_matrix[1], affine_matrix[2], affine_matrix[3], affine_matrix[4], affine_matrix[5]}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} \ No newline at end of file diff --git a/src/reference/ai_poc/face_mesh/utils.h b/src/reference/ai_poc/face_mesh/utils.h new file mode 100755 index 000000000..145e5630b --- /dev/null +++ b/src/reference/ai_poc/face_mesh/utils.h @@ -0,0 +1,307 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +// utils.h +#ifndef UTILS_H +#define UTILS_H + +#include +#include +#include +#include +#include +#include +#include + +using namespace nncase; +using namespace nncase::runtime; +using namespace nncase::runtime::k230; +using namespace nncase::F::k230; + +using cv::Mat; +using std::cout; +using std::endl; +using std::ifstream; +using std::vector; + +/** + * @brief 人脸检测框 + */ +typedef struct Bbox +{ + float x; // 人脸检测框的左顶点x坐标 + float y; // 人脸检测框的左顶点x坐标 + float w; + float h; +} Bbox; + +/** + * @brief 人脸五官点 + */ +typedef struct SparseLandmarks +{ + float points[10]; // 人脸五官点,依次是图片的左眼(x,y)、右眼(x,y),鼻子(x,y),左嘴角(x,y),右嘴角 +} SparseLandmarks; + +/** + * @brief 单张/帧图片大小 + */ +typedef struct FrameSize +{ + size_t width; // 宽 + size_t height; // 高 +} FrameSize; + +/** + * @brief 单张/帧图片大小 + */ +typedef struct FrameCHWSize +{ + size_t channel; // 通道 + size_t height; // 高 + size_t width; // 宽 +} FrameCHWSize; + +/** + * @brief AI Demo工具类 + * 封装了AI Demo常用的函数,包括二进制文件读取、文件保存、图片预处理等操作 + */ +class Utils +{ +public: + /** + * @brief 读取2进制文件 + * @param file_name 文件路径 + * @return 文件对应类型的数据 + */ + template + static vector read_binary_file(const char *file_name) + { + ifstream ifs(file_name, std::ios::binary); + ifs.seekg(0, ifs.end); + size_t len = ifs.tellg(); + vector vec(len / sizeof(T), 0); + ifs.seekg(0, ifs.beg); + ifs.read(reinterpret_cast(vec.data()), len); + ifs.close(); + return vec; + } + + /** + * @brief 打印数据 + * @param data 需打印数据对应指针 + * @param size 需打印数据大小 + * @return None + */ + template + static void dump(const T *data, size_t size) + { + for (size_t i = 0; i < size; i++) + { + cout << data[i] << " "; + } + cout << endl; + } + + // 静态成员函数不依赖于类的实例,可以直接通过类名调用 + /** + * @brief 将数据以2进制方式保存为文件 + * @param file_name 保存文件路径+文件名 + * @param data 需要保存的数据 + * @param size 需要保存的长度 + * @return None + */ + static void dump_binary_file(const char *file_name, char *data, const size_t size); + + /** + * @brief 将数据保存为灰度图片 + * @param file_name 保存图片路径+文件名 + * @param frame_size 保存图片的宽、高 + * @param data 需要保存的数据 + * @return None + */ + static void dump_gray_image(const char *file_name, const FrameSize &frame_size, unsigned char *data); + + /** + * @brief 将数据保存为彩色图片 + * @param file_name 保存图片路径+文件名 + * @param frame_size 保存图片的宽、高 + * @param data 需要保存的数据 + * @return None + */ + static void dump_color_image(const char *file_name, const FrameSize &frame_size, unsigned char *data); + + + /*************************for img process********************/ + /** + * @brief 对图片进行先padding后resize的处理 + * @param ori_img 原始图片 + * @param frame_size 需要resize图像的宽高 + * @param padding 需要padding的像素,默认是cv::Scalar(104, 117, 123),BGR + * @return 处理后图像 + */ + static cv::Mat padding_resize(const cv::Mat img, const FrameSize &frame_size, const cv::Scalar &padding = cv::Scalar(104, 117, 123)); + + /** + * @brief 对图片resize + * @param ori_img 原始图片 + * @param frame_size 需要resize图像的宽高 + * @param padding 需要padding的像素,默认是cv::Scalar(104, 117, 123),BGR + * @return 处理后图像 + */ + static cv::Mat resize(const cv::Mat ori_img, const FrameSize &frame_size); + + /** + * @brief 将图片从bgr转为rgb + * @param ori_img 原始图片 + * @return 处理后图像 + */ + static cv::Mat bgr_to_rgb(cv::Mat ori_img); + + /** + * @brief 将RGB或RGB图片从hwc转为chw + * @param ori_img 原始图片 + * @param chw_vec 转为chw后的数据 + * @return None + */ + static void hwc_to_chw(cv::Mat &ori_img, std::vector &chw_vec); // for rgb data + + /** + * @brief 将BGR图片从hwc转为chw + * @param ori_img 原始图片 + * @param chw_vec 转为chw后的数据 + * @return None + */ + static void bgr2rgb_and_hwc2chw(cv::Mat &ori_img, std::vector &chw_vec); + + /*************************for ai2d ori_img process********************/ + // resize + /** + * @brief resize函数,对chw数据进行resize + * @param ori_shape 原始数据chw + * @param chw_vec 原始数据 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + void resize(FrameCHWSize ori_shape, std::vector &chw_vec, runtime_tensor &ai2d_out_tensor); + + /** + * @brief resize函数 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + void resize(std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor); + + // crop resize + /** + * @brief resize函数,对chw数据进行crop & resize + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + static void crop_resize(FrameCHWSize ori_shape, std::vector &chw_vec, Bbox &crop_info, runtime_tensor &ai2d_out_tensor); + + /** + * @brief crop_resize函数,对chw数据进行crop & resize + * @param crop_info 需要crop的位置,x,y,w,h + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + static void crop_resize(Bbox &crop_info, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor); + + // padding resize + /** + * @brief padding_resize函数(上下左右padding),对chw数据进行padding & resize + * @param ori_shape 原始数据chw + * @param chw_vec 原始数据 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + static void padding_resize(FrameCHWSize ori_shape, std::vector &chw_vec, FrameSize resize_shape, runtime_tensor &ai2d_out_tensor, cv::Scalar padding); + + /** + * @brief padding_resize函数(右或下padding),对chw数据进行padding & resize + * @param ori_shape 原始数据chw + * @param chw_vec 原始数据 + * @param resize_shape resize之后的大小 + * @param ai2d_out_tensor ai2d输出 + * @param padding 填充值,用于resize时的等比例变换 + * @return None + */ + static void padding_resize_one_side(FrameCHWSize ori_shape, std::vector &chw_vec, FrameSize resize_shape, runtime_tensor &ai2d_out_tensor, cv::Scalar padding); + + /** + * @brief padding_resize函数(上下左右padding),对chw数据进行padding & resize + * @param ori_shape 原始数据chw + * @param resize_shape resize之后的大小 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @param padding 填充值,用于resize时的等比例变换 + * @return None + */ + static void padding_resize(FrameCHWSize ori_shape, FrameSize resize_shape, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor, cv::Scalar padding); + + /** + * @brief padding_resize函数(右或下padding),对chw数据进行padding & resize + * @param ori_shape 原始数据chw + * @param resize_shape resize之后的大小 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @param padding 填充值,用于resize时的等比例变换 + * @return None + */ + static void padding_resize_one_side(FrameCHWSize ori_shape, FrameSize resize_shape, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor, const cv::Scalar padding); + + // affine + /** + * @brief 仿射变换函数,对chw数据进行仿射变换(for imgae) + * @param ori_shape 原始数据chw大小 + * @param ori_data 原始数据 + * @param affine_matrix 仿射变换矩阵 + * @param ai2d_out_tensor 仿射变换后的数据 + * @return None + */ + static void affine(FrameCHWSize ori_shape, std::vector &ori_data, float *affine_matrix, runtime_tensor &ai2d_out_tensor); + + /** + * @brief 仿射变换函数,对chw数据进行仿射变换(for video) + * @param affine_matrix 仿射变换矩阵 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + static void affine(float *affine_matrix, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor); +}; + +#endif diff --git a/src/reference/ai_poc/face_mesh/vi_vo.h b/src/reference/ai_poc/face_mesh/vi_vo.h new file mode 100644 index 000000000..f0c1bccc5 --- /dev/null +++ b/src/reference/ai_poc/face_mesh/vi_vo.h @@ -0,0 +1,627 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include "mpi_sys_api.h" + +/* vicap */ +#include +#include +#include +#include +#include + +#include "k_module.h" +#include "k_type.h" +#include "k_vb_comm.h" +#include "k_video_comm.h" +#include "k_sys_comm.h" +#include "mpi_vb_api.h" +#include "mpi_vicap_api.h" +#include "mpi_isp_api.h" +#include "mpi_sys_api.h" +#include "k_vo_comm.h" +#include "mpi_vo_api.h" + +#include "vo_test_case.h" + +#include "k_connector_comm.h" +#include "mpi_connector_api.h" +#include "k_autoconf_comm.h" + + +#if defined(CONFIG_BOARD_K230_CANMV) +#define SENSOR_CHANNEL (3) // isp通道数 +#define SENSOR_HEIGHT (720) // isp高度,ai输入,竖屏 +#define SENSOR_WIDTH (1280) // isp宽度,ai输入,竖屏 +#define ISP_CHN0_WIDTH (1920)//(1920) +#define ISP_CHN0_HEIGHT (1080)//(1080) +#define vicap_install_osd (1) +#define osd_id K_VO_OSD3 +#define osd_width (1920) +#define osd_height (1080) +#else +#define SENSOR_CHANNEL (3) // isp通道数 +#define SENSOR_HEIGHT (1280) // isp高度,ai输入,竖屏 +#define SENSOR_WIDTH (720) // isp宽度,ai输入,竖屏 +#define ISP_CHN0_WIDTH (1088)//(1920) +#define ISP_CHN0_HEIGHT (1920)//(1080) +#define vicap_install_osd (1) +#define osd_id K_VO_OSD3 +#define osd_width (1080) +#define osd_height (1920) +#endif + + +k_vb_config config; +k_vicap_dev vicap_dev; +k_vicap_chn vicap_chn; +k_vicap_dev_attr dev_attr; +k_vicap_chn_attr chn_attr; +k_vicap_sensor_info sensor_info; +k_vicap_sensor_type sensor_type; +k_mpp_chn vicap_mpp_chn; +k_mpp_chn vo_mpp_chn; + +k_video_frame_info dump_info; + +k_vo_draw_frame vo_frame = (k_vo_draw_frame) { + 1, + 16, + 16, + 128, + 128, + 1 +}; + +static k_vb_blk_handle block; +k_u32 g_pool_id; + +int vo_creat_layer_test(k_vo_layer chn_id, layer_info *info) +{ + k_vo_video_layer_attr attr; + + // check layer + if ((chn_id >= K_MAX_VO_LAYER_NUM) || ((info->func & K_VO_SCALER_ENABLE) && (chn_id != K_VO_LAYER0)) + || ((info->func != 0) && (chn_id == K_VO_LAYER2))) + { + printf("input layer num failed \n"); + return -1 ; + } + + // check scaler + + // set offset + attr.display_rect = info->offset; + // set act + attr.img_size = info->act_size; + // sget size + info->size = info->act_size.height * info->act_size.width * 3 / 2; + //set pixel format + attr.pixel_format = info->format; + if (info->format != PIXEL_FORMAT_YVU_PLANAR_420) + { + printf("input pix format failed \n"); + return -1; + } + // set stride + attr.stride = (info->act_size.width / 8 - 1) + ((info->act_size.height - 1) << 16); + // set function + attr.func = info->func; + // set scaler attr + attr.scaler_attr = info->attr; + + // set video layer atrr + kd_mpi_vo_set_video_layer_attr(chn_id, &attr); + + // enable layer + kd_mpi_vo_enable_video_layer(chn_id); + + return 0; +} + +k_vb_blk_handle vo_insert_frame(k_video_frame_info *vf_info, void **pic_vaddr) +{ + k_u64 phys_addr = 0; + k_u32 *virt_addr; + k_vb_blk_handle handle; + k_s32 size; + + if (vf_info == NULL) + return K_FALSE; + + if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_ABGR_8888 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_ARGB_8888) + size = vf_info->v_frame.height * vf_info->v_frame.width * 4; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_RGB_565 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_BGR_565) + size = vf_info->v_frame.height * vf_info->v_frame.width * 2; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_ABGR_4444 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_ARGB_4444) + size = vf_info->v_frame.height * vf_info->v_frame.width * 2; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_RGB_888 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_BGR_888) + size = vf_info->v_frame.height * vf_info->v_frame.width * 3; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_ARGB_1555 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_ABGR_1555) + size = vf_info->v_frame.height * vf_info->v_frame.width * 2; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_YVU_PLANAR_420) + size = vf_info->v_frame.height * vf_info->v_frame.width * 3 / 2; + + size = size + 4096; // 强制4K ,后边得删了 + + printf("vb block size is %x \n", size); + + handle = kd_mpi_vb_get_block(g_pool_id, size, NULL); + if (handle == VB_INVALID_HANDLE) + { + printf("%s get vb block error\n", __func__); + return K_FAILED; + } + + phys_addr = kd_mpi_vb_handle_to_phyaddr(handle); + if (phys_addr == 0) + { + printf("%s get phys addr error\n", __func__); + return K_FAILED; + } + + virt_addr = (k_u32 *)kd_mpi_sys_mmap(phys_addr, size); + // virt_addr = (k_u32 *)kd_mpi_sys_mmap_cached(phys_addr, size); + + if (virt_addr == NULL) + { + printf("%s mmap error\n", __func__); + return K_FAILED; + } + + vf_info->mod_id = K_ID_VO; + vf_info->pool_id = g_pool_id; + vf_info->v_frame.phys_addr[0] = phys_addr; + if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_YVU_PLANAR_420) + vf_info->v_frame.phys_addr[1] = phys_addr + (vf_info->v_frame.height * vf_info->v_frame.stride[0]); + *pic_vaddr = virt_addr; + + printf("phys_addr is %lx g_pool_id is %d \n", phys_addr, g_pool_id); + + return handle; +} + +k_u32 vo_creat_osd_test(k_vo_osd osd, osd_info *info) +{ + k_vo_video_osd_attr attr; + + // set attr + attr.global_alptha = info->global_alptha; + + if (info->format == PIXEL_FORMAT_ABGR_8888 || info->format == PIXEL_FORMAT_ARGB_8888) + { + info->size = info->act_size.width * info->act_size.height * 4; + info->stride = info->act_size.width * 4 / 8; + } + else if (info->format == PIXEL_FORMAT_RGB_565 || info->format == PIXEL_FORMAT_BGR_565) + { + info->size = info->act_size.width * info->act_size.height * 2; + info->stride = info->act_size.width * 2 / 8; + } + else if (info->format == PIXEL_FORMAT_RGB_888 || info->format == PIXEL_FORMAT_BGR_888) + { + info->size = info->act_size.width * info->act_size.height * 3; + info->stride = info->act_size.width * 3 / 8; + } + else if(info->format == PIXEL_FORMAT_ARGB_4444 || info->format == PIXEL_FORMAT_ABGR_4444) + { + info->size = info->act_size.width * info->act_size.height * 2; + info->stride = info->act_size.width * 2 / 8; + } + else if(info->format == PIXEL_FORMAT_ARGB_1555 || info->format == PIXEL_FORMAT_ABGR_1555) + { + info->size = info->act_size.width * info->act_size.height * 2; + info->stride = info->act_size.width * 2 / 8; + } + else + { + printf("set osd pixel format failed \n"); + } + + attr.stride = info->stride; + attr.pixel_format = info->format; + attr.display_rect = info->offset; + attr.img_size = info->act_size; + kd_mpi_vo_set_video_osd_attr(osd, &attr); + + kd_mpi_vo_osd_enable(osd); + + return 0; +} + +void sample_vicap_install_osd(void) +{ + osd_info osd; + + osd.act_size.width = osd_width ; + osd.act_size.height = osd_height; + osd.offset.x = 0; + osd.offset.y = 0; + osd.global_alptha = 0xff; + // osd.global_alptha = 0x32; + osd.format = PIXEL_FORMAT_ARGB_8888;//PIXEL_FORMAT_ARGB_4444; //PIXEL_FORMAT_ARGB_1555;//PIXEL_FORMAT_ARGB_8888; + + vo_creat_osd_test(osd_id, &osd); +} + +void vo_osd_release_block(void) +{ + if(vicap_install_osd == 1) + { + kd_mpi_vo_osd_disable(osd_id); + kd_mpi_vb_release_block(block); + } + +} + +static k_s32 sample_connector_init(void) +{ + k_u32 ret = 0; + k_s32 connector_fd; +#if defined(CONFIG_BOARD_K230_CANMV) + k_connector_type connector_type = LT9611_MIPI_4LAN_1920X1080_30FPS;// HX8377_V2_MIPI_4LAN_1080X1920_30FPS; +#else + k_connector_type connector_type = HX8377_V2_MIPI_4LAN_1080X1920_30FPS; +#endif + k_connector_info connector_info; + + memset(&connector_info, 0, sizeof(k_connector_info)); + + //connector get sensor info + ret = kd_mpi_get_connector_info(connector_type, &connector_info); + if (ret) { + printf("sample_vicap, the sensor type not supported!\n"); + return ret; + } + + connector_fd = kd_mpi_connector_open(connector_info.connector_name); + if (connector_fd < 0) { + printf("%s, connector open failed.\n", __func__); + return K_ERR_VO_NOTREADY; + } + + // set connect power + kd_mpi_connector_power_set(connector_fd, K_TRUE); + // connector init + kd_mpi_connector_init(connector_fd, connector_info); + + return 0; +} + +static k_s32 vo_layer_vdss_bind_vo_config(void) +{ + layer_info info; + + k_vo_layer chn_id = K_VO_LAYER1; + + memset(&info, 0, sizeof(info)); + + sample_connector_init(); + + // config lyaer + info.act_size.width = ISP_CHN0_WIDTH;//ISP_CHN0_HEIGHT;//1080;//640;//1080; + info.act_size.height = ISP_CHN0_HEIGHT;//ISP_CHN0_WIDTH;//1920;//480;//1920; + info.format = PIXEL_FORMAT_YVU_PLANAR_420; + info.func = 0;//K_ROTATION_180;////K_ROTATION_90; + info.global_alptha = 0xff; + info.offset.x = 0;//(1080-w)/2, + info.offset.y = 0;//(1920-h)/2; + vo_creat_layer_test(chn_id, &info); + + if(vicap_install_osd == 1) + sample_vicap_install_osd(); + + //exit ; + return 0; +} + +static void sample_vicap_bind_vo(k_mpp_chn vicap_mpp_chn, k_mpp_chn vo_mpp_chn) +{ + k_s32 ret; + + ret = kd_mpi_sys_bind(&vicap_mpp_chn, &vo_mpp_chn); + if (ret) { + printf("kd_mpi_sys_unbind failed:0x%x\n", ret); + } + + return; +} + +static void sample_vicap_unbind_vo(k_mpp_chn vicap_mpp_chn, k_mpp_chn vo_mpp_chn) +{ + k_s32 ret; + + ret = kd_mpi_sys_unbind(&vicap_mpp_chn, &vo_mpp_chn); + if (ret) { + printf("kd_mpi_sys_unbind failed:0x%x\n", ret); + } + + return; +} + +int vivcap_start() +{ + k_s32 ret = 0; + + k_u32 pool_id; + k_vb_pool_config pool_config; + + printf("sample_vicap ...\n"); + +#if defined(CONFIG_BOARD_K230_CANMV) + sensor_type = OV_OV5647_MIPI_CSI0_1920X1080_30FPS_10BIT_LINEAR; + kd_mpi_vicap_set_mclk(VICAP_MCLK0, VICAP_PLL0_CLK_DIV4, 16, 1); +#else + sensor_type = IMX335_MIPI_2LANE_RAW12_2592X1944_30FPS_LINEAR; +#endif + vicap_dev = VICAP_DEV_ID_0; + + memset(&config, 0, sizeof(config)); + config.max_pool_cnt = 64; + //VB for YUV420SP output + config.comm_pool[0].blk_cnt = 5; + config.comm_pool[0].mode = VB_REMAP_MODE_NOCACHE; + config.comm_pool[0].blk_size = VICAP_ALIGN_UP((ISP_CHN0_WIDTH * ISP_CHN0_HEIGHT * 3 / 2), VICAP_ALIGN_1K); + + //VB for RGB888 output + config.comm_pool[1].blk_cnt = 5; + config.comm_pool[1].mode = VB_REMAP_MODE_NOCACHE; + config.comm_pool[1].blk_size = VICAP_ALIGN_UP((SENSOR_HEIGHT * SENSOR_WIDTH * 3 ), VICAP_ALIGN_1K); + + ret = kd_mpi_vb_set_config(&config); + if (ret) { + printf("vb_set_config failed ret:%d\n", ret); + return ret; + } + + k_vb_supplement_config supplement_config; + memset(&supplement_config, 0, sizeof(supplement_config)); + supplement_config.supplement_config |= VB_SUPPLEMENT_JPEG_MASK; + + ret = kd_mpi_vb_set_supplement_config(&supplement_config); + if (ret) { + printf("vb_set_supplement_config failed ret:%d\n", ret); + return ret; + } + + ret = kd_mpi_vb_init(); + if (ret) { + printf("vb_init failed ret:%d\n", ret); + return ret; + } + printf("sample_vicap ...kd_mpi_vicap_get_sensor_info\n"); + + // dwc_dsi_init(); + vo_layer_vdss_bind_vo_config(); + + if(vicap_install_osd == 1) + { + memset(&pool_config, 0, sizeof(pool_config)); + pool_config.blk_size = VICAP_ALIGN_UP((osd_width * osd_height * 4 * 2), VICAP_ALIGN_1K); + pool_config.blk_cnt = 4; + pool_config.mode = VB_REMAP_MODE_NOCACHE; + pool_id = kd_mpi_vb_create_pool(&pool_config); // osd0 - 3 argb 320 x 240 + g_pool_id = pool_id; + + printf("--------aa--------------g_pool_id is %d pool_id is %d \n",g_pool_id, pool_id); + } + + memset(&sensor_info, 0, sizeof(k_vicap_sensor_info)); + ret = kd_mpi_vicap_get_sensor_info(sensor_type, &sensor_info); + if (ret) { + printf("sample_vicap, the sensor type not supported!\n"); + return ret; + } + + memset(&dev_attr, 0, sizeof(k_vicap_dev_attr)); + dev_attr.acq_win.h_start = 0; + dev_attr.acq_win.v_start = 0; +#if defined (CONFIG_BOARD_K230_CANMV) + dev_attr.acq_win.width = ISP_CHN0_WIDTH; + dev_attr.acq_win.height = ISP_CHN0_HEIGHT; +#else + dev_attr.acq_win.width = 2592;//SENSOR_HEIGHT; + dev_attr.acq_win.height = 1944;//SENSOR_WIDTH; +#endif + dev_attr.mode = VICAP_WORK_ONLINE_MODE; + + dev_attr.pipe_ctrl.data = 0xFFFFFFFF; + dev_attr.pipe_ctrl.bits.af_enable = 0; + dev_attr.pipe_ctrl.bits.ahdr_enable = 0; + + + dev_attr.cpature_frame = 0; + memcpy(&dev_attr.sensor_info, &sensor_info, sizeof(k_vicap_sensor_info)); + + ret = kd_mpi_vicap_set_dev_attr(vicap_dev, dev_attr); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_set_dev_attr failed.\n"); + return ret; + } + + memset(&chn_attr, 0, sizeof(k_vicap_chn_attr)); + + //set chn0 output yuv420sp + chn_attr.out_win.h_start = 0; + chn_attr.out_win.v_start = 0; + chn_attr.out_win.width = ISP_CHN0_WIDTH; + chn_attr.out_win.height = ISP_CHN0_HEIGHT; + + +#if defined(CONFIG_BOARD_K230_CANMV) + chn_attr.crop_win = dev_attr.acq_win; +#else + // chn_attr.crop_win = dev_attr.acq_win; + chn_attr.crop_win.h_start = 768; + chn_attr.crop_win.v_start = 16; + chn_attr.crop_win.width = ISP_CHN0_WIDTH; + chn_attr.crop_win.height = ISP_CHN0_HEIGHT; +#endif + + chn_attr.scale_win = chn_attr.out_win; + chn_attr.crop_enable = K_FALSE; + chn_attr.scale_enable = K_FALSE; + // chn_attr.dw_enable = K_FALSE; + chn_attr.chn_enable = K_TRUE; + chn_attr.pix_format = PIXEL_FORMAT_YVU_PLANAR_420; + chn_attr.buffer_num = VICAP_MAX_FRAME_COUNT;//at least 3 buffers for isp + chn_attr.buffer_size = config.comm_pool[0].blk_size; + vicap_chn = VICAP_CHN_ID_0; + + printf("sample_vicap ...kd_mpi_vicap_set_chn_attr, buffer_size[%d]\n", chn_attr.buffer_size); + ret = kd_mpi_vicap_set_chn_attr(vicap_dev, vicap_chn, chn_attr); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_set_chn_attr failed.\n"); + return ret; + } + + //bind vicap chn 0 to vo + vicap_mpp_chn.mod_id = K_ID_VI; + vicap_mpp_chn.dev_id = vicap_dev; + vicap_mpp_chn.chn_id = vicap_chn; + + vo_mpp_chn.mod_id = K_ID_VO; + vo_mpp_chn.dev_id = K_VO_DISPLAY_DEV_ID; + vo_mpp_chn.chn_id = K_VO_DISPLAY_CHN_ID1; + + sample_vicap_bind_vo(vicap_mpp_chn, vo_mpp_chn); + printf("sample_vicap ...dwc_dsi_init\n"); + + //set chn1 output rgb888p + chn_attr.out_win.h_start = 0; + chn_attr.out_win.v_start = 0; + chn_attr.out_win.width = SENSOR_WIDTH ; + chn_attr.out_win.height = SENSOR_HEIGHT; + // chn_attr.crop_win = dev_attr.acq_win; + +#if defined(CONFIG_BOARD_K230_CANMV) + chn_attr.crop_win = dev_attr.acq_win; +#else + chn_attr.crop_win.h_start = 768; + chn_attr.crop_win.v_start = 16; + chn_attr.crop_win.width = ISP_CHN0_WIDTH; + chn_attr.crop_win.height = ISP_CHN0_HEIGHT; +#endif + + chn_attr.scale_win = chn_attr.out_win; + chn_attr.crop_enable = K_FALSE; + chn_attr.scale_enable = K_FALSE; + // chn_attr.dw_enable = K_FALSE; + chn_attr.chn_enable = K_TRUE; + chn_attr.pix_format = PIXEL_FORMAT_BGR_888_PLANAR; + chn_attr.buffer_num = VICAP_MAX_FRAME_COUNT;//at least 3 buffers for isp + chn_attr.buffer_size = config.comm_pool[1].blk_size; + + printf("sample_vicap ...kd_mpi_vicap_set_chn_attr, buffer_size[%d]\n", chn_attr.buffer_size); + ret = kd_mpi_vicap_set_chn_attr(vicap_dev, VICAP_CHN_ID_1, chn_attr); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_set_chn_attr failed.\n"); + return ret; + } + + printf("sample_vicap ...kd_mpi_vicap_init\n"); + ret = kd_mpi_vicap_init(vicap_dev); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_init failed.\n"); + // goto err_exit; + } + + printf("sample_vicap ...kd_mpi_vicap_start_stream\n"); + ret = kd_mpi_vicap_start_stream(vicap_dev); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_init failed.\n"); + // goto err_exit; + } + + return ret; +} + +int vivcap_stop() +{ + printf("sample_vicap ...kd_mpi_vicap_stop_stream\n"); + int ret = kd_mpi_vicap_stop_stream(vicap_dev); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_init failed.\n"); + return ret; + } + + ret = kd_mpi_vicap_deinit(vicap_dev); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_deinit failed.\n"); + return ret; + } + + kd_mpi_vo_disable_video_layer(K_VO_LAYER1); + + vicap_mpp_chn.mod_id = K_ID_VI; + vicap_mpp_chn.dev_id = vicap_dev; + vicap_mpp_chn.chn_id = vicap_chn; + + vo_mpp_chn.mod_id = K_ID_VO; + vo_mpp_chn.dev_id = K_VO_DISPLAY_DEV_ID; + vo_mpp_chn.chn_id = K_VO_DISPLAY_CHN_ID1; + + sample_vicap_unbind_vo(vicap_mpp_chn, vo_mpp_chn); + + /*Allow one frame time for the VO to release the VB block*/ + k_u32 display_ms = 1000 / 33; + usleep(1000 * display_ms); + + ret = kd_mpi_vb_exit(); + if (ret) { + printf("sample_vicap, kd_mpi_vb_exit failed.\n"); + return ret; + } + + return 0; +} + +void yuv_rotate_90(char *des, char *src,int width,int height) +{ + int n = 0; + int hw = width>>1; + int hh = height>>1; + int size = width * height; + int hsize = size>>2; + + int pos = 0; + + for(int i = width-1;i >= 0;i--) + { + pos = 0; + for(int j= 0;j < height;j++) + { + des[n++]= src[pos+i]; + pos += width; + } + } + +} \ No newline at end of file diff --git a/src/reference/ai_poc/face_parse/face_detection.h b/src/reference/ai_poc/face_parse/face_detection.h index 4e4331600..385d98109 100755 --- a/src/reference/ai_poc/face_parse/face_detection.h +++ b/src/reference/ai_poc/face_parse/face_detection.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2022, Canaan Bright Sight Co., Ltd +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/src/reference/ai_poc/face_pose/face_detection.h b/src/reference/ai_poc/face_pose/face_detection.h index 4e4331600..385d98109 100755 --- a/src/reference/ai_poc/face_pose/face_detection.h +++ b/src/reference/ai_poc/face_pose/face_detection.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2022, Canaan Bright Sight Co., Ltd +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/src/reference/ai_poc/head_detection/head_detection.h b/src/reference/ai_poc/head_detection/head_detection.h index a9db02d14..bbbf6cbc7 100644 --- a/src/reference/ai_poc/head_detection/head_detection.h +++ b/src/reference/ai_poc/head_detection/head_detection.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2022, Canaan Bright Sight Co., Ltd +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/src/reference/ai_poc/ocr/README.md b/src/reference/ai_poc/ocr/README.md index 82c850b6b..69daaeb40 100644 --- a/src/reference/ai_poc/ocr/README.md +++ b/src/reference/ai_poc/ocr/README.md @@ -17,11 +17,13 @@ Options: debug_mode 是否需要调试,0、1、2分别表示不调试、简单调试、详细调试 #单图推理示例:(ocr_img.sh) -./ocr_rec.elf ocr_det.kmodel 0.25 0.5 test.jpg ocr_rec.kmodel 0 +./ocr_reco.elf ocr_det_int16.kmodel 0.25 0.4 333.jpg ocr_rec_int16.kmodel 0 #视频流推理:(ocr_isp.sh) -./ocr_rec.elf ocr_det.kmodel 0.25 0.5 None ocr_rec.kmodel 0 +./ocr_reco.elf ocr_det_int16.kmodel 0.25 0.4 None ocr_rec_int16.kmodel 0 ``` +## 2.2 效果展示 +文字识别效果图 diff --git a/src/reference/ai_poc/self_learning/CMakeLists.txt b/src/reference/ai_poc/self_learning/CMakeLists.txt new file mode 100755 index 000000000..b8a7cea7c --- /dev/null +++ b/src/reference/ai_poc/self_learning/CMakeLists.txt @@ -0,0 +1,18 @@ +set(src main.cc utils.cc ai_base.cc self_learning.cc) +set(bin self_learning.elf) + +include_directories(${PROJECT_SOURCE_DIR}) +include_directories(${nncase_sdk_root}/riscv64/rvvlib/include) +include_directories(${k230_sdk}/src/big/mpp/userapps/api/) +include_directories(${k230_sdk}/src/big/mpp/include) +include_directories(${k230_sdk}/src/big/mpp/include/comm) +include_directories(${k230_sdk}/src/big/mpp/userapps/sample/sample_vo) +link_directories(${nncase_sdk_root}/riscv64/rvvlib/) + +add_executable(${bin} ${src}) +target_link_libraries(${bin} -Wl,--start-group rvv Nncase.Runtime.Native nncase.rt_modules.k230 functional_k230 sys vicap vb cam_device cam_engine + hal oslayer ebase fpga isp_drv binder auto_ctrol common cam_caldb isi 3a buffer_management cameric_drv video_in virtual_hal start_engine cmd_buffer + switch cameric_reg_drv t_database_c t_mxml_c t_json_c t_common_c vo connector sensor atomic dma -Wl,--end-group) + +target_link_libraries(${bin} opencv_imgcodecs opencv_imgproc opencv_core zlib libjpeg-turbo libopenjp2 libpng libtiff libwebp csi_cv) +install(TARGETS ${bin} DESTINATION bin) diff --git a/src/reference/ai_poc/self_learning/README.md b/src/reference/ai_poc/self_learning/README.md new file mode 100755 index 000000000..e33050e29 --- /dev/null +++ b/src/reference/ai_poc/self_learning/README.md @@ -0,0 +1,84 @@ +# 1.简介 + +自学习(self-taught learning) 是更为一般的、更强大的学习方式,它不要求未标注数据和已标注数据有同样的分布。自学习在无标注数据集的特征学习中应用更广。 + +假设有一个区分香蕉和葡萄的计算机视觉任务。为了获取大量的未标注数据,从互联网下载含有香蕉和葡萄的图像数据集,然后在这个图像数据集上训练稀疏自编码器。这个自编码器的输出是一个定长的向量,这个向量用于提取图像特征。这种情形就是“自学习”。 + +自学习包括两个部分,第一个是用无标签的样本集训练稀疏自编码器,第二个是用有标签的训练样本集训练一个分类器。 + +具体过程如下: + +第一步,设置神经网络的结构; + +第二步,利用无标签数据集训练稀疏自编码器; + +第三步,利用稀疏自编码器对有标签的训练样本集和测试样本集提取特征; + +第四步,利用第三步提取的训练集特征及其标签集**,**训练一个分类器。 + + +# 2.应用使用说明 + +## 2.1 使用帮助 + +``` +Usage: ./self_learning.elf +For example: + [for isp] ./self_learning.elf recognition.kmodel None 0 3 work +Options: + 1> kmodel kmodel文件路径 + 2> input_mode 摄像头(None) + 3> debug_mode 是否需要调试,0、1、2分别表示不调试、简单调试、详细调试 + 4> topK 返回topK结果 + 5> mode 操作模式,[work] or [label] +``` + +## 2.2 操作步骤 + +### 2.2.1 创建类别层级目录 + +自学习效果图 + +首先,在小核界面执行 “./create_category” 命令,然后按照提示,依次输入类别,比如“apple”、“pear”、“banana”、“grape”、“orange”,自动创建类别层级目录。 可执行文件 create_category 是由项目工程 self_learning_small 生成的。 + +自学习效果图 + + + +### 2.2.2 标注【label】 + +自学习效果图 + +在大核界面,执行 + +``` +./self_learning_label.sh +``` + +查看 self_learning_label.sh :( cat self_learning_label.sh 即可查看 ) + +``` +./self_learning.elf recognition.kmodel None 0 3 label +``` + +每张图片按照不同角度拍摄 4~6 张即可。 + +可执行文件 self_learning.elf 是由 self_learning 项目工程生成的。 + +需要注意的是,退出【label】模式,需要 重启板子。重启命令:reboot。 + +### 2.2.3 检测识别【work】 + +自学习效果图 + +在大核界面,执行 + +``` +./self_learning_work.sh +``` + +查看 self_learning_work.sh :( cat self_learning_work.sh 即可查看 ) + +``` +./self_learning.elf recognition.kmodel None 0 3 work +``` diff --git a/src/reference/ai_poc/self_learning/ai_base.cc b/src/reference/ai_poc/self_learning/ai_base.cc new file mode 100755 index 000000000..6ecbdd59d --- /dev/null +++ b/src/reference/ai_poc/self_learning/ai_base.cc @@ -0,0 +1,191 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "ai_base.h" + +#include +#include + +#include "utils.h" + +using std::cout; +using std::endl; +using namespace nncase; +using namespace nncase::runtime::detail; + +AIBase::AIBase(const char *kmodel_file,const string model_name, const int debug_mode) : debug_mode_(debug_mode),model_name_(model_name) +{ + if (debug_mode > 1) + cout << "kmodel_file:" << kmodel_file << endl; + // kmodel_vec_ = Utils::read_binary_file(kmodel_file); + // kmodel_interp_.load_model({(const gsl::byte *)kmodel_vec_.data(), kmodel_vec_.size()}).expect("cannot load kmodel."); + + std::ifstream ifs(kmodel_file, std::ios::binary); + kmodel_interp_.load_model(ifs).expect("Invalid kmodel"); + + set_input_init(); + set_output_init(); +} + +AIBase::~AIBase() +{ +} + +void AIBase::set_input_init() +{ + ScopedTiming st(model_name_ + " set_input init", debug_mode_); + int input_total_size = 0; + each_input_size_by_byte_.push_back(0); // 先补0,为之后做准备 + for (int i = 0; i < kmodel_interp_.inputs_size(); ++i) + { + auto desc = kmodel_interp_.input_desc(i); + auto shape = kmodel_interp_.input_shape(i); + auto tensor = host_runtime_tensor::create(desc.datatype, shape, hrt::pool_shared).expect("cannot create input tensor"); + kmodel_interp_.input_tensor(i, tensor).expect("cannot set input tensor"); + vector in_shape = {shape[0], shape[1], shape[2], shape[3]}; + input_shapes_.push_back(in_shape); + int dsize = shape[0] * shape[1] * shape[2] * shape[3]; + if (debug_mode_ > 1) + cout << "input shape:" << shape[0] << " " << shape[1] << " " << shape[2] << " " << shape[3] << endl; + // DEFINE_TYPECODE(uint8, u8, 0x06) + // DEFINE_TYPECODE(float32, f32, 0x0B) + if (desc.datatype == 0x06) + { + input_total_size += dsize; + each_input_size_by_byte_.push_back(input_total_size); + } + else if (desc.datatype == 0x0B) + { + input_total_size += (dsize * 4); + each_input_size_by_byte_.push_back(input_total_size); + } + else + assert(("kmodel input data type supports only uint8, float32", 0)); + } + each_input_size_by_byte_.push_back(input_total_size); // 最后一个保存总大小 +} + +void AIBase::set_input(const unsigned char *buf, size_t size) +{ + if (*each_input_size_by_byte_.rbegin() != size) + cout << "set_input:the actual input size{" + std::to_string(size) + "} is different from the model's required input size{" + std::to_string(*each_input_size_by_byte_.rbegin()) + "}" << endl; + assert((*each_input_size_by_byte_.rbegin() == size)); + + ScopedTiming st(model_name_ + " set_input", debug_mode_); + for (size_t i = 0; i < kmodel_interp_.inputs_size(); ++i) + { + auto desc = kmodel_interp_.input_desc(i); + auto shape = kmodel_interp_.input_shape(i); + auto tensor = host_runtime_tensor::create(desc.datatype, shape, hrt::pool_shared).expect("cannot create input tensor"); + auto mapped_buf = std::move(hrt::map(tensor, map_access_::map_write).unwrap()); // mapped_buf实际是有缓存数据的 + memcpy(reinterpret_cast(mapped_buf.buffer().data()), buf, each_input_size_by_byte_[i + 1] - each_input_size_by_byte_[i]); + auto ret = mapped_buf.unmap(); + ret = hrt::sync(tensor, sync_op_t::sync_write_back, true); + if (!ret.is_ok()) + { + std::cerr << "hrt::sync failed" << std::endl; + std::abort(); + } + kmodel_interp_.input_tensor(i, tensor).expect("cannot set input tensor"); + } +} + +runtime_tensor AIBase::get_input_tensor(size_t idx) +{ + return kmodel_interp_.input_tensor(idx).expect("cannot get input tensor"); +} + +void AIBase::set_input_tensor(size_t idx, runtime_tensor &tensor) +{ + ScopedTiming st(model_name_ + " set_input_tensor", debug_mode_); + kmodel_interp_.input_tensor(idx, tensor).expect("cannot set input tensor"); +} + +void AIBase::set_output_init() +{ + ScopedTiming st(model_name_ + " set_output_init", debug_mode_); + each_output_size_by_byte_.clear(); + int output_total_size = 0; + each_output_size_by_byte_.push_back(0); + for (size_t i = 0; i < kmodel_interp_.outputs_size(); i++) + { + auto desc = kmodel_interp_.output_desc(i); + auto shape = kmodel_interp_.output_shape(i); + vector out_shape; + int dsize = 1; + for (int j = 0; j < shape.size(); ++j) + { + out_shape.push_back(shape[j]); + dsize *= shape[j]; + if (debug_mode_ > 1) + cout << shape[j] << ","; + } + if (debug_mode_ > 1) + cout << endl; + output_shapes_.push_back(out_shape); + // DEFINE_TYPECODE(float32, f32, 0x0B) + if (desc.datatype == 0x0B) + { + output_total_size += (dsize * 4); + each_output_size_by_byte_.push_back(output_total_size); + } + else + assert(("kmodel output data type supports only float32", 0)); + auto tensor = host_runtime_tensor::create(desc.datatype, shape, hrt::pool_shared).expect("cannot create output tensor"); + kmodel_interp_.output_tensor(i, tensor).expect("cannot set output tensor"); + } +} + +void AIBase::set_output() +{ + ScopedTiming st(model_name_ + " set_output", debug_mode_); + for (size_t i = 0; i < kmodel_interp_.outputs_size(); i++) + { + auto desc = kmodel_interp_.output_desc(i); + auto shape = kmodel_interp_.output_shape(i); + auto tensor = host_runtime_tensor::create(desc.datatype, shape, hrt::pool_shared).expect("cannot create output tensor"); + kmodel_interp_.output_tensor(i, tensor).expect("cannot set output tensor"); + } +} + +void AIBase::run() +{ + ScopedTiming st(model_name_ + " run", debug_mode_); + kmodel_interp_.run().expect("error occurred in running model"); +} + +void AIBase::get_output() +{ + ScopedTiming st(model_name_ + " get_output", debug_mode_); + p_outputs_.clear(); + for (int i = 0; i < kmodel_interp_.outputs_size(); i++) + { + auto out = kmodel_interp_.output_tensor(i).expect("cannot get output tensor"); + // auto mapped_buf = std::move(hrt::map(out, map_access_::map_read).unwrap()); + // float *p_out = reinterpret_cast(mapped_buf.buffer().data()); + auto buf = out.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_read).unwrap().buffer(); + float *p_out = reinterpret_cast(buf.data()); + p_outputs_.push_back(p_out); + } +} diff --git a/src/reference/ai_poc/self_learning/ai_base.h b/src/reference/ai_poc/self_learning/ai_base.h new file mode 100755 index 000000000..9fd4470cc --- /dev/null +++ b/src/reference/ai_poc/self_learning/ai_base.h @@ -0,0 +1,120 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +// ai_base.h +#ifndef AI_BASE_H +#define AI_BASE_H + +#include +#include +#include + +#include +#include "scoped_timing.hpp" + +using std::string; +using std::vector; +using namespace nncase::runtime; + +/** + * @brief AI基类,封装nncase相关操作 + * 主要封装了nncase的加载、设置输入、运行、获取输出操作,后续开发demo只需要关注模型的前处理、后处理即可 + */ +class AIBase +{ +public: + /** + * @brief AI基类构造函数,加载kmodel,并初始化kmodel输入、输出 + * @param kmodel_file kmodel文件路径 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + AIBase(const char *kmodel_file,const string model_name, const int debug_mode = 1); + + /** + * @brief AI基类析构函数 + * @return None + */ + ~AIBase(); + + /** + * @brief 设置kmodel输入 + * @param buf 输入数据指针 + * @param size 输入数据大小 + * @return None + */ + void set_input(const unsigned char *buf, size_t size); + + /** + * @brief 根据索引获取kmodel输入tensor + * @param idx 输入数据指针 + * @return None + */ + runtime_tensor get_input_tensor(size_t idx); + + void set_input_tensor(size_t idx, runtime_tensor &tensor); + + /** + * @brief 初始化kmodel输出 + * @return None + */ + void set_output(); + + /** + * @brief 推理kmodel + * @return None + */ + void run(); + + /** + * @brief 获取kmodel输出,结果保存在对应的类属性中 + * @return None + */ + void get_output(); + +protected: + string model_name_; // 模型名字 + int debug_mode_; // 调试模型,0(不打印),1(打印时间),2(打印所有) + vector p_outputs_; // kmodel输出对应的指针列表 + vector> input_shapes_; //{{N,C,H,W},{N,C,H,W}...} + vector> output_shapes_; //{{N,C,H,W},{N,C,H,W}...}} 或 {{N,C},{N,C}...}}等 + vector each_input_size_by_byte_; //{0,layer1_length,layer1_length+layer2_length,...} + vector each_output_size_by_byte_; //{0,layer1_length,layer1_length+layer2_length,...} +private: + /** + * @brief 首次初始化kmodel输入,并获取输入shape + * @return None + */ + void set_input_init(); + + /** + * @brief 首次初始化kmodel输出,并获取输出shape + * @return None + */ + void set_output_init(); + + interpreter kmodel_interp_; // kmodel解释器,从kmodel文件构建,负责模型的加载、输入输出设置和推理 + vector kmodel_vec_; // 通过读取kmodel文件得到整个kmodel数据,用于传给kmodel解释器加载kmodel +}; +#endif \ No newline at end of file diff --git a/src/reference/ai_poc/self_learning/main.cc b/src/reference/ai_poc/self_learning/main.cc new file mode 100755 index 000000000..4a8d65a33 --- /dev/null +++ b/src/reference/ai_poc/self_learning/main.cc @@ -0,0 +1,294 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include "utils.h" +#include "vi_vo.h" +#include "self_learning.h" + +using std::cerr; +using std::cout; +using std::endl; + +std::atomic isp_stop(false); + +bool isFolderExist(string folderPath) { + struct stat info; + if (stat(folderPath.c_str(), &info) != 0) { + return false; + } + return (info.st_mode & S_IFDIR); +} + +void print_usage(const char *name) +{ + cout << "Usage: " << name << " " << endl + << "For example: " << endl + << " [for isp] ./self_learning.elf recognition.kmodel None 0 3 work" << endl + << "Options:" << endl + << " 1> kmodel kmodel文件路径 \n" + << " 2> input_mode 摄像头(None) \n" + << " 3> debug_mode 是否需要调试,0、1、2分别表示不调试、简单调试、详细调试\n" + << " 4> topK 返回topK结果\n" + << " 5> mode 操作模式,[work] or [label] \n" + << "\n" + << endl; +} + + +void video_proc(char *argv[]) +{ + vivcap_start(); + + k_video_frame_info vf_info; + void *pic_vaddr = NULL; //osd + + memset(&vf_info, 0, sizeof(vf_info)); + + vf_info.v_frame.width = osd_width; + vf_info.v_frame.height = osd_height; + vf_info.v_frame.stride[0] = osd_width; + vf_info.v_frame.pixel_format = PIXEL_FORMAT_ARGB_8888; + block = vo_insert_frame(&vf_info, &pic_vaddr); + + // alloc memory + size_t paddr = 0; + void *vaddr = nullptr; + size_t size = SENSOR_CHANNEL * SENSOR_HEIGHT * SENSOR_WIDTH; + int ret = kd_mpi_sys_mmz_alloc_cached(&paddr, &vaddr, "allocate", "anonymous", size); + if (ret) + { + std::cerr << "physical_memory_block::allocate failed: ret = " << ret << ", errno = " << strerror(errno) << std::endl; + std::abort(); + } + + bool sure_flag = true; + bool cate_flag = true; + + SL sl(argv[1],{SENSOR_CHANNEL, SENSOR_HEIGHT, SENSOR_WIDTH}, reinterpret_cast(vaddr), reinterpret_cast(paddr), atoi(argv[3])); + + while (!isp_stop) + { + + { + ScopedTiming st("read capture", atoi(argv[3])); + // VICAP_CHN_ID_1 out rgb888p + memset(&dump_info, 0 , sizeof(k_video_frame_info)); + ret = kd_mpi_vicap_dump_frame(vicap_dev, VICAP_CHN_ID_1, VICAP_DUMP_YUV, &dump_info, 1000); + if (ret) { + printf("sample_vicap...kd_mpi_vicap_dump_frame failed.\n"); + continue; + } + } + + + { + ScopedTiming st("isp copy", atoi(argv[3])); + // 从vivcap中读取一帧图像到dump_info + auto vbvaddr = kd_mpi_sys_mmap_cached(dump_info.v_frame.phys_addr[0], size); + memcpy(vaddr, (void *)vbvaddr, SENSOR_HEIGHT * SENSOR_WIDTH * 3); // 这里以后可以去掉,不用copy + kd_mpi_sys_munmap(vbvaddr, size); + } + + cv::Mat osd_frame(osd_height, osd_width, CV_8UC4, cv::Scalar(0, 0, 0, 0)); + + sl.pre_process(); + sl.inference(); + + vector results; + results.clear(); + int topK = atoi( argv[4] ); + std::string mode = argv[5]; + + if(strcmp(mode.c_str(),"work")==0) + { + sl.post_process(results,topK); + + std::string text; + cv::Point origin; + + int width = 100; + int i = 0; + + for (auto r : results) + { + ScopedTiming st("add texts", atoi(argv[3])); + text = r.category + " : " + std::to_string(round( r.score * 100) / 100).substr(0,4); + + int x1 = 1.0 / 2 * osd_width - 200 ; + int y1 = width; + + origin.x = x1; + origin.y = y1 + width * i; + i++; + + cv::putText(osd_frame, text, origin, cv::FONT_HERSHEY_COMPLEX, 2, cv::Scalar(255,255, 0, 0), 4, 8, 0); + + } + } + else if( strcmp(mode.c_str(),"label")==0 ) + { + + std:string sure ; + float* output; + while(sure_flag) + { + std::cout << "Are you sure? \n" << "If sure, please s[sure] " << std::endl; + getline(std::cin, sure); + + if( (strcmp(sure.c_str(),"s")==0) || (strcmp(sure.c_str(),"sure")==0)) + { + sure_flag = false; + cate_flag = true; + } + output = sl.get_vecOutput(); + + } + + std::string category ; + + while( cate_flag ) + { + std::cout << "Its label : " << std::endl; + getline(std::cin, category); + + std::cout << " category = " << category << std::endl; + sure_flag = true; + cate_flag = false; + + std::string cate_dir = "vectors/" + category; + if (!isFolderExist(cate_dir)) + { + std::cout << "Please create " << "'" << cate_dir << "'" << " folder on the 'small core window'" << std::endl; + continue; + } + + + int length = sl.get_len(); + vector vec(output, output + length); + + + ifstream f; + f.open( cate_dir + "/index.txt" ,std::ios::in); + std::string index; + f>>index; + std::cout<< "index = " << index < +#include +#include + +/** + * @brief 计时类 + * 统计在该类实例生命周期内的耗时 + */ +class ScopedTiming +{ +public: + /** + * @brief ScopedTiming构造函数,初始化计时对象名称并开始计时 + * @param info 计时对象名称 + * @param enable_profile 是否开始计时 + * @return None + */ + ScopedTiming(std::string info = "ScopedTiming", int enable_profile = 1) + : m_info(info), enable_profile(enable_profile) + { + if (enable_profile) + { + m_start = std::chrono::steady_clock::now(); + } + } + + /** + * @brief ScopedTiming析构,结束计时,并打印耗时 + * @return None + */ + ~ScopedTiming() + { + if (enable_profile) + { + m_stop = std::chrono::steady_clock::now(); + double elapsed_ms = std::chrono::duration(m_stop - m_start).count(); + std::cout << m_info << " took " << elapsed_ms << " ms" << std::endl; + } + } + +private: + int enable_profile; // 是否统计时间 + std::string m_info; // 计时对象名称 + std::chrono::steady_clock::time_point m_start; // 计时开始时间 + std::chrono::steady_clock::time_point m_stop; // 计时结束时间 +}; \ No newline at end of file diff --git a/src/reference/ai_poc/self_learning/self_learning.cc b/src/reference/ai_poc/self_learning/self_learning.cc new file mode 100755 index 000000000..d8e447679 --- /dev/null +++ b/src/reference/ai_poc/self_learning/self_learning.cc @@ -0,0 +1,246 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "self_learning.h" + +bool GreaterSort(Evec a, Evec b) // 降序 +{ + return (a.score > b.score); +} +bool LessSort(Evec a, Evec b) // 升序 +{ + return (a.score < b.score); +} + +float getMold(const vector& vec){ //求向量的模长 + int n = vec.size(); + float sum = 0.0; + for (int i = 0; i& lhs, const vector& rhs){ + int n = lhs.size(); + // assert(n == rhs.size()); + float tmp = 0.0; //内积 + for (int i = 0; i str.length()) + { + return false; + } + + return (str.rfind(suffix) == (str.length() - suffix.length())); +} + +void GetFileNames(string path,vector& filenames) +{ + DIR *pDir; + struct dirent* ptr; + if(!(pDir = opendir(path.c_str()))){ + cout <<"Folder doesn't Exist!"<< endl; + return; + } + while((ptr = readdir(pDir))!=0) { + if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0){ + filenames.push_back(path + "/" + ptr->d_name); + } + } + closedir(pDir); +} + +vector split(const string &str, const string &pattern) +{ + char * strc = new char[strlen(str.c_str())+1]; + strcpy(strc, str.c_str()); //string转换成C-string + vector res; + char* temp = strtok(strc, pattern.c_str()); + while(temp != NULL) + { + res.push_back(string(temp)); + temp = strtok(NULL, pattern.c_str()); + } + delete[] strc; + return res; +} + + +// for image +SL::SL(const char *kmodel_file, const int debug_mode): AIBase(kmodel_file,"self_learning", debug_mode) +{ + + model_name_ = "self_learning"; + + ai2d_out_tensor_ = get_input_tensor(0); + +} + + +// for video +SL::SL(const char *kmodel_file, FrameCHWSize isp_shape, uintptr_t vaddr, uintptr_t paddr, const int debug_mode):AIBase(kmodel_file,"self_learning", debug_mode) +{ + model_name_ = "self_learning"; + + vaddr_ = vaddr; + + isp_shape_ = isp_shape; + dims_t in_shape{1, isp_shape_.channel, isp_shape_.height, isp_shape_.width}; + int isp_size = isp_shape_.channel * isp_shape_.height * isp_shape_.width; + #if 0 + ai2d_in_tensor_ = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, { (gsl::byte *)vaddr, isp_size }, + true, hrt::pool_shared).expect("cannot create input tensor"); + #else + ai2d_in_tensor_ = hrt::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("create ai2d input tensor failed"); + #endif + + // ai2d_out_tensor + ai2d_out_tensor_ = get_input_tensor(0); + // fixed padding resize param + Utils::resize(ai2d_builder_, ai2d_in_tensor_, ai2d_out_tensor_); +} + + +SL::~SL() +{ + +} + +// ai2d for image +void SL::pre_process(cv::Mat ori_img) +{ + ScopedTiming st(model_name_ + " pre_process image", debug_mode_); + + cv::cvtColor( ori_img, ori_img,cv::COLOR_BGR2RGB); + + std::vector chw_vec; + Utils::hwc_to_chw(ori_img, chw_vec); + Utils::resize({ori_img.channels(), ori_img.rows, ori_img.cols}, chw_vec, ai2d_out_tensor_); +} + +// ai2d for video +void SL::pre_process() +{ + ScopedTiming st(model_name_ + " pre_process video", debug_mode_); + #if 0 + ai2d_builder_->invoke().expect("error occurred in ai2d running"); + #else + size_t isp_size = isp_shape_.channel * isp_shape_.height * isp_shape_.width; + auto buf = ai2d_in_tensor_.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(buf.data()), (void *)vaddr_, isp_size); + hrt::sync(ai2d_in_tensor_, sync_op_t::sync_write_back, true).expect("sync write_back failed"); + ai2d_builder_->invoke(ai2d_in_tensor_,ai2d_out_tensor_).expect("error occurred in ai2d running"); + // run ai2d + #endif +} + +void SL::inference() +{ + ScopedTiming st(model_name_ + " inference", debug_mode_); + this->run(); + this->get_output(); +} + +void SL::post_process( vector& results,int topK) +{ + + ScopedTiming st(model_name_ + " post_process", debug_mode_); + float *output = p_outputs_[0]; + + int length = output_shapes_[0][1]; + vector output_vec(output, output + length); + + // Utils::dump_binary_file("onboard.bin", (char *)output, length * sizeof(float)); + + // float output_mold = getMold(output_vec); + + const char* filePath = "vectors"; + + vector dirs; + GetFileNames(filePath,dirs); + + vector files; + for( auto dir:dirs ) + { + GetFileNames(dir,files); + } + + for(auto file:files) + { + if( endsWith( file, ".bin") ) + { + vector vec = Utils::read_binary_file< float >(file.c_str()); + + float score = getSimilarity(output_vec, vec); + + if( results.size() < topK ) + { + Evec evec; + vector res = split( file, "/" ); + evec.category = res[1]; + evec.score = score; + evec.bin_file = file; + results.push_back( evec ); + std::sort(results.begin(), results.end(), GreaterSort); + + } + else + { + if( score <= results[topK-1].score ) + { + continue; + } + else + { + Evec evec; + vector res = split( file, "/" ); + evec.category = res[1]; + evec.score = score; + evec.bin_file = file; + results.push_back( evec ); + std::sort(results.begin(), results.end(), GreaterSort); + + results.pop_back(); + } + } + } + } + +} + +float* SL::get_vecOutput( ) +{ + return p_outputs_[0] ; +} + +int SL::get_len() +{ + int length = output_shapes_[0][1]; + return length; +} \ No newline at end of file diff --git a/src/reference/ai_poc/self_learning/self_learning.h b/src/reference/ai_poc/self_learning/self_learning.h new file mode 100755 index 000000000..c743cb3b0 --- /dev/null +++ b/src/reference/ai_poc/self_learning/self_learning.h @@ -0,0 +1,117 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _PPHUMANSL +#define _PPHUMANSL + +#include +#include "utils.h" +#include "ai_base.h" + +#include +#include +#include +#include +#include + +typedef struct Evec +{ + string category; + float score; + string bin_file; + +} Evec; + +/** + * @brief 人像分割任务 + * 主要封装了对于每一帧图片,从预处理、运行到后处理给出结果的过程 + */ +class SL: public AIBase +{ + public: + + /** + * @brief SL 构造函数,加载kmodel,并初始化kmodel输入、输出、类阈值和NMS阈值 + * @param kmodel_file kmodel文件路径 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + SL(const char *kmodel_file, const int debug_mode); + + /** + * @brief SL 构造函数,加载kmodel,并初始化kmodel输入、输出、类阈值和NMS阈值 + * @param kmodel_file kmodel文件路径 + * @param isp_shape isp输入大小(chw) + * @param vaddr isp对应虚拟地址 + * @param paddr isp对应物理地址 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + SL(const char *kmodel_file, FrameCHWSize isp_shape, uintptr_t vaddr, uintptr_t paddr, const int debug_mode); + + /** + * @brief SL 析构函数 + * @return None + */ + ~SL(); + + /** + * @brief 图片预处理(ai2d for image) + * @param ori_img 原始图片 + * @return None + */ + void pre_process(cv::Mat ori_img); + + /** + * @brief 视频流预处理(ai2d for video) + * @return None + */ + void pre_process(); + + /** + * @brief kmodel推理 + * @return None + */ + void inference(); + + /** + * @brief postprocess 函数 + * @return mask + */ + void post_process( vector& results,int topK); + + float* get_vecOutput(); + + int get_len(); + + private: + + std::unique_ptr ai2d_builder_; // ai2d构建器 + runtime_tensor ai2d_in_tensor_; // ai2d输入tensor + runtime_tensor ai2d_out_tensor_; // ai2d输出tensor + uintptr_t vaddr_; // isp的虚拟地址 + FrameCHWSize isp_shape_; // isp对应的地址大小 +}; +#endif diff --git a/src/reference/ai_poc/self_learning/utils.cc b/src/reference/ai_poc/self_learning/utils.cc new file mode 100755 index 000000000..04189afcd --- /dev/null +++ b/src/reference/ai_poc/self_learning/utils.cc @@ -0,0 +1,403 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +// utils.cpp +#include +#include "utils.h" + +using std::ofstream; +using std::vector; +auto cache = cv::Mat::zeros(1, 1, CV_32FC1); +void Utils::dump_binary_file(const char *file_name, char *data, const size_t size) +{ + // eg:Utils::dump_binary_file(out_name.c_str(),reinterpret_cast(p_outputs_[i]),each_output_size_by_byte_[i+1]-each_output_size_by_byte_[i]); + std::ofstream outf; + outf.open(file_name, std::ofstream::binary); + outf.write(data, size); + outf.close(); +} + +void Utils::dump_gray_image(const char *file_name, const FrameSize &frame_size, unsigned char *data) +{ + cv::Mat gray_image = cv::Mat(frame_size.height, frame_size.width, CV_8UC1, data); + cv::imwrite(file_name, gray_image); +} + +void Utils::dump_color_image(const char *file_name, const FrameSize &frame_size, unsigned char *data) +{ + cv::Mat image_r = cv::Mat(frame_size.height, frame_size.width, CV_8UC1, data); + cv::Mat image_g = cv::Mat(frame_size.height, frame_size.width, CV_8UC1, data+frame_size.height*frame_size.width); + cv::Mat image_b = cv::Mat(frame_size.height, frame_size.width, CV_8UC1, data+2*frame_size.height*frame_size.width); + + std::vector color_vec(3); + color_vec.clear(); + color_vec.push_back(image_b); + color_vec.push_back(image_g); + color_vec.push_back(image_r); + + cv::Mat color_img; + cv::merge(color_vec, color_img); + cv::imwrite(file_name, color_img); +} + +cv::Mat Utils::padding_resize(const cv::Mat img, const FrameSize &frame_size, const cv::Scalar &padding) +{ + // width:dst_width + int ori_w = img.cols; + int ori_h = img.rows; + float ratiow = (float)frame_size.width / ori_w; + float ratioh = (float)frame_size.height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(frame_size.width - new_w) / 2; + float dh = (float)(frame_size.height - new_h) / 2; + int top = (int)(roundf(0 - 0.1)); + int bottom = (int)(roundf(dh * 2 + 0.1)); + int left = (int)(roundf(0 - 0.1)); + int right = (int)(roundf(dw * 2 - 0.1)); + cv::Mat cropped_img; + { + if ((new_w != frame_size.width) || (new_h != frame_size.height)) + { + cv::resize(img, cropped_img, cv::Size(new_w, new_h), cv::INTER_AREA); + } + } + { + // 104, 117, 123,BGR + cv::copyMakeBorder(cropped_img, cropped_img, top, bottom, left, right, cv::BORDER_CONSTANT, padding); + } + return cropped_img; +} + +cv::Mat Utils::resize(const cv::Mat img, const FrameSize &frame_size) +{ + cv::Mat cropped_img; + cv::resize(img, cropped_img, cv::Size(frame_size.width, frame_size.height), cv::INTER_LINEAR); + return cropped_img; +} + +cv::Mat Utils::bgr_to_rgb(cv::Mat ori_img) +{ + cv::Mat rgb_img; + cv::cvtColor(ori_img, rgb_img, cv::COLOR_BGR2RGB); + return rgb_img; +} + +void Utils::hwc_to_chw(cv::Mat &ori_img, std::vector &chw_vec) +{ + // for rgb format + std::vector rgbChannels(3); + cv::split(ori_img, rgbChannels); + for (auto i = 0; i < rgbChannels.size(); i++) + { + std::vector data = std::vector(rgbChannels[i].reshape(1, 1)); + chw_vec.insert(chw_vec.end(), data.begin(), data.end()); + } +} + +void Utils::bgr2rgb_and_hwc2chw(cv::Mat &ori_img, std::vector &chw_vec) +{ + // for bgr format + std::vector bgrChannels(3); + cv::split(ori_img, bgrChannels); + for (auto i = 2; i > -1; i--) + { + std::vector data = std::vector(bgrChannels[i].reshape(1, 1)); + chw_vec.insert(chw_vec.end(), data.begin(), data.end()); + } +} + +void Utils::resize(FrameCHWSize ori_shape, std::vector &chw_vec, runtime_tensor &ai2d_out_tensor) +{ + // build ai2d_in_tensor + dims_t in_shape{1, ori_shape.channel, ori_shape.height, ori_shape.width}; + runtime_tensor ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), chw_vec.data(), chw_vec.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + // ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, typecode_t::dt_uint8, typecode_t::dt_uint8}; + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param { false, 30, 20, 400, 600 }; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, ai2d_pad_mode::constant, {114, 114, 114}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::resize(std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor) +{ + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param { false, 30, 20, 400, 600 }; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, ai2d_pad_mode::constant, {114, 114, 114}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::crop_resize(FrameCHWSize ori_shape, std::vector &chw_vec, Bbox &crop_info, runtime_tensor &ai2d_out_tensor) +{ + // build ai2d_in_tensor + dims_t in_shape{1, ori_shape.channel, ori_shape.height, ori_shape.width}; + runtime_tensor ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), chw_vec.data(), chw_vec.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{true, crop_info.x, crop_info.y, crop_info.w, crop_info.h}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, ai2d_pad_mode::constant, {114, 114, 114}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::crop_resize(Bbox &crop_info, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor) +{ + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{true, crop_info.x, crop_info.y, crop_info.w, crop_info.h}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, ai2d_pad_mode::constant, {114, 114, 114}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::padding_resize(FrameCHWSize ori_shape, std::vector &chw_vec, FrameSize resize_shape, runtime_tensor &ai2d_out_tensor, cv::Scalar padding) +{ + int ori_w = ori_shape.width; + int ori_h = ori_shape.height; + int width = resize_shape.width; + int height = resize_shape.height; + float ratiow = (float)width / ori_w; + float ratioh = (float)height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(width - new_w) / 2; + float dh = (float)(height - new_h) / 2; + int top = (int)(roundf(dh - 0.1)); + int bottom = (int)(roundf(dh + 0.1)); + int left = (int)(roundf(dw - 0.1)); + int right = (int)(roundf(dw - 0.1)); + + // create input + dims_t in_shape{1, ori_shape.channel, ori_h, ori_w}; + auto ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), chw_vec.data(), chw_vec.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{true, {{0, 0}, {0, 0}, {top, bottom}, {left, right}}, ai2d_pad_mode::constant, {padding[0], padding[1], padding[2]}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::padding_resize_one_side(FrameCHWSize ori_shape, std::vector &chw_vec, FrameSize resize_shape, runtime_tensor &ai2d_out_tensor, cv::Scalar padding) +{ + int ori_w = ori_shape.width; + int ori_h = ori_shape.height; + int width = resize_shape.width; + int height = resize_shape.height; + float ratiow = (float)width / ori_w; + float ratioh = (float)height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(width - new_w) / 2; + float dh = (float)(height - new_h) / 2; + int top = (int)(roundf(0)); + int bottom = (int)(roundf(dh * 2 + 0.1)); + int left = (int)(roundf(0)); + int right = (int)(roundf(dw * 2 - 0.1)); + + // create input + dims_t in_shape{1, ori_shape.channel, ori_h, ori_w}; + auto ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), chw_vec.data(), chw_vec.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{true, {{0, 0}, {0, 0}, {top, bottom}, {left, right}}, ai2d_pad_mode::constant, {padding[0], padding[1], padding[2]}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::padding_resize(FrameCHWSize ori_shape, FrameSize resize_shape, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor, const cv::Scalar padding) +{ + int ori_w = ori_shape.width; + int ori_h = ori_shape.height; + int width = resize_shape.width; + int height = resize_shape.height; + float ratiow = (float)width / ori_w; + float ratioh = (float)height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(width - new_w) / 2; + float dh = (float)(height - new_h) / 2; + int top = (int)(roundf(dh - 0.1)); + int bottom = (int)(roundf(dh + 0.1)); + int left = (int)(roundf(dw - 0.1)); + int right = (int)(roundf(dw - 0.1)); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{true, {{0, 0}, {0, 0}, {top, bottom}, {left, right}}, ai2d_pad_mode::constant, {padding[0], padding[1], padding[2]}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::padding_resize_one_side(FrameCHWSize ori_shape, FrameSize resize_shape, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor, const cv::Scalar padding) +{ + int ori_w = ori_shape.width; + int ori_h = ori_shape.height; + int width = resize_shape.width; + int height = resize_shape.height; + float ratiow = (float)width / ori_w; + float ratioh = (float)height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(width - new_w) / 2; + float dh = (float)(height - new_h) / 2; + int top = (int)(roundf(0)); + int bottom = (int)(roundf(dh * 2 + 0.1)); + int left = (int)(roundf(0)); + int right = (int)(roundf(dw * 2 - 0.1)); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{true, {{0, 0}, {0, 0}, {top, bottom}, {left, right}}, ai2d_pad_mode::constant, {padding[0], padding[1], padding[2]}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::affine(FrameCHWSize ori_shape, std::vector &ori_data, float *affine_matrix, runtime_tensor &ai2d_out_tensor) +{ + runtime_tensor ai2d_in_tensor; + // init ai2d in/out + dims_t in_shape{1, ori_shape.channel, ori_shape.height, ori_shape.width}; + ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + + // ai2d input + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), ori_data.data(), ori_data.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {10, 0}}, ai2d_pad_mode::constant, {255, 10, 5}}; + ai2d_resize_param_t resize_param{false, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{true, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {affine_matrix[0], affine_matrix[1], affine_matrix[2], affine_matrix[3], affine_matrix[4], affine_matrix[5]}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +// for video(只算一次即可) +void Utils::affine(float *affine_matrix, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor) +{ + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {10, 0}}, ai2d_pad_mode::constant, {255, 10, 5}}; + ai2d_resize_param_t resize_param{false, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{true, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {affine_matrix[0], affine_matrix[1], affine_matrix[2], affine_matrix[3], affine_matrix[4], affine_matrix[5]}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + diff --git a/src/reference/ai_poc/self_learning/utils.h b/src/reference/ai_poc/self_learning/utils.h new file mode 100755 index 000000000..9483313c0 --- /dev/null +++ b/src/reference/ai_poc/self_learning/utils.h @@ -0,0 +1,322 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +// utils.h +#ifndef UTILS_H +#define UTILS_H + +#include +#include +#include +#include +#include +#include +#include + +using namespace nncase; +using namespace nncase::runtime; +using namespace nncase::runtime::k230; +using namespace nncase::F::k230; + +using cv::Mat; +using std::cout; +using std::endl; +using std::ifstream; +using std::vector; + +/** + * @brief 行人检测框信息 + */ +typedef struct BoxInfo +{ + float x1; // 行人检测框左上顶点x坐标 + float y1; // 行人检测框左上顶点y坐标 + float x2; // 行人检测框右下顶点x坐标 + float y2; // 行人检测框右下顶点y坐标 + float score; // 行人检测框的得分 + int label; // 行人检测框的标签 +} BoxInfo; + +/** + * @brief 人脸检测框 + */ +typedef struct Bbox +{ + float x; // 人脸检测框的左顶点x坐标 + float y; // 人脸检测框的左顶点x坐标 + float w; + float h; +} Bbox; + +/** + * @brief 人脸五官点 + */ +typedef struct SparseLandmarks +{ + float points[10]; // 人脸五官点,依次是图片的左眼(x,y)、右眼(x,y),鼻子(x,y),左嘴角(x,y),右嘴角 +} SparseLandmarks; + +/** + * @brief 单张/帧图片大小 + */ +typedef struct FrameSize +{ + size_t width; // 宽 + size_t height; // 高 +} FrameSize; + +/** + * @brief 单张/帧图片大小 + */ +typedef struct FrameCHWSize +{ + size_t channel; // 通道 + size_t height; // 高 + size_t width; // 宽 +} FrameCHWSize; + +/** + * @brief AI Demo工具类 + * 封装了AI Demo常用的函数,包括二进制文件读取、文件保存、图片预处理等操作 + */ +class Utils +{ +public: + /** + * @brief 读取2进制文件 + * @param file_name 文件路径 + * @return 文件对应类型的数据 + */ + template + static vector read_binary_file(const char *file_name) + { + ifstream ifs(file_name, std::ios::binary); + ifs.seekg(0, ifs.end); + size_t len = ifs.tellg(); + vector vec(len / sizeof(T), 0); + ifs.seekg(0, ifs.beg); + ifs.read(reinterpret_cast(vec.data()), len); + ifs.close(); + return vec; + } + + /** + * @brief 打印数据 + * @param data 需打印数据对应指针 + * @param size 需打印数据大小 + * @return None + */ + template + static void dump(const T *data, size_t size) + { + for (size_t i = 0; i < size; i++) + { + cout << data[i] << " "; + } + cout << endl; + } + + // 静态成员函数不依赖于类的实例,可以直接通过类名调用 + /** + * @brief 将数据以2进制方式保存为文件 + * @param file_name 保存文件路径+文件名 + * @param data 需要保存的数据 + * @param size 需要保存的长度 + * @return None + */ + static void dump_binary_file(const char *file_name, char *data, const size_t size); + + /** + * @brief 将数据保存为灰度图片 + * @param file_name 保存图片路径+文件名 + * @param frame_size 保存图片的宽、高 + * @param data 需要保存的数据 + * @return None + */ + static void dump_gray_image(const char *file_name, const FrameSize &frame_size, unsigned char *data); + + /** + * @brief 将数据保存为彩色图片 + * @param file_name 保存图片路径+文件名 + * @param frame_size 保存图片的宽、高 + * @param data 需要保存的数据 + * @return None + */ + static void dump_color_image(const char *file_name, const FrameSize &frame_size, unsigned char *data); + + + /*************************for img process********************/ + /** + * @brief 对图片进行先padding后resize的处理 + * @param ori_img 原始图片 + * @param frame_size 需要resize图像的宽高 + * @param padding 需要padding的像素,默认是cv::Scalar(114, 114, 114),BGR + * @return 处理后图像 + */ + static cv::Mat padding_resize(const cv::Mat img, const FrameSize &frame_size, const cv::Scalar &padding = cv::Scalar(114, 114, 114)); + + /** + * @brief 对图片resize + * @param ori_img 原始图片 + * @param frame_size 需要resize图像的宽高 + * @param padding 需要padding的像素,默认是cv::Scalar(114, 114, 114),BGR + * @return 处理后图像 + */ + static cv::Mat resize(const cv::Mat ori_img, const FrameSize &frame_size); + + /** + * @brief 将图片从bgr转为rgb + * @param ori_img 原始图片 + * @return 处理后图像 + */ + static cv::Mat bgr_to_rgb(cv::Mat ori_img); + + /** + * @brief 将RGB或RGB图片从hwc转为chw + * @param ori_img 原始图片 + * @param chw_vec 转为chw后的数据 + * @return None + */ + static void hwc_to_chw(cv::Mat &ori_img, std::vector &chw_vec); // for rgb data + + /** + * @brief 将BGR图片从hwc转为chw + * @param ori_img 原始图片 + * @param chw_vec 转为chw后的数据 + * @return None + */ + static void bgr2rgb_and_hwc2chw(cv::Mat &ori_img, std::vector &chw_vec); + + /*************************for ai2d ori_img process********************/ + // resize + /** + * @brief resize函数,对chw数据进行resize + * @param ori_shape 原始数据chw + * @param chw_vec 原始数据 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + static void resize(FrameCHWSize ori_shape, std::vector &chw_vec, runtime_tensor &ai2d_out_tensor); + + /** + * @brief resize函数 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + static void resize(std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor); + + // crop resize + /** + * @brief resize函数,对chw数据进行crop & resize + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + static void crop_resize(FrameCHWSize ori_shape, std::vector &chw_vec, Bbox &crop_info, runtime_tensor &ai2d_out_tensor); + + /** + * @brief crop_resize函数,对chw数据进行crop & resize + * @param crop_info 需要crop的位置,x,y,w,h + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + static void crop_resize(Bbox &crop_info, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor); + + // padding resize + /** + * @brief padding_resize函数(上下左右padding),对chw数据进行padding & resize + * @param ori_shape 原始数据chw + * @param chw_vec 原始数据 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + static void padding_resize(FrameCHWSize ori_shape, std::vector &chw_vec, FrameSize resize_shape, runtime_tensor &ai2d_out_tensor, cv::Scalar padding); + + /** + * @brief padding_resize函数(右或下padding),对chw数据进行padding & resize + * @param ori_shape 原始数据chw + * @param chw_vec 原始数据 + * @param resize_shape resize之后的大小 + * @param ai2d_out_tensor ai2d输出 + * @param padding 填充值,用于resize时的等比例变换 + * @return None + */ + static void padding_resize_one_side(FrameCHWSize ori_shape, std::vector &chw_vec, FrameSize resize_shape, runtime_tensor &ai2d_out_tensor, cv::Scalar padding); + + /** + * @brief padding_resize函数(上下左右padding),对chw数据进行padding & resize + * @param ori_shape 原始数据chw + * @param resize_shape resize之后的大小 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @param padding 填充值,用于resize时的等比例变换 + * @return None + */ + static void padding_resize(FrameCHWSize ori_shape, FrameSize resize_shape, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor, cv::Scalar padding); + + /** + * @brief padding_resize函数(右或下padding),对chw数据进行padding & resize + * @param ori_shape 原始数据chw + * @param resize_shape resize之后的大小 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @param padding 填充值,用于resize时的等比例变换 + * @return None + */ + static void padding_resize_one_side(FrameCHWSize ori_shape, FrameSize resize_shape, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor, const cv::Scalar padding); + + // affine + /** + * @brief 仿射变换函数,对chw数据进行仿射变换(for imgae) + * @param ori_shape 原始数据chw大小 + * @param ori_data 原始数据 + * @param affine_matrix 仿射变换矩阵 + * @param ai2d_out_tensor 仿射变换后的数据 + * @return None + */ + static void affine(FrameCHWSize ori_shape, std::vector &ori_data, float *affine_matrix, runtime_tensor &ai2d_out_tensor); + + /** + * @brief 仿射变换函数,对chw数据进行仿射变换(for video) + * @param affine_matrix 仿射变换矩阵 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + static void affine(float *affine_matrix, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor); + + +}; + +#endif diff --git a/src/reference/ai_poc/self_learning/vi_vo.h b/src/reference/ai_poc/self_learning/vi_vo.h new file mode 100755 index 000000000..76be47ac2 --- /dev/null +++ b/src/reference/ai_poc/self_learning/vi_vo.h @@ -0,0 +1,627 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include "mpi_sys_api.h" + +/* vicap */ +#include +#include +#include +#include +#include + +#include "k_module.h" +#include "k_type.h" +#include "k_vb_comm.h" +#include "k_video_comm.h" +#include "k_sys_comm.h" +#include "mpi_vb_api.h" +#include "mpi_vicap_api.h" +#include "mpi_isp_api.h" +#include "mpi_sys_api.h" +#include "k_vo_comm.h" +#include "mpi_vo_api.h" + +#include "vo_test_case.h" + +#include "k_connector_comm.h" +#include "mpi_connector_api.h" +#include "k_autoconf_comm.h" + +#if defined(CONFIG_BOARD_K230_CANMV) +#define SENSOR_CHANNEL (3) // isp通道数 +#define SENSOR_HEIGHT (720) // isp高度,ai输入,竖屏 +#define SENSOR_WIDTH (1280) // isp宽度,ai输入,竖屏 +#define ISP_CHN0_WIDTH (1920)//(1920) +#define ISP_CHN0_HEIGHT (1080)//(1080) +#define vicap_install_osd (1) +#define osd_id K_VO_OSD3 +#define osd_width (1920) +#define osd_height (1080) +#else +#define SENSOR_CHANNEL (3) // isp通道数 +#define SENSOR_HEIGHT (1280) // isp高度,ai输入,竖屏 +#define SENSOR_WIDTH (720) // isp宽度,ai输入,竖屏 +#define ISP_CHN0_WIDTH (1088)//(1920) +#define ISP_CHN0_HEIGHT (1920)//(1080) +#define vicap_install_osd (1) +#define osd_id K_VO_OSD3 +#define osd_width (1080) +#define osd_height (1920) +#endif + + +k_vb_config config; +k_vicap_dev vicap_dev; +k_vicap_chn vicap_chn; +k_vicap_dev_attr dev_attr; +k_vicap_chn_attr chn_attr; +k_vicap_sensor_info sensor_info; +k_vicap_sensor_type sensor_type; +k_mpp_chn vicap_mpp_chn; +k_mpp_chn vo_mpp_chn; + +k_video_frame_info dump_info; + +k_vo_draw_frame vo_frame = (k_vo_draw_frame) { + 1, + 16, + 16, + 128, + 128, + 1 +}; + +static k_vb_blk_handle block; +k_u32 g_pool_id; + +int vo_creat_layer_test(k_vo_layer chn_id, layer_info *info) +{ + k_vo_video_layer_attr attr; + + // check layer + if ((chn_id >= K_MAX_VO_LAYER_NUM) || ((info->func & K_VO_SCALER_ENABLE) && (chn_id != K_VO_LAYER0)) + || ((info->func != 0) && (chn_id == K_VO_LAYER2))) + { + printf("input layer num failed \n"); + return -1 ; + } + + // check scaler + + // set offset + attr.display_rect = info->offset; + // set act + attr.img_size = info->act_size; + // sget size + info->size = info->act_size.height * info->act_size.width * 3 / 2; + //set pixel format + attr.pixel_format = info->format; + if (info->format != PIXEL_FORMAT_YVU_PLANAR_420) + { + printf("input pix format failed \n"); + return -1; + } + // set stride + attr.stride = (info->act_size.width / 8 - 1) + ((info->act_size.height - 1) << 16); + // set function + attr.func = info->func; + // set scaler attr + attr.scaler_attr = info->attr; + + // set video layer atrr + kd_mpi_vo_set_video_layer_attr(chn_id, &attr); + + // enable layer + kd_mpi_vo_enable_video_layer(chn_id); + + return 0; +} + +k_vb_blk_handle vo_insert_frame(k_video_frame_info *vf_info, void **pic_vaddr) +{ + k_u64 phys_addr = 0; + k_u32 *virt_addr; + k_vb_blk_handle handle; + k_s32 size; + + if (vf_info == NULL) + return K_FALSE; + + if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_ABGR_8888 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_ARGB_8888) + size = vf_info->v_frame.height * vf_info->v_frame.width * 4; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_RGB_565 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_BGR_565) + size = vf_info->v_frame.height * vf_info->v_frame.width * 2; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_ABGR_4444 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_ARGB_4444) + size = vf_info->v_frame.height * vf_info->v_frame.width * 2; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_RGB_888 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_BGR_888) + size = vf_info->v_frame.height * vf_info->v_frame.width * 3; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_ARGB_1555 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_ABGR_1555) + size = vf_info->v_frame.height * vf_info->v_frame.width * 2; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_YVU_PLANAR_420) + size = vf_info->v_frame.height * vf_info->v_frame.width * 3 / 2; + + size = size + 4096; // 强制4K ,后边得删了 + + printf("vb block size is %x \n", size); + + handle = kd_mpi_vb_get_block(g_pool_id, size, NULL); + if (handle == VB_INVALID_HANDLE) + { + printf("%s get vb block error\n", __func__); + return K_FAILED; + } + + phys_addr = kd_mpi_vb_handle_to_phyaddr(handle); + if (phys_addr == 0) + { + printf("%s get phys addr error\n", __func__); + return K_FAILED; + } + + virt_addr = (k_u32 *)kd_mpi_sys_mmap(phys_addr, size); + // virt_addr = (k_u32 *)kd_mpi_sys_mmap_cached(phys_addr, size); + + if (virt_addr == NULL) + { + printf("%s mmap error\n", __func__); + return K_FAILED; + } + + vf_info->mod_id = K_ID_VO; + vf_info->pool_id = g_pool_id; + vf_info->v_frame.phys_addr[0] = phys_addr; + if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_YVU_PLANAR_420) + vf_info->v_frame.phys_addr[1] = phys_addr + (vf_info->v_frame.height * vf_info->v_frame.stride[0]); + *pic_vaddr = virt_addr; + + printf("phys_addr is %lx g_pool_id is %d \n", phys_addr, g_pool_id); + + return handle; +} + +k_u32 vo_creat_osd_test(k_vo_osd osd, osd_info *info) +{ + k_vo_video_osd_attr attr; + + // set attr + attr.global_alptha = info->global_alptha; + + if (info->format == PIXEL_FORMAT_ABGR_8888 || info->format == PIXEL_FORMAT_ARGB_8888) + { + info->size = info->act_size.width * info->act_size.height * 4; + info->stride = info->act_size.width * 4 / 8; + } + else if (info->format == PIXEL_FORMAT_RGB_565 || info->format == PIXEL_FORMAT_BGR_565) + { + info->size = info->act_size.width * info->act_size.height * 2; + info->stride = info->act_size.width * 2 / 8; + } + else if (info->format == PIXEL_FORMAT_RGB_888 || info->format == PIXEL_FORMAT_BGR_888) + { + info->size = info->act_size.width * info->act_size.height * 3; + info->stride = info->act_size.width * 3 / 8; + } + else if(info->format == PIXEL_FORMAT_ARGB_4444 || info->format == PIXEL_FORMAT_ABGR_4444) + { + info->size = info->act_size.width * info->act_size.height * 2; + info->stride = info->act_size.width * 2 / 8; + } + else if(info->format == PIXEL_FORMAT_ARGB_1555 || info->format == PIXEL_FORMAT_ABGR_1555) + { + info->size = info->act_size.width * info->act_size.height * 2; + info->stride = info->act_size.width * 2 / 8; + } + else + { + printf("set osd pixel format failed \n"); + } + + attr.stride = info->stride; + attr.pixel_format = info->format; + attr.display_rect = info->offset; + attr.img_size = info->act_size; + kd_mpi_vo_set_video_osd_attr(osd, &attr); + + kd_mpi_vo_osd_enable(osd); + + return 0; +} + +void sample_vicap_install_osd(void) +{ + osd_info osd; + + osd.act_size.width = osd_width ; + osd.act_size.height = osd_height; + osd.offset.x = 0; + osd.offset.y = 0; + osd.global_alptha = 0xff; + // osd.global_alptha = 0x32; + osd.format = PIXEL_FORMAT_ARGB_8888;//PIXEL_FORMAT_ARGB_4444; //PIXEL_FORMAT_ARGB_1555;//PIXEL_FORMAT_ARGB_8888; + + vo_creat_osd_test(osd_id, &osd); +} + +void vo_osd_release_block(void) +{ + if(vicap_install_osd == 1) + { + kd_mpi_vo_osd_disable(osd_id); + kd_mpi_vb_release_block(block); + } + +} + +static k_s32 sample_connector_init(void) +{ + k_u32 ret = 0; + k_s32 connector_fd; +#if defined(CONFIG_BOARD_K230_CANMV) + k_connector_type connector_type = LT9611_MIPI_4LAN_1920X1080_30FPS;// HX8377_V2_MIPI_4LAN_1080X1920_30FPS; +#else + k_connector_type connector_type = HX8377_V2_MIPI_4LAN_1080X1920_30FPS; +#endif + k_connector_info connector_info; + + memset(&connector_info, 0, sizeof(k_connector_info)); + + //connector get sensor info + ret = kd_mpi_get_connector_info(connector_type, &connector_info); + if (ret) { + printf("sample_vicap, the sensor type not supported!\n"); + return ret; + } + + connector_fd = kd_mpi_connector_open(connector_info.connector_name); + if (connector_fd < 0) { + printf("%s, connector open failed.\n", __func__); + return K_ERR_VO_NOTREADY; + } + + // set connect power + kd_mpi_connector_power_set(connector_fd, K_TRUE); + // connector init + kd_mpi_connector_init(connector_fd, connector_info); + + return 0; +} + +static k_s32 vo_layer_vdss_bind_vo_config(void) +{ + layer_info info; + + k_vo_layer chn_id = K_VO_LAYER1; + + memset(&info, 0, sizeof(info)); + + sample_connector_init(); + + // config lyaer + info.act_size.width = ISP_CHN0_WIDTH;//ISP_CHN0_HEIGHT;//1080;//640;//1080; + info.act_size.height = ISP_CHN0_HEIGHT;//ISP_CHN0_WIDTH;//1920;//480;//1920; + info.format = PIXEL_FORMAT_YVU_PLANAR_420; + info.func = 0;//K_ROTATION_180;////K_ROTATION_90; + info.global_alptha = 0xff; + info.offset.x = 0;//(1080-w)/2, + info.offset.y = 0;//(1920-h)/2; + vo_creat_layer_test(chn_id, &info); + + if(vicap_install_osd == 1) + sample_vicap_install_osd(); + + //exit ; + return 0; +} + +static void sample_vicap_bind_vo(k_mpp_chn vicap_mpp_chn, k_mpp_chn vo_mpp_chn) +{ + k_s32 ret; + + ret = kd_mpi_sys_bind(&vicap_mpp_chn, &vo_mpp_chn); + if (ret) { + printf("kd_mpi_sys_unbind failed:0x%x\n", ret); + } + + return; +} + +static void sample_vicap_unbind_vo(k_mpp_chn vicap_mpp_chn, k_mpp_chn vo_mpp_chn) +{ + k_s32 ret; + + ret = kd_mpi_sys_unbind(&vicap_mpp_chn, &vo_mpp_chn); + if (ret) { + printf("kd_mpi_sys_unbind failed:0x%x\n", ret); + } + + return; +} + +int vivcap_start() +{ + k_s32 ret = 0; + + k_u32 pool_id; + k_vb_pool_config pool_config; + + printf("sample_vicap ...\n"); + +#if defined(CONFIG_BOARD_K230_CANMV) + sensor_type = OV_OV5647_MIPI_CSI0_1920X1080_30FPS_10BIT_LINEAR; + kd_mpi_vicap_set_mclk(VICAP_MCLK0, VICAP_PLL0_CLK_DIV4, 16, 1); +#else + sensor_type = IMX335_MIPI_2LANE_RAW12_2592X1944_30FPS_LINEAR; +#endif + vicap_dev = VICAP_DEV_ID_0; + + memset(&config, 0, sizeof(config)); + config.max_pool_cnt = 64; + //VB for YUV420SP output + config.comm_pool[0].blk_cnt = 5; + config.comm_pool[0].mode = VB_REMAP_MODE_NOCACHE; + config.comm_pool[0].blk_size = VICAP_ALIGN_UP((ISP_CHN0_WIDTH * ISP_CHN0_HEIGHT * 3 / 2), VICAP_ALIGN_1K); + + //VB for RGB888 output + config.comm_pool[1].blk_cnt = 5; + config.comm_pool[1].mode = VB_REMAP_MODE_NOCACHE; + config.comm_pool[1].blk_size = VICAP_ALIGN_UP((SENSOR_HEIGHT * SENSOR_WIDTH * 3 ), VICAP_ALIGN_1K); + + ret = kd_mpi_vb_set_config(&config); + if (ret) { + printf("vb_set_config failed ret:%d\n", ret); + return ret; + } + + k_vb_supplement_config supplement_config; + memset(&supplement_config, 0, sizeof(supplement_config)); + supplement_config.supplement_config |= VB_SUPPLEMENT_JPEG_MASK; + + ret = kd_mpi_vb_set_supplement_config(&supplement_config); + if (ret) { + printf("vb_set_supplement_config failed ret:%d\n", ret); + return ret; + } + + ret = kd_mpi_vb_init(); + if (ret) { + printf("vb_init failed ret:%d\n", ret); + return ret; + } + printf("sample_vicap ...kd_mpi_vicap_get_sensor_info\n"); + + // dwc_dsi_init(); + vo_layer_vdss_bind_vo_config(); + + if(vicap_install_osd == 1) + { + memset(&pool_config, 0, sizeof(pool_config)); + pool_config.blk_size = VICAP_ALIGN_UP((osd_width * osd_height * 4 * 2), VICAP_ALIGN_1K); + pool_config.blk_cnt = 4; + pool_config.mode = VB_REMAP_MODE_NOCACHE; + pool_id = kd_mpi_vb_create_pool(&pool_config); // osd0 - 3 argb 320 x 240 + g_pool_id = pool_id; + + printf("--------aa--------------g_pool_id is %d pool_id is %d \n",g_pool_id, pool_id); + } + + memset(&sensor_info, 0, sizeof(k_vicap_sensor_info)); + ret = kd_mpi_vicap_get_sensor_info(sensor_type, &sensor_info); + if (ret) { + printf("sample_vicap, the sensor type not supported!\n"); + return ret; + } + + memset(&dev_attr, 0, sizeof(k_vicap_dev_attr)); + dev_attr.acq_win.h_start = 0; + dev_attr.acq_win.v_start = 0; +#if defined (CONFIG_BOARD_K230_CANMV) + dev_attr.acq_win.width = ISP_CHN0_WIDTH; + dev_attr.acq_win.height = ISP_CHN0_HEIGHT; +#else + dev_attr.acq_win.width = 2592;//SENSOR_HEIGHT; + dev_attr.acq_win.height = 1944;//SENSOR_WIDTH; +#endif + dev_attr.mode = VICAP_WORK_ONLINE_MODE; + + dev_attr.pipe_ctrl.data = 0xFFFFFFFF; + dev_attr.pipe_ctrl.bits.af_enable = 0; + dev_attr.pipe_ctrl.bits.ahdr_enable = 0; + + + dev_attr.cpature_frame = 0; + memcpy(&dev_attr.sensor_info, &sensor_info, sizeof(k_vicap_sensor_info)); + + ret = kd_mpi_vicap_set_dev_attr(vicap_dev, dev_attr); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_set_dev_attr failed.\n"); + return ret; + } + + memset(&chn_attr, 0, sizeof(k_vicap_chn_attr)); + + //set chn0 output yuv420sp + chn_attr.out_win.h_start = 0; + chn_attr.out_win.v_start = 0; + chn_attr.out_win.width = ISP_CHN0_WIDTH; + chn_attr.out_win.height = ISP_CHN0_HEIGHT; + + +#if defined(CONFIG_BOARD_K230_CANMV) + chn_attr.crop_win = dev_attr.acq_win; +#else + // chn_attr.crop_win = dev_attr.acq_win; + chn_attr.crop_win.h_start = 768; + chn_attr.crop_win.v_start = 16; + chn_attr.crop_win.width = ISP_CHN0_WIDTH; + chn_attr.crop_win.height = ISP_CHN0_HEIGHT; +#endif + + chn_attr.scale_win = chn_attr.out_win; + chn_attr.crop_enable = K_FALSE; + chn_attr.scale_enable = K_FALSE; + // chn_attr.dw_enable = K_FALSE; + chn_attr.chn_enable = K_TRUE; + chn_attr.pix_format = PIXEL_FORMAT_YVU_PLANAR_420; + chn_attr.buffer_num = VICAP_MAX_FRAME_COUNT;//at least 3 buffers for isp + chn_attr.buffer_size = config.comm_pool[0].blk_size; + vicap_chn = VICAP_CHN_ID_0; + + printf("sample_vicap ...kd_mpi_vicap_set_chn_attr, buffer_size[%d]\n", chn_attr.buffer_size); + ret = kd_mpi_vicap_set_chn_attr(vicap_dev, vicap_chn, chn_attr); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_set_chn_attr failed.\n"); + return ret; + } + + //bind vicap chn 0 to vo + vicap_mpp_chn.mod_id = K_ID_VI; + vicap_mpp_chn.dev_id = vicap_dev; + vicap_mpp_chn.chn_id = vicap_chn; + + vo_mpp_chn.mod_id = K_ID_VO; + vo_mpp_chn.dev_id = K_VO_DISPLAY_DEV_ID; + vo_mpp_chn.chn_id = K_VO_DISPLAY_CHN_ID1; + + sample_vicap_bind_vo(vicap_mpp_chn, vo_mpp_chn); + printf("sample_vicap ...dwc_dsi_init\n"); + + //set chn1 output rgb888p + chn_attr.out_win.h_start = 0; + chn_attr.out_win.v_start = 0; + chn_attr.out_win.width = SENSOR_WIDTH ; + chn_attr.out_win.height = SENSOR_HEIGHT; + // chn_attr.crop_win = dev_attr.acq_win; + +#if defined(CONFIG_BOARD_K230_CANMV) + chn_attr.crop_win = dev_attr.acq_win; +#else + chn_attr.crop_win.h_start = 768; + chn_attr.crop_win.v_start = 16; + chn_attr.crop_win.width = ISP_CHN0_WIDTH; + chn_attr.crop_win.height = ISP_CHN0_HEIGHT; +#endif + + chn_attr.scale_win = chn_attr.out_win; + chn_attr.crop_enable = K_FALSE; + chn_attr.scale_enable = K_FALSE; + // chn_attr.dw_enable = K_FALSE; + chn_attr.chn_enable = K_TRUE; + chn_attr.pix_format = PIXEL_FORMAT_BGR_888_PLANAR; + chn_attr.buffer_num = VICAP_MAX_FRAME_COUNT;//at least 3 buffers for isp + chn_attr.buffer_size = config.comm_pool[1].blk_size; + + printf("sample_vicap ...kd_mpi_vicap_set_chn_attr, buffer_size[%d]\n", chn_attr.buffer_size); + ret = kd_mpi_vicap_set_chn_attr(vicap_dev, VICAP_CHN_ID_1, chn_attr); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_set_chn_attr failed.\n"); + return ret; + } + + printf("sample_vicap ...kd_mpi_vicap_init\n"); + ret = kd_mpi_vicap_init(vicap_dev); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_init failed.\n"); + // goto err_exit; + } + + printf("sample_vicap ...kd_mpi_vicap_start_stream\n"); + ret = kd_mpi_vicap_start_stream(vicap_dev); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_init failed.\n"); + // goto err_exit; + } + + return ret; +} + +int vivcap_stop() +{ + printf("sample_vicap ...kd_mpi_vicap_stop_stream\n"); + int ret = kd_mpi_vicap_stop_stream(vicap_dev); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_init failed.\n"); + return ret; + } + + ret = kd_mpi_vicap_deinit(vicap_dev); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_deinit failed.\n"); + return ret; + } + + kd_mpi_vo_disable_video_layer(K_VO_LAYER1); + + vicap_mpp_chn.mod_id = K_ID_VI; + vicap_mpp_chn.dev_id = vicap_dev; + vicap_mpp_chn.chn_id = vicap_chn; + + vo_mpp_chn.mod_id = K_ID_VO; + vo_mpp_chn.dev_id = K_VO_DISPLAY_DEV_ID; + vo_mpp_chn.chn_id = K_VO_DISPLAY_CHN_ID1; + + sample_vicap_unbind_vo(vicap_mpp_chn, vo_mpp_chn); + + /*Allow one frame time for the VO to release the VB block*/ + k_u32 display_ms = 1000 / 33; + usleep(1000 * display_ms); + + ret = kd_mpi_vb_exit(); + if (ret) { + printf("sample_vicap, kd_mpi_vb_exit failed.\n"); + return ret; + } + + return 0; +} + +void yuv_rotate_90(char *des, char *src,int width,int height) +{ + int n = 0; + int hw = width>>1; + int hh = height>>1; + int size = width * height; + int hsize = size>>2; + + int pos = 0; + + for(int i = width-1;i >= 0;i--) + { + pos = 0; + for(int j= 0;j < height;j++) + { + des[n++]= src[pos+i]; + pos += width; + } + } + +} + diff --git a/src/reference/ai_poc/self_learning_small/base64.cc b/src/reference/ai_poc/self_learning_small/base64.cc new file mode 100755 index 000000000..72179be6b --- /dev/null +++ b/src/reference/ai_poc/self_learning_small/base64.cc @@ -0,0 +1,164 @@ +/* This is a public domain base64 implementation written by WEI Zhicheng. */ + +#include "base64.h" + +#define BASE64_PAD '=' +#define BASE64DE_FIRST '+' +#define BASE64DE_LAST 'z' + +/* BASE 64 encode table */ +static const char base64en[] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', '+', '/', +}; + +/* ASCII order for BASE 64 decode, 255 in unused character */ +static const unsigned char base64de[] = { + /* nul, soh, stx, etx, eot, enq, ack, bel, */ + 255, 255, 255, 255, 255, 255, 255, 255, + + /* bs, ht, nl, vt, np, cr, so, si, */ + 255, 255, 255, 255, 255, 255, 255, 255, + + /* dle, dc1, dc2, dc3, dc4, nak, syn, etb, */ + 255, 255, 255, 255, 255, 255, 255, 255, + + /* can, em, sub, esc, fs, gs, rs, us, */ + 255, 255, 255, 255, 255, 255, 255, 255, + + /* sp, '!', '"', '#', '$', '%', '&', ''', */ + 255, 255, 255, 255, 255, 255, 255, 255, + + /* '(', ')', '*', '+', ',', '-', '.', '/', */ + 255, 255, 255, 62, 255, 255, 255, 63, + + /* '0', '1', '2', '3', '4', '5', '6', '7', */ + 52, 53, 54, 55, 56, 57, 58, 59, + + /* '8', '9', ':', ';', '<', '=', '>', '?', */ + 60, 61, 255, 255, 255, 255, 255, 255, + + /* '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', */ + 255, 0, 1, 2, 3, 4, 5, 6, + + /* 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', */ + 7, 8, 9, 10, 11, 12, 13, 14, + + /* 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', */ + 15, 16, 17, 18, 19, 20, 21, 22, + + /* 'X', 'Y', 'Z', '[', '\', ']', '^', '_', */ + 23, 24, 25, 255, 255, 255, 255, 255, + + /* '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', */ + 255, 26, 27, 28, 29, 30, 31, 32, + + /* 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', */ + 33, 34, 35, 36, 37, 38, 39, 40, + + /* 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', */ + 41, 42, 43, 44, 45, 46, 47, 48, + + /* 'x', 'y', 'z', '{', '|', '}', '~', del, */ + 49, 50, 51, 255, 255, 255, 255, 255 +}; + +unsigned int +base64_encode(const char *in, unsigned int inlen, char *out) +{ + int s; + unsigned int i; + unsigned int j; + unsigned char c; + unsigned char l; + + s = 0; + l = 0; + for (i = j = 0; i < inlen; i++) { + c = in[i]; + + switch (s) { + case 0: + s = 1; + out[j++] = base64en[(c >> 2) & 0x3F]; + break; + case 1: + s = 2; + out[j++] = base64en[((l & 0x3) << 4) | ((c >> 4) & 0xF)]; + break; + case 2: + s = 0; + out[j++] = base64en[((l & 0xF) << 2) | ((c >> 6) & 0x3)]; + out[j++] = base64en[c & 0x3F]; + break; + } + l = c; + } + + switch (s) { + case 1: + out[j++] = base64en[(l & 0x3) << 4]; + out[j++] = BASE64_PAD; + out[j++] = BASE64_PAD; + break; + case 2: + out[j++] = base64en[(l & 0xF) << 2]; + out[j++] = BASE64_PAD; + break; + } + + out[j] = 0; + + return j; +} + +unsigned int +base64_decode(const char *in, unsigned int inlen, unsigned char *out) +{ + unsigned int i; + unsigned int j; + unsigned char c; + + if (inlen & 0x3) { + return 0; + } + + for (i = j = 0; i < inlen; i++) { + if (in[i] == BASE64_PAD) { + break; + } + if (in[i] < BASE64DE_FIRST || in[i] > BASE64DE_LAST) { + return 0; + } + + c = base64de[(unsigned char)in[i]]; + if (c == 255) { + return 0; + } + + switch (i & 0x3) { + case 0: + out[j] = (c << 2) & 0xFF; + break; + case 1: + out[j++] |= (c >> 4) & 0x3; + out[j] = (c & 0xF) << 4; + break; + case 2: + out[j++] |= (c >> 2) & 0xF; + out[j] = (c & 0x3) << 6; + break; + case 3: + out[j++] |= c; + break; + } + } + + return j; +} diff --git a/src/reference/ai_poc/self_learning_small/base64.h b/src/reference/ai_poc/self_learning_small/base64.h new file mode 100755 index 000000000..028d4c5c2 --- /dev/null +++ b/src/reference/ai_poc/self_learning_small/base64.h @@ -0,0 +1,20 @@ +#ifndef BASE64_H +#define BASE64_H + +#define BASE64_ENCODE_OUT_SIZE(s) ((unsigned int)((((s) + 2) / 3) * 4 + 1)) +#define BASE64_DECODE_OUT_SIZE(s) ((unsigned int)(((s) / 4) * 3)) + +/* + * out is null-terminated encode string. + * return values is out length, exclusive terminating `\0' + */ +unsigned int +base64_encode(const char *in, unsigned int inlen, char *out); + +/* + * return values is out length + */ +unsigned int +base64_decode(const char *in, unsigned int inlen, unsigned char *out); + +#endif /* BASE64_H */ diff --git a/src/reference/ai_poc/self_learning_small/main.cc b/src/reference/ai_poc/self_learning_small/main.cc new file mode 100755 index 000000000..7ba1aaddf --- /dev/null +++ b/src/reference/ai_poc/self_learning_small/main.cc @@ -0,0 +1,109 @@ +#include +#include +#include +#include + +using namespace std; + +std::string readBinInt(std::string path) +{ + + ifstream file2(path, std::ios::binary); + int len2 = 0; + file2.read((char*)&len2, sizeof(len2)); + char* buffer = new char[len2 + 1]; + file2.read(buffer, len2); + buffer[len2] = '\0'; + string str2 = buffer; + delete[] buffer; + file2.close(); + + return str2; +} + +std::vector read_binary_file(const char* file_name) +{ + std::ifstream ifs(file_name, std::ios::binary); + ifs.seekg(0, ifs.end); + size_t len = ifs.tellg(); + std::vector vec(len / sizeof(float), 0); + ifs.seekg(0, ifs.beg); + //ifs->vec + ifs.read(reinterpret_cast(vec.data()), len); + ifs.close(); + return vec; +} + +bool Is_File_Exist(const std::string& file_path) +{ + std::ifstream file(file_path.c_str()); + return file.good(); +} + +bool isFolderExist(string folderPath) { + struct stat info; + if (stat(folderPath.c_str(), &info) != 0) { + return false; + } + return (info.st_mode & S_IFDIR); +} + +bool createFolder(string folderPath) { + if (mkdir(folderPath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) { + return false; + } + return true; +} + +int main(int argc, char *argv[]) +{ + + std::string vec_dir = "vectors"; + if (!isFolderExist(vec_dir)) + { + if (!createFolder(vec_dir)) + { + std::cout << "Create 'vectors' folder failed!!" << std::endl; + return 1; + } + std::cout << "Create 'vectors' folder success!!" << std::endl; + } + else + { + std::cout << " 'vectors' folder has existed already!!" << std::endl; + } + + + while(1) + { + std::cout << "Please input the category:" << std::endl; + std::string category = ""; + getline(std::cin, category); + + std::string cate_dir = vec_dir + "/" + category ; + if (!isFolderExist(cate_dir)) + { + if (!createFolder(cate_dir)) + { + std::cout << "Create " << "'" << cate_dir << "'" << " folder failed!!" << std::endl; + return 1; + } + std::cout << "Create " << "'" << cate_dir << "'" << " folder success!!" << std::endl; + if(!Is_File_Exist( cate_dir + "/index.txt" )) + { + fstream f; + f.open((cate_dir + "/index.txt" ),ios::out); + f<<"0"; + f.close(); + } + } + else + { + std::cout << "'" << cate_dir << "'" << " folder has existed already!!" << std::endl; + } + + } + + + return 0; +} diff --git a/src/reference/ai_poc/shell/crosswalk_detect_img.sh b/src/reference/ai_poc/shell/crosswalk_detect_img.sh new file mode 100644 index 000000000..287c3953d --- /dev/null +++ b/src/reference/ai_poc/shell/crosswalk_detect_img.sh @@ -0,0 +1 @@ +./crosswalk_detect.elf crosswalk.kmodel 0.5 0.45 cw.jpg 0 diff --git a/src/reference/ai_poc/shell/crosswalk_detect_isp.sh b/src/reference/ai_poc/shell/crosswalk_detect_isp.sh new file mode 100644 index 000000000..2b5fabd1a --- /dev/null +++ b/src/reference/ai_poc/shell/crosswalk_detect_isp.sh @@ -0,0 +1 @@ +./crosswalk_detect.elf crosswalk.kmodel 0.5 0.45 None 0 diff --git a/src/reference/ai_poc/shell/face_alignment_image.sh b/src/reference/ai_poc/shell/face_alignment_image.sh new file mode 100755 index 000000000..cc1555491 --- /dev/null +++ b/src/reference/ai_poc/shell/face_alignment_image.sh @@ -0,0 +1,2 @@ +#!/bin/bash +./face_alignment.elf face_detection_320.kmodel 0.6 0.2 face_alignment.kmodel face_alignment_post.kmodel 1024x768.jpg depth 1 \ No newline at end of file diff --git a/src/reference/ai_poc/shell/face_alignment_isp.sh b/src/reference/ai_poc/shell/face_alignment_isp.sh new file mode 100755 index 000000000..2b0b3e9e4 --- /dev/null +++ b/src/reference/ai_poc/shell/face_alignment_isp.sh @@ -0,0 +1,2 @@ +#!/bin/bash +./face_alignment.elf face_detection_320.kmodel 0.6 0.2 face_alignment.kmodel face_alignment_post.kmodel None depth 0 \ No newline at end of file diff --git a/src/reference/ai_poc/shell/face_mesh_image.sh b/src/reference/ai_poc/shell/face_mesh_image.sh new file mode 100755 index 000000000..c53bd1c26 --- /dev/null +++ b/src/reference/ai_poc/shell/face_mesh_image.sh @@ -0,0 +1,2 @@ +#!/bin/bash +./face_mesh.elf face_detection_320.kmodel 0.6 0.2 face_alignment.kmodel face_alignment_post.kmodel 1024x768.jpg 1 \ No newline at end of file diff --git a/src/reference/ai_poc/shell/face_mesh_isp.sh b/src/reference/ai_poc/shell/face_mesh_isp.sh new file mode 100755 index 000000000..9bb8f2f0a --- /dev/null +++ b/src/reference/ai_poc/shell/face_mesh_isp.sh @@ -0,0 +1,2 @@ +#!/bin/bash +./face_mesh.elf face_detection_320.kmodel 0.6 0.2 face_alignment.kmodel face_alignment_post.kmodel None 0 \ No newline at end of file diff --git a/src/reference/ai_poc/shell/handkpflower_image.sh b/src/reference/ai_poc/shell/handkpflower_image.sh new file mode 100644 index 000000000..c332fb857 --- /dev/null +++ b/src/reference/ai_poc/shell/handkpflower_image.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +set -x +./sq_handkp_flower.elf hand_det.kmodel input_flower.jpg 0.15 0.4 handkp_det.kmodel flower_rec.kmodel 0 diff --git a/src/reference/ai_poc/shell/handkpflower_isp.sh b/src/reference/ai_poc/shell/handkpflower_isp.sh new file mode 100644 index 000000000..7adccbec8 --- /dev/null +++ b/src/reference/ai_poc/shell/handkpflower_isp.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +set -x +./sq_handkp_flower.elf hand_det.kmodel None 0.15 0.4 handkp_det.kmodel flower_rec.kmodel 0 diff --git a/src/reference/ai_poc/shell/self_learning_label.sh b/src/reference/ai_poc/shell/self_learning_label.sh new file mode 100644 index 000000000..6abc9aad6 --- /dev/null +++ b/src/reference/ai_poc/shell/self_learning_label.sh @@ -0,0 +1 @@ +./self_learning.elf recognition.kmodel None 0 3 label \ No newline at end of file diff --git a/src/reference/ai_poc/shell/self_learning_work.sh b/src/reference/ai_poc/shell/self_learning_work.sh new file mode 100644 index 000000000..11838f275 --- /dev/null +++ b/src/reference/ai_poc/shell/self_learning_work.sh @@ -0,0 +1 @@ +./self_learning.elf recognition.kmodel None 0 3 work \ No newline at end of file diff --git a/src/reference/ai_poc/shell/translate_en_ch.sh b/src/reference/ai_poc/shell/translate_en_ch.sh new file mode 100644 index 000000000..570fddc68 --- /dev/null +++ b/src/reference/ai_poc/shell/translate_en_ch.sh @@ -0,0 +1 @@ +translate_en_ch.elf translate_encoder.kmodel translate_decoder.kmodel trans_src.model trans_tag.model 0 \ No newline at end of file diff --git a/src/reference/ai_poc/shell/virtual_keyboard.sh b/src/reference/ai_poc/shell/virtual_keyboard.sh new file mode 100644 index 000000000..2b4f89a95 --- /dev/null +++ b/src/reference/ai_poc/shell/virtual_keyboard.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +set -x +./virtual_keyboard.elf hand_det.kmodel 0.25 0.4 handkp_det.kmodel 0 diff --git a/src/reference/ai_poc/sq_handkp_flower/CMakeLists.txt b/src/reference/ai_poc/sq_handkp_flower/CMakeLists.txt new file mode 100644 index 000000000..e722b2f8f --- /dev/null +++ b/src/reference/ai_poc/sq_handkp_flower/CMakeLists.txt @@ -0,0 +1,18 @@ +set(src ai_base.cc main.cc utils.cc clipper.cpp hand_keypoint.cc hand_detection.cc hungarian.cpp my_tracker.cpp sort.cpp flower_recognition.cc) +set(bin sq_handkp_flower.elf) + +include_directories(${PROJECT_SOURCE_DIR}) +include_directories(${nncase_sdk_root}/riscv64/rvvlib/include) +include_directories(${k230_sdk}/src/big/mpp/userapps/api/) +include_directories(${k230_sdk}/src/big/mpp/include) +include_directories(${k230_sdk}/src/big/mpp/include/comm) +include_directories(${k230_sdk}/src/big/mpp/userapps/sample/sample_vo) +link_directories(${nncase_sdk_root}/riscv64/rvvlib/) + +add_executable(${bin} ${src}) +target_link_libraries(${bin} -Wl,--start-group rvv Nncase.Runtime.Native nncase.rt_modules.k230 functional_k230 sys vicap vb cam_device cam_engine + hal oslayer ebase fpga isp_drv binder auto_ctrol common cam_caldb isi 3a buffer_management cameric_drv video_in virtual_hal start_engine cmd_buffer + switch cameric_reg_drv t_database_c t_mxml_c t_json_c t_common_c vo connector sensor atomic dma -Wl,--end-group) + +target_link_libraries(${bin} opencv_imgcodecs opencv_imgproc opencv_core zlib libjpeg-turbo libopenjp2 libpng libtiff libwebp csi_cv) +install(TARGETS ${bin} DESTINATION bin) diff --git a/src/reference/ai_poc/sq_handkp_flower/README.md b/src/reference/ai_poc/sq_handkp_flower/README.md new file mode 100644 index 000000000..f1d56d07b --- /dev/null +++ b/src/reference/ai_poc/sq_handkp_flower/README.md @@ -0,0 +1,30 @@ +# 1.简介 + +手掌检测采用了yolov5网络结构,backbone选取了1.0-mobilenetV2,手掌关键点检测采用了resnet50网络结构。花卉识别backbone选取了1.0-mobilenetV2。使用该应用,可得到图像或视频中的两个手掌的食指指尖包围区域内的花卉类别。可支持102种花卉的种类识别,具体种类可参考 [102 Category Flower Dataset](https://www.robots.ox.ac.uk/~vgg/data/flowers/102/) 。 + +# 2.应用使用说明 + +## 2.1 使用帮助 + +``` +"Usage: " << sq_handkp_flower.elf << " " + +各参数释义如下: +kmodel_det 手掌检测 kmodel路径 +input_mode 本地图片(图片路径)/ 摄像头(None) +obj_thresh 手掌检测阈值 +nms_thresh 手掌检测非极大值抑制阈值 +kmodel_kp 手掌关键点检测 kmodel路径 +flower_rec 花卉识别kmodel路径 +debug_mode 是否需要调试,0、1、2分别表示不调试、简单调试、详细调试 + + #单图推理示例:(handkpflower_image.sh) +./sq_handkp_flower.elf hand_det.kmodel input_flower.jpg 0.15 0.4 handkp_det.kmodel flower_rec.kmodel 0 + + #视频流推理:(handkpflower_isp.sh) +./sq_handkp_flower.elf hand_det.kmodel None 0.15 0.4 handkp_det.kmodel flower_rec.kmodel 0 +``` +## 2.2 效果展示 +![demo示例](https://kendryte-download.canaan-creative.com/k230/downloads/doc_images/ai_demo/sq_handkp_flower/handkp_flower.jpg){:height="50%" width="50%"} + +**注意:** 当两只手同时稳定出现在摄像头下才会做花卉识别,正确使用方式请参考上图。本应用仅提供一个示例实现,如需更高精度或更优体验,可通过调整阈值或自行替换相应的模型文件。 diff --git a/src/reference/ai_poc/sq_handkp_flower/ai_base.cc b/src/reference/ai_poc/sq_handkp_flower/ai_base.cc new file mode 100644 index 000000000..44674d4a1 --- /dev/null +++ b/src/reference/ai_poc/sq_handkp_flower/ai_base.cc @@ -0,0 +1,187 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "ai_base.h" + +#include +#include + +#include "utils.h" + +using std::cout; +using std::endl; +using namespace nncase; +using namespace nncase::runtime::detail; + +AIBase::AIBase(const char *kmodel_file,const string model_name, const int debug_mode) : debug_mode_(debug_mode),model_name_(model_name) +{ + if (debug_mode > 1) + cout << "kmodel_file:" << kmodel_file << endl; + std::ifstream ifs(kmodel_file, std::ios::binary); + kmodel_interp_.load_model(ifs).expect("Invalid kmodel"); + set_input_init(); + set_output_init(); +} + +AIBase::~AIBase() +{ +} + +void AIBase::set_input_init() +{ + ScopedTiming st(model_name_ + " set_input init", debug_mode_); + int input_total_size = 0; + each_input_size_by_byte_.push_back(0); // 先补0,为之后做准备 + for (int i = 0; i < kmodel_interp_.inputs_size(); ++i) + { + auto desc = kmodel_interp_.input_desc(i); + auto shape = kmodel_interp_.input_shape(i); + auto tensor = host_runtime_tensor::create(desc.datatype, shape, hrt::pool_shared).expect("cannot create input tensor"); + kmodel_interp_.input_tensor(i, tensor).expect("cannot set input tensor"); + vector in_shape = {shape[0], shape[1], shape[2], shape[3]}; + input_shapes_.push_back(in_shape); + int dsize = shape[0] * shape[1] * shape[2] * shape[3]; + if (debug_mode_ > 1) + cout << "input shape:" << shape[0] << " " << shape[1] << " " << shape[2] << " " << shape[3] << endl; + // DEFINE_TYPECODE(uint8, u8, 0x06) + // DEFINE_TYPECODE(float32, f32, 0x0B) + if (desc.datatype == 0x06) + { + input_total_size += dsize; + each_input_size_by_byte_.push_back(input_total_size); + } + else if (desc.datatype == 0x0B) + { + input_total_size += (dsize * 4); + each_input_size_by_byte_.push_back(input_total_size); + } + else + assert(("kmodel input data type supports only uint8, float32", 0)); + } + each_input_size_by_byte_.push_back(input_total_size); // 最后一个保存总大小 +} + +void AIBase::set_input(const unsigned char *buf, size_t size) +{ + if (*each_input_size_by_byte_.rbegin() != size) + cout << "set_input:the actual input size{" + std::to_string(size) + "} is different from the model's required input size{" + std::to_string(*each_input_size_by_byte_.rbegin()) + "}" << endl; + assert((*each_input_size_by_byte_.rbegin() == size)); + + ScopedTiming st(model_name_ + " set_input", debug_mode_); + for (size_t i = 0; i < kmodel_interp_.inputs_size(); ++i) + { + auto desc = kmodel_interp_.input_desc(i); + auto shape = kmodel_interp_.input_shape(i); + auto tensor = host_runtime_tensor::create(desc.datatype, shape, hrt::pool_shared).expect("cannot create input tensor"); + auto mapped_buf = std::move(hrt::map(tensor, map_access_::map_write).unwrap()); // mapped_buf实际是有缓存数据的 + memcpy(reinterpret_cast(mapped_buf.buffer().data()), buf, each_input_size_by_byte_[i + 1] - each_input_size_by_byte_[i]); + auto ret = mapped_buf.unmap(); + ret = hrt::sync(tensor, sync_op_t::sync_write_back, true); + if (!ret.is_ok()) + { + std::cerr << "hrt::sync failed" << std::endl; + std::abort(); + } + kmodel_interp_.input_tensor(i, tensor).expect("cannot set input tensor"); + } +} + +runtime_tensor AIBase::get_input_tensor(size_t idx) +{ + return kmodel_interp_.input_tensor(idx).expect("cannot get input tensor"); +} + +void AIBase::set_input_tensor(size_t idx, runtime_tensor &tensor) +{ + ScopedTiming st(model_name_ + " set_input_tensor", debug_mode_); + kmodel_interp_.input_tensor(idx, tensor).expect("cannot set input tensor"); +} + +void AIBase::set_output_init() +{ + ScopedTiming st(model_name_ + " set_output_init", debug_mode_); + each_output_size_by_byte_.clear(); + int output_total_size = 0; + each_output_size_by_byte_.push_back(0); + for (size_t i = 0; i < kmodel_interp_.outputs_size(); i++) + { + auto desc = kmodel_interp_.output_desc(i); + auto shape = kmodel_interp_.output_shape(i); + vector out_shape; + int dsize = 1; + for (int j = 0; j < shape.size(); ++j) + { + out_shape.push_back(shape[j]); + dsize *= shape[j]; + if (debug_mode_ > 1) + cout << shape[j] << ","; + } + if (debug_mode_ > 1) + cout << endl; + output_shapes_.push_back(out_shape); + // DEFINE_TYPECODE(float32, f32, 0x0B) + if (desc.datatype == 0x0B) + { + output_total_size += (dsize * 4); + each_output_size_by_byte_.push_back(output_total_size); + } + else + assert(("kmodel output data type supports only float32", 0)); + auto tensor = host_runtime_tensor::create(desc.datatype, shape, hrt::pool_shared).expect("cannot create output tensor"); + kmodel_interp_.output_tensor(i, tensor).expect("cannot set output tensor"); + } +} + +void AIBase::set_output() +{ + ScopedTiming st(model_name_ + " set_output", debug_mode_); + for (size_t i = 0; i < kmodel_interp_.outputs_size(); i++) + { + auto desc = kmodel_interp_.output_desc(i); + auto shape = kmodel_interp_.output_shape(i); + auto tensor = host_runtime_tensor::create(desc.datatype, shape, hrt::pool_shared).expect("cannot create output tensor"); + kmodel_interp_.output_tensor(i, tensor).expect("cannot set output tensor"); + } +} + +void AIBase::run() +{ + ScopedTiming st(model_name_ + " run", debug_mode_); + kmodel_interp_.run().expect("error occurred in running model"); +} + +void AIBase::get_output() +{ + ScopedTiming st(model_name_ + " get_output", debug_mode_); + p_outputs_.clear(); + for (int i = 0; i < kmodel_interp_.outputs_size(); i++) + { + auto out = kmodel_interp_.output_tensor(i).expect("cannot get output tensor"); + // auto mapped_buf = std::move(hrt::map(out, map_access_::map_read).unwrap()); + // float *p_out = reinterpret_cast(mapped_buf.buffer().data()); + auto buf = out.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_read).unwrap().buffer(); + float *p_out = reinterpret_cast(buf.data()); + p_outputs_.push_back(p_out); + } +} diff --git a/src/reference/ai_poc/sq_handkp_flower/ai_base.h b/src/reference/ai_poc/sq_handkp_flower/ai_base.h new file mode 100644 index 000000000..9fd4470cc --- /dev/null +++ b/src/reference/ai_poc/sq_handkp_flower/ai_base.h @@ -0,0 +1,120 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +// ai_base.h +#ifndef AI_BASE_H +#define AI_BASE_H + +#include +#include +#include + +#include +#include "scoped_timing.hpp" + +using std::string; +using std::vector; +using namespace nncase::runtime; + +/** + * @brief AI基类,封装nncase相关操作 + * 主要封装了nncase的加载、设置输入、运行、获取输出操作,后续开发demo只需要关注模型的前处理、后处理即可 + */ +class AIBase +{ +public: + /** + * @brief AI基类构造函数,加载kmodel,并初始化kmodel输入、输出 + * @param kmodel_file kmodel文件路径 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + AIBase(const char *kmodel_file,const string model_name, const int debug_mode = 1); + + /** + * @brief AI基类析构函数 + * @return None + */ + ~AIBase(); + + /** + * @brief 设置kmodel输入 + * @param buf 输入数据指针 + * @param size 输入数据大小 + * @return None + */ + void set_input(const unsigned char *buf, size_t size); + + /** + * @brief 根据索引获取kmodel输入tensor + * @param idx 输入数据指针 + * @return None + */ + runtime_tensor get_input_tensor(size_t idx); + + void set_input_tensor(size_t idx, runtime_tensor &tensor); + + /** + * @brief 初始化kmodel输出 + * @return None + */ + void set_output(); + + /** + * @brief 推理kmodel + * @return None + */ + void run(); + + /** + * @brief 获取kmodel输出,结果保存在对应的类属性中 + * @return None + */ + void get_output(); + +protected: + string model_name_; // 模型名字 + int debug_mode_; // 调试模型,0(不打印),1(打印时间),2(打印所有) + vector p_outputs_; // kmodel输出对应的指针列表 + vector> input_shapes_; //{{N,C,H,W},{N,C,H,W}...} + vector> output_shapes_; //{{N,C,H,W},{N,C,H,W}...}} 或 {{N,C},{N,C}...}}等 + vector each_input_size_by_byte_; //{0,layer1_length,layer1_length+layer2_length,...} + vector each_output_size_by_byte_; //{0,layer1_length,layer1_length+layer2_length,...} +private: + /** + * @brief 首次初始化kmodel输入,并获取输入shape + * @return None + */ + void set_input_init(); + + /** + * @brief 首次初始化kmodel输出,并获取输出shape + * @return None + */ + void set_output_init(); + + interpreter kmodel_interp_; // kmodel解释器,从kmodel文件构建,负责模型的加载、输入输出设置和推理 + vector kmodel_vec_; // 通过读取kmodel文件得到整个kmodel数据,用于传给kmodel解释器加载kmodel +}; +#endif \ No newline at end of file diff --git a/src/reference/ai_poc/sq_handkp_flower/clipper.cpp b/src/reference/ai_poc/sq_handkp_flower/clipper.cpp new file mode 100644 index 000000000..5c64bc4c1 --- /dev/null +++ b/src/reference/ai_poc/sq_handkp_flower/clipper.cpp @@ -0,0 +1,4597 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "clipper.hpp" +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ClipperLib { + +static double const pi = 3.141592653589793238; +static double const two_pi = pi *2; +static double const def_arc_tolerance = 0.25; + +enum Direction { dRightToLeft, dLeftToRight }; + +static int const Unassigned = -1; //edge not currently 'owning' a solution +static int const Skip = -2; //edge that would otherwise close a path + +#define HORIZONTAL (-1.0E+40) +#define TOLERANCE (1.0e-20) +#define NEAR_ZERO(val) (((val) > -TOLERANCE) && ((val) < TOLERANCE)) + +struct TEdge { + IntPoint Bot; + IntPoint Curr; //current (updated for every new scanbeam) + IntPoint Top; + double Dx; + PolyType PolyTyp; + EdgeSide Side; //side only refers to current side of solution poly + int WindDelta; //1 or -1 depending on winding direction + int WindCnt; + int WindCnt2; //winding count of the opposite polytype + int OutIdx; + TEdge *Next; + TEdge *Prev; + TEdge *NextInLML; + TEdge *NextInAEL; + TEdge *PrevInAEL; + TEdge *NextInSEL; + TEdge *PrevInSEL; +}; + +struct IntersectNode { + TEdge *Edge1; + TEdge *Edge2; + IntPoint Pt; +}; + +struct LocalMinimum { + cInt Y; + TEdge *LeftBound; + TEdge *RightBound; +}; + +struct OutPt; + +//OutRec: contains a path in the clipping solution. Edges in the AEL will +//carry a pointer to an OutRec when they are part of the clipping solution. +struct OutRec { + int Idx; + bool IsHole; + bool IsOpen; + OutRec *FirstLeft; //see comments in clipper.pas + PolyNode *PolyNd; + OutPt *Pts; + OutPt *BottomPt; +}; + +struct OutPt { + int Idx; + IntPoint Pt; + OutPt *Next; + OutPt *Prev; +}; + +struct Join { + OutPt *OutPt1; + OutPt *OutPt2; + IntPoint OffPt; +}; + +struct LocMinSorter +{ + inline bool operator()(const LocalMinimum& locMin1, const LocalMinimum& locMin2) + { + return locMin2.Y < locMin1.Y; + } +}; + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ + +inline cInt Round(double val) +{ + if ((val < 0)) return static_cast(val - 0.5); + else return static_cast(val + 0.5); +} +//------------------------------------------------------------------------------ + +inline cInt Abs(cInt val) +{ + return val < 0 ? -val : val; +} + +//------------------------------------------------------------------------------ +// PolyTree methods ... +//------------------------------------------------------------------------------ + +void PolyTree::Clear() +{ + for (PolyNodes::size_type i = 0; i < AllNodes.size(); ++i) + delete AllNodes[i]; + AllNodes.resize(0); + Childs.resize(0); +} +//------------------------------------------------------------------------------ + +PolyNode* PolyTree::GetFirst() const +{ + if (!Childs.empty()) + return Childs[0]; + else + return 0; +} +//------------------------------------------------------------------------------ + +int PolyTree::Total() const +{ + int result = (int)AllNodes.size(); + //with negative offsets, ignore the hidden outer polygon ... + if (result > 0 && Childs[0] != AllNodes[0]) result--; + return result; +} + +//------------------------------------------------------------------------------ +// PolyNode methods ... +//------------------------------------------------------------------------------ + +PolyNode::PolyNode(): Parent(0), Index(0), m_IsOpen(false) +{ +} +//------------------------------------------------------------------------------ + +int PolyNode::ChildCount() const +{ + return (int)Childs.size(); +} +//------------------------------------------------------------------------------ + +void PolyNode::AddChild(PolyNode& child) +{ + unsigned cnt = (unsigned)Childs.size(); + Childs.push_back(&child); + child.Parent = this; + child.Index = cnt; +} +//------------------------------------------------------------------------------ + +PolyNode* PolyNode::GetNext() const +{ + if (!Childs.empty()) + return Childs[0]; + else + return GetNextSiblingUp(); +} +//------------------------------------------------------------------------------ + +PolyNode* PolyNode::GetNextSiblingUp() const +{ + if (!Parent) //protects against PolyTree.GetNextSiblingUp() + return 0; + else if (Index == Parent->Childs.size() - 1) + return Parent->GetNextSiblingUp(); + else + return Parent->Childs[Index + 1]; +} +//------------------------------------------------------------------------------ + +bool PolyNode::IsHole() const +{ + bool result = true; + PolyNode* node = Parent; + while (node) + { + result = !result; + node = node->Parent; + } + return result; +} +//------------------------------------------------------------------------------ + +bool PolyNode::IsOpen() const +{ + return m_IsOpen; +} +//------------------------------------------------------------------------------ + +#ifndef use_int32 + +class Int128 +{ + public: + ulong64 lo; + long64 hi; + + Int128(long64 _lo = 0) + { + lo = (ulong64)_lo; + if (_lo < 0) hi = -1; else hi = 0; + } + + + Int128(const Int128 &val): lo(val.lo), hi(val.hi){} + + Int128(const long64& _hi, const ulong64& _lo): lo(_lo), hi(_hi){} + + Int128& operator = (const long64 &val) + { + lo = (ulong64)val; + if (val < 0) hi = -1; else hi = 0; + return *this; + } + + bool operator == (const Int128 &val) const + {return (hi == val.hi && lo == val.lo);} + + bool operator != (const Int128 &val) const + { return !(*this == val);} + + bool operator > (const Int128 &val) const + { + if (hi != val.hi) + return hi > val.hi; + else + return lo > val.lo; + } + + bool operator < (const Int128 &val) const + { + if (hi != val.hi) + return hi < val.hi; + else + return lo < val.lo; + } + + bool operator >= (const Int128 &val) const + { return !(*this < val);} + + bool operator <= (const Int128 &val) const + { return !(*this > val);} + + Int128& operator += (const Int128 &rhs) + { + hi += rhs.hi; + lo += rhs.lo; + if (lo < rhs.lo) hi++; + return *this; + } + + Int128 operator + (const Int128 &rhs) const + { + Int128 result(*this); + result+= rhs; + return result; + } + + Int128& operator -= (const Int128 &rhs) + { + *this += -rhs; + return *this; + } + + Int128 operator - (const Int128 &rhs) const + { + Int128 result(*this); + result -= rhs; + return result; + } + + Int128 operator-() const //unary negation + { + if (lo == 0) + return Int128(-hi, 0); + else + return Int128(~hi, ~lo + 1); + } + + operator double() const + { + const double shift64 = 18446744073709551616.0; //2^64 + if (hi < 0) + { + if (lo == 0) return (double)hi * shift64; + else return -(double)(~lo + ~hi * shift64); + } + else + return (double)(lo + hi * shift64); + } + +}; +//------------------------------------------------------------------------------ + +Int128 Int128Mul (long64 lhs, long64 rhs) +{ + bool negate = (lhs < 0) != (rhs < 0); + + if (lhs < 0) lhs = -lhs; + ulong64 int1Hi = ulong64(lhs) >> 32; + ulong64 int1Lo = ulong64(lhs & 0xFFFFFFFF); + + if (rhs < 0) rhs = -rhs; + ulong64 int2Hi = ulong64(rhs) >> 32; + ulong64 int2Lo = ulong64(rhs & 0xFFFFFFFF); + + //nb: see comments in clipper.pas + ulong64 a = int1Hi * int2Hi; + ulong64 b = int1Lo * int2Lo; + ulong64 c = int1Hi * int2Lo + int1Lo * int2Hi; + + Int128 tmp; + tmp.hi = long64(a + (c >> 32)); + tmp.lo = long64(c << 32); + tmp.lo += long64(b); + if (tmp.lo < b) tmp.hi++; + if (negate) tmp = -tmp; + return tmp; +}; +#endif + +bool Orientation(const Path &poly) +{ + return Area(poly) >= 0; +} +//------------------------------------------------------------------------------ + +double Area(const Path &poly) +{ + int size = (int)poly.size(); + if (size < 3) return 0; + + double a = 0; + for (int i = 0, j = size -1; i < size; ++i) + { + a += ((double)poly[j].X + poly[i].X) * ((double)poly[j].Y - poly[i].Y); + j = i; + } + return -a * 0.5; +} +//------------------------------------------------------------------------------ + +double Area(const OutPt *op) +{ + const OutPt *startOp = op; + if (!op) return 0; + double a = 0; + do { + a += (double)(op->Prev->Pt.X + op->Pt.X) * (double)(op->Prev->Pt.Y - op->Pt.Y); + op = op->Next; + } while (op != startOp); + return a * 0.5; +} +//------------------------------------------------------------------------------ + +double Area(const OutRec &outRec) +{ + return Area(outRec.Pts); +} +//------------------------------------------------------------------------------ + +bool PointIsVertex(const IntPoint &Pt, OutPt *pp) +{ + OutPt *pp2 = pp; + do + { + if (pp2->Pt == Pt) return true; + pp2 = pp2->Next; + } + while (pp2 != pp); + return false; +} +//------------------------------------------------------------------------------ + +//See "The Point in Polygon Problem for Arbitrary Polygons" by Hormann & Agathos +//http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.88.5498&rep=rep1&type=pdf +int PointInPolygon(const IntPoint &pt, const Path &path) +{ + //returns 0 if false, +1 if true, -1 if pt ON polygon boundary + int result = 0; + size_t cnt = path.size(); + if (cnt < 3) return 0; + IntPoint ip = path[0]; + for(size_t i = 1; i <= cnt; ++i) + { + IntPoint ipNext = (i == cnt ? path[0] : path[i]); + if (ipNext.Y == pt.Y) + { + if ((ipNext.X == pt.X) || (ip.Y == pt.Y && + ((ipNext.X > pt.X) == (ip.X < pt.X)))) return -1; + } + if ((ip.Y < pt.Y) != (ipNext.Y < pt.Y)) + { + if (ip.X >= pt.X) + { + if (ipNext.X > pt.X) result = 1 - result; + else + { + double d = (double)(ip.X - pt.X) * (ipNext.Y - pt.Y) - + (double)(ipNext.X - pt.X) * (ip.Y - pt.Y); + if (!d) return -1; + if ((d > 0) == (ipNext.Y > ip.Y)) result = 1 - result; + } + } else + { + if (ipNext.X > pt.X) + { + double d = (double)(ip.X - pt.X) * (ipNext.Y - pt.Y) - + (double)(ipNext.X - pt.X) * (ip.Y - pt.Y); + if (!d) return -1; + if ((d > 0) == (ipNext.Y > ip.Y)) result = 1 - result; + } + } + } + ip = ipNext; + } + return result; +} +//------------------------------------------------------------------------------ + +int PointInPolygon (const IntPoint &pt, OutPt *op) +{ + //returns 0 if false, +1 if true, -1 if pt ON polygon boundary + int result = 0; + OutPt* startOp = op; + for(;;) + { + if (op->Next->Pt.Y == pt.Y) + { + if ((op->Next->Pt.X == pt.X) || (op->Pt.Y == pt.Y && + ((op->Next->Pt.X > pt.X) == (op->Pt.X < pt.X)))) return -1; + } + if ((op->Pt.Y < pt.Y) != (op->Next->Pt.Y < pt.Y)) + { + if (op->Pt.X >= pt.X) + { + if (op->Next->Pt.X > pt.X) result = 1 - result; + else + { + double d = (double)(op->Pt.X - pt.X) * (op->Next->Pt.Y - pt.Y) - + (double)(op->Next->Pt.X - pt.X) * (op->Pt.Y - pt.Y); + if (!d) return -1; + if ((d > 0) == (op->Next->Pt.Y > op->Pt.Y)) result = 1 - result; + } + } else + { + if (op->Next->Pt.X > pt.X) + { + double d = (double)(op->Pt.X - pt.X) * (op->Next->Pt.Y - pt.Y) - + (double)(op->Next->Pt.X - pt.X) * (op->Pt.Y - pt.Y); + if (!d) return -1; + if ((d > 0) == (op->Next->Pt.Y > op->Pt.Y)) result = 1 - result; + } + } + } + op = op->Next; + if (startOp == op) break; + } + return result; +} + +bool Poly2ContainsPoly1(OutPt *OutPt1, OutPt *OutPt2) +{ + OutPt* op = OutPt1; + do + { + //nb: PointInPolygon returns 0 if false, +1 if true, -1 if pt on polygon + int res = PointInPolygon(op->Pt, OutPt2); + if (res >= 0) return res > 0; + op = op->Next; + } + while (op != OutPt1); + return true; +} + +bool SlopesEqual(const TEdge &e1, const TEdge &e2, bool UseFullInt64Range) +{ +#ifndef use_int32 + if (UseFullInt64Range) + return Int128Mul(e1.Top.Y - e1.Bot.Y, e2.Top.X - e2.Bot.X) == + Int128Mul(e1.Top.X - e1.Bot.X, e2.Top.Y - e2.Bot.Y); + else +#endif + return (e1.Top.Y - e1.Bot.Y) * (e2.Top.X - e2.Bot.X) == + (e1.Top.X - e1.Bot.X) * (e2.Top.Y - e2.Bot.Y); +} + +bool SlopesEqual(const IntPoint pt1, const IntPoint pt2, + const IntPoint pt3, bool UseFullInt64Range) +{ +#ifndef use_int32 + if (UseFullInt64Range) + return Int128Mul(pt1.Y-pt2.Y, pt2.X-pt3.X) == Int128Mul(pt1.X-pt2.X, pt2.Y-pt3.Y); + else +#endif + return (pt1.Y-pt2.Y)*(pt2.X-pt3.X) == (pt1.X-pt2.X)*(pt2.Y-pt3.Y); +} + +bool SlopesEqual(const IntPoint pt1, const IntPoint pt2, + const IntPoint pt3, const IntPoint pt4, bool UseFullInt64Range) +{ +#ifndef use_int32 + if (UseFullInt64Range) + return Int128Mul(pt1.Y-pt2.Y, pt3.X-pt4.X) == Int128Mul(pt1.X-pt2.X, pt3.Y-pt4.Y); + else +#endif + return (pt1.Y-pt2.Y)*(pt3.X-pt4.X) == (pt1.X-pt2.X)*(pt3.Y-pt4.Y); +} +//------------------------------------------------------------------------------ + +inline bool IsHorizontal(TEdge &e) +{ + return e.Dx == HORIZONTAL; +} +//------------------------------------------------------------------------------ + +inline double GetDx(const IntPoint pt1, const IntPoint pt2) +{ + return (pt1.Y == pt2.Y) ? + HORIZONTAL : (double)(pt2.X - pt1.X) / (pt2.Y - pt1.Y); +} +//--------------------------------------------------------------------------- + +inline void SetDx(TEdge &e) +{ + cInt dy = (e.Top.Y - e.Bot.Y); + if (dy == 0) e.Dx = HORIZONTAL; + else e.Dx = (double)(e.Top.X - e.Bot.X) / dy; +} +//--------------------------------------------------------------------------- + +inline void SwapSides(TEdge &Edge1, TEdge &Edge2) +{ + EdgeSide Side = Edge1.Side; + Edge1.Side = Edge2.Side; + Edge2.Side = Side; +} +//------------------------------------------------------------------------------ + +inline void SwapPolyIndexes(TEdge &Edge1, TEdge &Edge2) +{ + int OutIdx = Edge1.OutIdx; + Edge1.OutIdx = Edge2.OutIdx; + Edge2.OutIdx = OutIdx; +} +//------------------------------------------------------------------------------ + +inline cInt TopX(TEdge &edge, const cInt currentY) +{ + return ( currentY == edge.Top.Y ) ? + edge.Top.X : edge.Bot.X + Round(edge.Dx *(currentY - edge.Bot.Y)); +} +//------------------------------------------------------------------------------ + +void IntersectPoint(TEdge &Edge1, TEdge &Edge2, IntPoint &ip) +{ +#ifdef use_xyz + ip.Z = 0; +#endif + + double b1, b2; + if (Edge1.Dx == Edge2.Dx) + { + ip.Y = Edge1.Curr.Y; + ip.X = TopX(Edge1, ip.Y); + return; + } + else if (Edge1.Dx == 0) + { + ip.X = Edge1.Bot.X; + if (IsHorizontal(Edge2)) + ip.Y = Edge2.Bot.Y; + else + { + b2 = Edge2.Bot.Y - (Edge2.Bot.X / Edge2.Dx); + ip.Y = Round(ip.X / Edge2.Dx + b2); + } + } + else if (Edge2.Dx == 0) + { + ip.X = Edge2.Bot.X; + if (IsHorizontal(Edge1)) + ip.Y = Edge1.Bot.Y; + else + { + b1 = Edge1.Bot.Y - (Edge1.Bot.X / Edge1.Dx); + ip.Y = Round(ip.X / Edge1.Dx + b1); + } + } + else + { + b1 = Edge1.Bot.X - Edge1.Bot.Y * Edge1.Dx; + b2 = Edge2.Bot.X - Edge2.Bot.Y * Edge2.Dx; + double q = (b2-b1) / (Edge1.Dx - Edge2.Dx); + ip.Y = Round(q); + if (std::fabs(Edge1.Dx) < std::fabs(Edge2.Dx)) + ip.X = Round(Edge1.Dx * q + b1); + else + ip.X = Round(Edge2.Dx * q + b2); + } + + if (ip.Y < Edge1.Top.Y || ip.Y < Edge2.Top.Y) + { + if (Edge1.Top.Y > Edge2.Top.Y) + ip.Y = Edge1.Top.Y; + else + ip.Y = Edge2.Top.Y; + if (std::fabs(Edge1.Dx) < std::fabs(Edge2.Dx)) + ip.X = TopX(Edge1, ip.Y); + else + ip.X = TopX(Edge2, ip.Y); + } + //finally, don't allow 'ip' to be BELOW curr.Y (ie bottom of scanbeam) ... + if (ip.Y > Edge1.Curr.Y) + { + ip.Y = Edge1.Curr.Y; + //use the more vertical edge to derive X ... + if (std::fabs(Edge1.Dx) > std::fabs(Edge2.Dx)) + ip.X = TopX(Edge2, ip.Y); else + ip.X = TopX(Edge1, ip.Y); + } +} +//------------------------------------------------------------------------------ + +void ReversePolyPtLinks(OutPt *pp) +{ + if (!pp) return; + OutPt *pp1, *pp2; + pp1 = pp; + do { + pp2 = pp1->Next; + pp1->Next = pp1->Prev; + pp1->Prev = pp2; + pp1 = pp2; + } while( pp1 != pp ); +} +//------------------------------------------------------------------------------ + +void DisposeOutPts(OutPt*& pp) +{ + if (pp == 0) return; + pp->Prev->Next = 0; + while( pp ) + { + OutPt *tmpPp = pp; + pp = pp->Next; + delete tmpPp; + } +} +//------------------------------------------------------------------------------ + +inline void InitEdge(TEdge* e, TEdge* eNext, TEdge* ePrev, const IntPoint& Pt) +{ + std::memset(e, 0, sizeof(TEdge)); + e->Next = eNext; + e->Prev = ePrev; + e->Curr = Pt; + e->OutIdx = Unassigned; +} +//------------------------------------------------------------------------------ + +void InitEdge2(TEdge& e, PolyType Pt) +{ + if (e.Curr.Y >= e.Next->Curr.Y) + { + e.Bot = e.Curr; + e.Top = e.Next->Curr; + } else + { + e.Top = e.Curr; + e.Bot = e.Next->Curr; + } + SetDx(e); + e.PolyTyp = Pt; +} +//------------------------------------------------------------------------------ + +TEdge* RemoveEdge(TEdge* e) +{ + //removes e from double_linked_list (but without removing from memory) + e->Prev->Next = e->Next; + e->Next->Prev = e->Prev; + TEdge* result = e->Next; + e->Prev = 0; //flag as removed (see ClipperBase.Clear) + return result; +} +//------------------------------------------------------------------------------ + +inline void ReverseHorizontal(TEdge &e) +{ + //swap horizontal edges' Top and Bottom x's so they follow the natural + //progression of the bounds - ie so their xbots will align with the + //adjoining lower edge. [Helpful in the ProcessHorizontal() method.] + std::swap(e.Top.X, e.Bot.X); +#ifdef use_xyz + std::swap(e.Top.Z, e.Bot.Z); +#endif +} +//------------------------------------------------------------------------------ + +void SwapPoints(IntPoint &pt1, IntPoint &pt2) +{ + IntPoint tmp = pt1; + pt1 = pt2; + pt2 = tmp; +} +//------------------------------------------------------------------------------ + +bool GetOverlapSegment(IntPoint pt1a, IntPoint pt1b, IntPoint pt2a, + IntPoint pt2b, IntPoint &pt1, IntPoint &pt2) +{ + //precondition: segments are Collinear. + if (Abs(pt1a.X - pt1b.X) > Abs(pt1a.Y - pt1b.Y)) + { + if (pt1a.X > pt1b.X) SwapPoints(pt1a, pt1b); + if (pt2a.X > pt2b.X) SwapPoints(pt2a, pt2b); + if (pt1a.X > pt2a.X) pt1 = pt1a; else pt1 = pt2a; + if (pt1b.X < pt2b.X) pt2 = pt1b; else pt2 = pt2b; + return pt1.X < pt2.X; + } else + { + if (pt1a.Y < pt1b.Y) SwapPoints(pt1a, pt1b); + if (pt2a.Y < pt2b.Y) SwapPoints(pt2a, pt2b); + if (pt1a.Y < pt2a.Y) pt1 = pt1a; else pt1 = pt2a; + if (pt1b.Y > pt2b.Y) pt2 = pt1b; else pt2 = pt2b; + return pt1.Y > pt2.Y; + } +} +//------------------------------------------------------------------------------ + +bool FirstIsBottomPt(const OutPt* btmPt1, const OutPt* btmPt2) +{ + OutPt *p = btmPt1->Prev; + while ((p->Pt == btmPt1->Pt) && (p != btmPt1)) p = p->Prev; + double dx1p = std::fabs(GetDx(btmPt1->Pt, p->Pt)); + p = btmPt1->Next; + while ((p->Pt == btmPt1->Pt) && (p != btmPt1)) p = p->Next; + double dx1n = std::fabs(GetDx(btmPt1->Pt, p->Pt)); + + p = btmPt2->Prev; + while ((p->Pt == btmPt2->Pt) && (p != btmPt2)) p = p->Prev; + double dx2p = std::fabs(GetDx(btmPt2->Pt, p->Pt)); + p = btmPt2->Next; + while ((p->Pt == btmPt2->Pt) && (p != btmPt2)) p = p->Next; + double dx2n = std::fabs(GetDx(btmPt2->Pt, p->Pt)); + + if (std::max(dx1p, dx1n) == std::max(dx2p, dx2n) && + std::min(dx1p, dx1n) == std::min(dx2p, dx2n)) + return Area(btmPt1) > 0; //if otherwise identical use orientation + else + return (dx1p >= dx2p && dx1p >= dx2n) || (dx1n >= dx2p && dx1n >= dx2n); +} +//------------------------------------------------------------------------------ + +OutPt* GetBottomPt(OutPt *pp) +{ + OutPt* dups = 0; + OutPt* p = pp->Next; + while (p != pp) + { + if (p->Pt.Y > pp->Pt.Y) + { + pp = p; + dups = 0; + } + else if (p->Pt.Y == pp->Pt.Y && p->Pt.X <= pp->Pt.X) + { + if (p->Pt.X < pp->Pt.X) + { + dups = 0; + pp = p; + } else + { + if (p->Next != pp && p->Prev != pp) dups = p; + } + } + p = p->Next; + } + if (dups) + { + //there appears to be at least 2 vertices at BottomPt so ... + while (dups != p) + { + if (!FirstIsBottomPt(p, dups)) pp = dups; + dups = dups->Next; + while (dups->Pt != pp->Pt) dups = dups->Next; + } + } + return pp; +} +//------------------------------------------------------------------------------ + +bool Pt2IsBetweenPt1AndPt3(const IntPoint pt1, + const IntPoint pt2, const IntPoint pt3) +{ + if ((pt1 == pt3) || (pt1 == pt2) || (pt3 == pt2)) + return false; + else if (pt1.X != pt3.X) + return (pt2.X > pt1.X) == (pt2.X < pt3.X); + else + return (pt2.Y > pt1.Y) == (pt2.Y < pt3.Y); +} +//------------------------------------------------------------------------------ + +bool HorzSegmentsOverlap(cInt seg1a, cInt seg1b, cInt seg2a, cInt seg2b) +{ + if (seg1a > seg1b) std::swap(seg1a, seg1b); + if (seg2a > seg2b) std::swap(seg2a, seg2b); + return (seg1a < seg2b) && (seg2a < seg1b); +} + +//------------------------------------------------------------------------------ +// ClipperBase class methods ... +//------------------------------------------------------------------------------ + +ClipperBase::ClipperBase() //constructor +{ + m_CurrentLM = m_MinimaList.begin(); //begin() == end() here + m_UseFullRange = false; +} +//------------------------------------------------------------------------------ + +ClipperBase::~ClipperBase() //destructor +{ + Clear(); +} +//------------------------------------------------------------------------------ + +void RangeTest(const IntPoint& Pt, bool& useFullRange) +{ + if (useFullRange) + { + if (Pt.X > hiRange || Pt.Y > hiRange || -Pt.X > hiRange || -Pt.Y > hiRange) + throw clipperException("Coordinate outside allowed range"); + } + else if (Pt.X > loRange|| Pt.Y > loRange || -Pt.X > loRange || -Pt.Y > loRange) + { + useFullRange = true; + RangeTest(Pt, useFullRange); + } +} +//------------------------------------------------------------------------------ + +TEdge* FindNextLocMin(TEdge* E) +{ + for (;;) + { + while (E->Bot != E->Prev->Bot || E->Curr == E->Top) E = E->Next; + if (!IsHorizontal(*E) && !IsHorizontal(*E->Prev)) break; + while (IsHorizontal(*E->Prev)) E = E->Prev; + TEdge* E2 = E; + while (IsHorizontal(*E)) E = E->Next; + if (E->Top.Y == E->Prev->Bot.Y) continue; //ie just an intermediate horz. + if (E2->Prev->Bot.X < E->Bot.X) E = E2; + break; + } + return E; +} +//------------------------------------------------------------------------------ + +TEdge* ClipperBase::ProcessBound(TEdge* E, bool NextIsForward) +{ + TEdge *Result = E; + TEdge *Horz = 0; + + if (E->OutIdx == Skip) + { + //if edges still remain in the current bound beyond the skip edge then + //create another LocMin and call ProcessBound once more + if (NextIsForward) + { + while (E->Top.Y == E->Next->Bot.Y) E = E->Next; + //don't include top horizontals when parsing a bound a second time, + //they will be contained in the opposite bound ... + while (E != Result && IsHorizontal(*E)) E = E->Prev; + } + else + { + while (E->Top.Y == E->Prev->Bot.Y) E = E->Prev; + while (E != Result && IsHorizontal(*E)) E = E->Next; + } + + if (E == Result) + { + if (NextIsForward) Result = E->Next; + else Result = E->Prev; + } + else + { + //there are more edges in the bound beyond result starting with E + if (NextIsForward) + E = Result->Next; + else + E = Result->Prev; + MinimaList::value_type locMin; + locMin.Y = E->Bot.Y; + locMin.LeftBound = 0; + locMin.RightBound = E; + E->WindDelta = 0; + Result = ProcessBound(E, NextIsForward); + m_MinimaList.push_back(locMin); + } + return Result; + } + + TEdge *EStart; + + if (IsHorizontal(*E)) + { + //We need to be careful with open paths because this may not be a + //true local minima (ie E may be following a skip edge). + //Also, consecutive horz. edges may start heading left before going right. + if (NextIsForward) + EStart = E->Prev; + else + EStart = E->Next; + if (IsHorizontal(*EStart)) //ie an adjoining horizontal skip edge + { + if (EStart->Bot.X != E->Bot.X && EStart->Top.X != E->Bot.X) + ReverseHorizontal(*E); + } + else if (EStart->Bot.X != E->Bot.X) + ReverseHorizontal(*E); + } + + EStart = E; + if (NextIsForward) + { + while (Result->Top.Y == Result->Next->Bot.Y && Result->Next->OutIdx != Skip) + Result = Result->Next; + if (IsHorizontal(*Result) && Result->Next->OutIdx != Skip) + { + //nb: at the top of a bound, horizontals are added to the bound + //only when the preceding edge attaches to the horizontal's left vertex + //unless a Skip edge is encountered when that becomes the top divide + Horz = Result; + while (IsHorizontal(*Horz->Prev)) Horz = Horz->Prev; + if (Horz->Prev->Top.X > Result->Next->Top.X) Result = Horz->Prev; + } + while (E != Result) + { + E->NextInLML = E->Next; + if (IsHorizontal(*E) && E != EStart && + E->Bot.X != E->Prev->Top.X) ReverseHorizontal(*E); + E = E->Next; + } + if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Prev->Top.X) + ReverseHorizontal(*E); + Result = Result->Next; //move to the edge just beyond current bound + } else + { + while (Result->Top.Y == Result->Prev->Bot.Y && Result->Prev->OutIdx != Skip) + Result = Result->Prev; + if (IsHorizontal(*Result) && Result->Prev->OutIdx != Skip) + { + Horz = Result; + while (IsHorizontal(*Horz->Next)) Horz = Horz->Next; + if (Horz->Next->Top.X == Result->Prev->Top.X || + Horz->Next->Top.X > Result->Prev->Top.X) Result = Horz->Next; + } + + while (E != Result) + { + E->NextInLML = E->Prev; + if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Next->Top.X) + ReverseHorizontal(*E); + E = E->Prev; + } + if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Next->Top.X) + ReverseHorizontal(*E); + Result = Result->Prev; //move to the edge just beyond current bound + } + + return Result; +} +//------------------------------------------------------------------------------ + +bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed) +{ +#ifdef use_lines + if (!Closed && PolyTyp == ptClip) + throw clipperException("AddPath: Open paths must be subject."); +#else + if (!Closed) + throw clipperException("AddPath: Open paths have been disabled."); +#endif + + int highI = (int)pg.size() -1; + if (Closed) while (highI > 0 && (pg[highI] == pg[0])) --highI; + while (highI > 0 && (pg[highI] == pg[highI -1])) --highI; + if ((Closed && highI < 2) || (!Closed && highI < 1)) return false; + + //create a new edge array ... + TEdge *edges = new TEdge [highI +1]; + + bool IsFlat = true; + //1. Basic (first) edge initialization ... + try + { + edges[1].Curr = pg[1]; + RangeTest(pg[0], m_UseFullRange); + RangeTest(pg[highI], m_UseFullRange); + InitEdge(&edges[0], &edges[1], &edges[highI], pg[0]); + InitEdge(&edges[highI], &edges[0], &edges[highI-1], pg[highI]); + for (int i = highI - 1; i >= 1; --i) + { + RangeTest(pg[i], m_UseFullRange); + InitEdge(&edges[i], &edges[i+1], &edges[i-1], pg[i]); + } + } + catch(...) + { + delete [] edges; + throw; //range test fails + } + TEdge *eStart = &edges[0]; + + //2. Remove duplicate vertices, and (when closed) collinear edges ... + TEdge *E = eStart, *eLoopStop = eStart; + for (;;) + { + //nb: allows matching start and end points when not Closed ... + if (E->Curr == E->Next->Curr && (Closed || E->Next != eStart)) + { + if (E == E->Next) break; + if (E == eStart) eStart = E->Next; + E = RemoveEdge(E); + eLoopStop = E; + continue; + } + if (E->Prev == E->Next) + break; //only two vertices + else if (Closed && + SlopesEqual(E->Prev->Curr, E->Curr, E->Next->Curr, m_UseFullRange) && + (!m_PreserveCollinear || + !Pt2IsBetweenPt1AndPt3(E->Prev->Curr, E->Curr, E->Next->Curr))) + { + //Collinear edges are allowed for open paths but in closed paths + //the default is to merge adjacent collinear edges into a single edge. + //However, if the PreserveCollinear property is enabled, only overlapping + //collinear edges (ie spikes) will be removed from closed paths. + if (E == eStart) eStart = E->Next; + E = RemoveEdge(E); + E = E->Prev; + eLoopStop = E; + continue; + } + E = E->Next; + if ((E == eLoopStop) || (!Closed && E->Next == eStart)) break; + } + + if ((!Closed && (E == E->Next)) || (Closed && (E->Prev == E->Next))) + { + delete [] edges; + return false; + } + + if (!Closed) + { + m_HasOpenPaths = true; + eStart->Prev->OutIdx = Skip; + } + + //3. Do second stage of edge initialization ... + E = eStart; + do + { + InitEdge2(*E, PolyTyp); + E = E->Next; + if (IsFlat && E->Curr.Y != eStart->Curr.Y) IsFlat = false; + } + while (E != eStart); + + //4. Finally, add edge bounds to LocalMinima list ... + + //Totally flat paths must be handled differently when adding them + //to LocalMinima list to avoid endless loops etc ... + if (IsFlat) + { + if (Closed) + { + delete [] edges; + return false; + } + E->Prev->OutIdx = Skip; + MinimaList::value_type locMin; + locMin.Y = E->Bot.Y; + locMin.LeftBound = 0; + locMin.RightBound = E; + locMin.RightBound->Side = esRight; + locMin.RightBound->WindDelta = 0; + for (;;) + { + if (E->Bot.X != E->Prev->Top.X) ReverseHorizontal(*E); + if (E->Next->OutIdx == Skip) break; + E->NextInLML = E->Next; + E = E->Next; + } + m_MinimaList.push_back(locMin); + m_edges.push_back(edges); + return true; + } + + m_edges.push_back(edges); + bool leftBoundIsForward; + TEdge* EMin = 0; + + //workaround to avoid an endless loop in the while loop below when + //open paths have matching start and end points ... + if (E->Prev->Bot == E->Prev->Top) E = E->Next; + + for (;;) + { + E = FindNextLocMin(E); + if (E == EMin) break; + else if (!EMin) EMin = E; + + //E and E.Prev now share a local minima (left aligned if horizontal). + //Compare their slopes to find which starts which bound ... + MinimaList::value_type locMin; + locMin.Y = E->Bot.Y; + if (E->Dx < E->Prev->Dx) + { + locMin.LeftBound = E->Prev; + locMin.RightBound = E; + leftBoundIsForward = false; //Q.nextInLML = Q.prev + } else + { + locMin.LeftBound = E; + locMin.RightBound = E->Prev; + leftBoundIsForward = true; //Q.nextInLML = Q.next + } + + if (!Closed) locMin.LeftBound->WindDelta = 0; + else if (locMin.LeftBound->Next == locMin.RightBound) + locMin.LeftBound->WindDelta = -1; + else locMin.LeftBound->WindDelta = 1; + locMin.RightBound->WindDelta = -locMin.LeftBound->WindDelta; + + E = ProcessBound(locMin.LeftBound, leftBoundIsForward); + if (E->OutIdx == Skip) E = ProcessBound(E, leftBoundIsForward); + + TEdge* E2 = ProcessBound(locMin.RightBound, !leftBoundIsForward); + if (E2->OutIdx == Skip) E2 = ProcessBound(E2, !leftBoundIsForward); + + if (locMin.LeftBound->OutIdx == Skip) + locMin.LeftBound = 0; + else if (locMin.RightBound->OutIdx == Skip) + locMin.RightBound = 0; + m_MinimaList.push_back(locMin); + if (!leftBoundIsForward) E = E2; + } + return true; +} +//------------------------------------------------------------------------------ + +bool ClipperBase::AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed) +{ + bool result = false; + for (Paths::size_type i = 0; i < ppg.size(); ++i) + if (AddPath(ppg[i], PolyTyp, Closed)) result = true; + return result; +} +//------------------------------------------------------------------------------ + +void ClipperBase::Clear() +{ + DisposeLocalMinimaList(); + for (EdgeList::size_type i = 0; i < m_edges.size(); ++i) + { + TEdge* edges = m_edges[i]; + delete [] edges; + } + m_edges.clear(); + m_UseFullRange = false; + m_HasOpenPaths = false; +} +//------------------------------------------------------------------------------ + +void ClipperBase::Reset() +{ + m_CurrentLM = m_MinimaList.begin(); + if (m_CurrentLM == m_MinimaList.end()) return; //ie nothing to process + std::sort(m_MinimaList.begin(), m_MinimaList.end(), LocMinSorter()); + + m_Scanbeam = ScanbeamList(); //clears/resets priority_queue + //reset all edges ... + for (MinimaList::iterator lm = m_MinimaList.begin(); lm != m_MinimaList.end(); ++lm) + { + InsertScanbeam(lm->Y); + TEdge* e = lm->LeftBound; + if (e) + { + e->Curr = e->Bot; + e->Side = esLeft; + e->OutIdx = Unassigned; + } + + e = lm->RightBound; + if (e) + { + e->Curr = e->Bot; + e->Side = esRight; + e->OutIdx = Unassigned; + } + } + m_ActiveEdges = 0; + m_CurrentLM = m_MinimaList.begin(); +} +//------------------------------------------------------------------------------ + +void ClipperBase::DisposeLocalMinimaList() +{ + m_MinimaList.clear(); + m_CurrentLM = m_MinimaList.begin(); +} +//------------------------------------------------------------------------------ + +bool ClipperBase::PopLocalMinima(cInt Y, const LocalMinimum *&locMin) +{ + if (m_CurrentLM == m_MinimaList.end() || (*m_CurrentLM).Y != Y) return false; + locMin = &(*m_CurrentLM); + ++m_CurrentLM; + return true; +} +//------------------------------------------------------------------------------ + +IntRect ClipperBase::GetBounds() +{ + IntRect result; + MinimaList::iterator lm = m_MinimaList.begin(); + if (lm == m_MinimaList.end()) + { + result.left = result.top = result.right = result.bottom = 0; + return result; + } + result.left = lm->LeftBound->Bot.X; + result.top = lm->LeftBound->Bot.Y; + result.right = lm->LeftBound->Bot.X; + result.bottom = lm->LeftBound->Bot.Y; + while (lm != m_MinimaList.end()) + { + //todo - needs fixing for open paths + result.bottom = std::max(result.bottom, lm->LeftBound->Bot.Y); + TEdge* e = lm->LeftBound; + for (;;) { + TEdge* bottomE = e; + while (e->NextInLML) + { + if (e->Bot.X < result.left) result.left = e->Bot.X; + if (e->Bot.X > result.right) result.right = e->Bot.X; + e = e->NextInLML; + } + result.left = std::min(result.left, e->Bot.X); + result.right = std::max(result.right, e->Bot.X); + result.left = std::min(result.left, e->Top.X); + result.right = std::max(result.right, e->Top.X); + result.top = std::min(result.top, e->Top.Y); + if (bottomE == lm->LeftBound) e = lm->RightBound; + else break; + } + ++lm; + } + return result; +} +//------------------------------------------------------------------------------ + +void ClipperBase::InsertScanbeam(const cInt Y) +{ + m_Scanbeam.push(Y); +} +//------------------------------------------------------------------------------ + +bool ClipperBase::PopScanbeam(cInt &Y) +{ + if (m_Scanbeam.empty()) return false; + Y = m_Scanbeam.top(); + m_Scanbeam.pop(); + while (!m_Scanbeam.empty() && Y == m_Scanbeam.top()) { m_Scanbeam.pop(); } // Pop duplicates. + return true; +} +//------------------------------------------------------------------------------ + +void ClipperBase::DisposeAllOutRecs(){ + for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) + DisposeOutRec(i); + m_PolyOuts.clear(); +} +//------------------------------------------------------------------------------ + +void ClipperBase::DisposeOutRec(PolyOutList::size_type index) +{ + OutRec *outRec = m_PolyOuts[index]; + if (outRec->Pts) DisposeOutPts(outRec->Pts); + delete outRec; + m_PolyOuts[index] = 0; +} +//------------------------------------------------------------------------------ + +void ClipperBase::DeleteFromAEL(TEdge *e) +{ + TEdge* AelPrev = e->PrevInAEL; + TEdge* AelNext = e->NextInAEL; + if (!AelPrev && !AelNext && (e != m_ActiveEdges)) return; //already deleted + if (AelPrev) AelPrev->NextInAEL = AelNext; + else m_ActiveEdges = AelNext; + if (AelNext) AelNext->PrevInAEL = AelPrev; + e->NextInAEL = 0; + e->PrevInAEL = 0; +} +//------------------------------------------------------------------------------ + +OutRec* ClipperBase::CreateOutRec() +{ + OutRec* result = new OutRec; + result->IsHole = false; + result->IsOpen = false; + result->FirstLeft = 0; + result->Pts = 0; + result->BottomPt = 0; + result->PolyNd = 0; + m_PolyOuts.push_back(result); + result->Idx = (int)m_PolyOuts.size() - 1; + return result; +} +//------------------------------------------------------------------------------ + +void ClipperBase::SwapPositionsInAEL(TEdge *Edge1, TEdge *Edge2) +{ + //check that one or other edge hasn't already been removed from AEL ... + if (Edge1->NextInAEL == Edge1->PrevInAEL || + Edge2->NextInAEL == Edge2->PrevInAEL) return; + + if (Edge1->NextInAEL == Edge2) + { + TEdge* Next = Edge2->NextInAEL; + if (Next) Next->PrevInAEL = Edge1; + TEdge* Prev = Edge1->PrevInAEL; + if (Prev) Prev->NextInAEL = Edge2; + Edge2->PrevInAEL = Prev; + Edge2->NextInAEL = Edge1; + Edge1->PrevInAEL = Edge2; + Edge1->NextInAEL = Next; + } + else if (Edge2->NextInAEL == Edge1) + { + TEdge* Next = Edge1->NextInAEL; + if (Next) Next->PrevInAEL = Edge2; + TEdge* Prev = Edge2->PrevInAEL; + if (Prev) Prev->NextInAEL = Edge1; + Edge1->PrevInAEL = Prev; + Edge1->NextInAEL = Edge2; + Edge2->PrevInAEL = Edge1; + Edge2->NextInAEL = Next; + } + else + { + TEdge* Next = Edge1->NextInAEL; + TEdge* Prev = Edge1->PrevInAEL; + Edge1->NextInAEL = Edge2->NextInAEL; + if (Edge1->NextInAEL) Edge1->NextInAEL->PrevInAEL = Edge1; + Edge1->PrevInAEL = Edge2->PrevInAEL; + if (Edge1->PrevInAEL) Edge1->PrevInAEL->NextInAEL = Edge1; + Edge2->NextInAEL = Next; + if (Edge2->NextInAEL) Edge2->NextInAEL->PrevInAEL = Edge2; + Edge2->PrevInAEL = Prev; + if (Edge2->PrevInAEL) Edge2->PrevInAEL->NextInAEL = Edge2; + } + + if (!Edge1->PrevInAEL) m_ActiveEdges = Edge1; + else if (!Edge2->PrevInAEL) m_ActiveEdges = Edge2; +} +//------------------------------------------------------------------------------ + +void ClipperBase::UpdateEdgeIntoAEL(TEdge *&e) +{ + if (!e->NextInLML) + throw clipperException("UpdateEdgeIntoAEL: invalid call"); + + e->NextInLML->OutIdx = e->OutIdx; + TEdge* AelPrev = e->PrevInAEL; + TEdge* AelNext = e->NextInAEL; + if (AelPrev) AelPrev->NextInAEL = e->NextInLML; + else m_ActiveEdges = e->NextInLML; + if (AelNext) AelNext->PrevInAEL = e->NextInLML; + e->NextInLML->Side = e->Side; + e->NextInLML->WindDelta = e->WindDelta; + e->NextInLML->WindCnt = e->WindCnt; + e->NextInLML->WindCnt2 = e->WindCnt2; + e = e->NextInLML; + e->Curr = e->Bot; + e->PrevInAEL = AelPrev; + e->NextInAEL = AelNext; + if (!IsHorizontal(*e)) InsertScanbeam(e->Top.Y); +} +//------------------------------------------------------------------------------ + +bool ClipperBase::LocalMinimaPending() +{ + return (m_CurrentLM != m_MinimaList.end()); +} + +//------------------------------------------------------------------------------ +// TClipper methods ... +//------------------------------------------------------------------------------ + +Clipper::Clipper(int initOptions) : ClipperBase() //constructor +{ + m_ExecuteLocked = false; + m_UseFullRange = false; + m_ReverseOutput = ((initOptions & ioReverseSolution) != 0); + m_StrictSimple = ((initOptions & ioStrictlySimple) != 0); + m_PreserveCollinear = ((initOptions & ioPreserveCollinear) != 0); + m_HasOpenPaths = false; +#ifdef use_xyz + m_ZFill = 0; +#endif +} +//------------------------------------------------------------------------------ + +#ifdef use_xyz +void Clipper::ZFillFunction(ZFillCallback zFillFunc) +{ + m_ZFill = zFillFunc; +} +//------------------------------------------------------------------------------ +#endif + +bool Clipper::Execute(ClipType clipType, Paths &solution, PolyFillType fillType) +{ + return Execute(clipType, solution, fillType, fillType); +} +//------------------------------------------------------------------------------ + +bool Clipper::Execute(ClipType clipType, PolyTree &polytree, PolyFillType fillType) +{ + return Execute(clipType, polytree, fillType, fillType); +} +//------------------------------------------------------------------------------ + +bool Clipper::Execute(ClipType clipType, Paths &solution, + PolyFillType subjFillType, PolyFillType clipFillType) +{ + if( m_ExecuteLocked ) return false; + if (m_HasOpenPaths) + throw clipperException("Error: PolyTree struct is needed for open path clipping."); + m_ExecuteLocked = true; + solution.resize(0); + m_SubjFillType = subjFillType; + m_ClipFillType = clipFillType; + m_ClipType = clipType; + m_UsingPolyTree = false; + bool succeeded = ExecuteInternal(); + if (succeeded) BuildResult(solution); + DisposeAllOutRecs(); + m_ExecuteLocked = false; + return succeeded; +} +//------------------------------------------------------------------------------ + +bool Clipper::Execute(ClipType clipType, PolyTree& polytree, + PolyFillType subjFillType, PolyFillType clipFillType) +{ + if( m_ExecuteLocked ) return false; + m_ExecuteLocked = true; + m_SubjFillType = subjFillType; + m_ClipFillType = clipFillType; + m_ClipType = clipType; + m_UsingPolyTree = true; + bool succeeded = ExecuteInternal(); + if (succeeded) BuildResult2(polytree); + DisposeAllOutRecs(); + m_ExecuteLocked = false; + return succeeded; +} +//------------------------------------------------------------------------------ + +void Clipper::FixHoleLinkage(OutRec &outrec) +{ + //skip OutRecs that (a) contain outermost polygons or + //(b) already have the correct owner/child linkage ... + if (!outrec.FirstLeft || + (outrec.IsHole != outrec.FirstLeft->IsHole && + outrec.FirstLeft->Pts)) return; + + OutRec* orfl = outrec.FirstLeft; + while (orfl && ((orfl->IsHole == outrec.IsHole) || !orfl->Pts)) + orfl = orfl->FirstLeft; + outrec.FirstLeft = orfl; +} +//------------------------------------------------------------------------------ + +bool Clipper::ExecuteInternal() +{ + bool succeeded = true; + try { + Reset(); + m_Maxima = MaximaList(); + m_SortedEdges = 0; + + succeeded = true; + cInt botY, topY; + if (!PopScanbeam(botY)) return false; + InsertLocalMinimaIntoAEL(botY); + while (PopScanbeam(topY) || LocalMinimaPending()) + { + ProcessHorizontals(); + ClearGhostJoins(); + if (!ProcessIntersections(topY)) + { + succeeded = false; + break; + } + ProcessEdgesAtTopOfScanbeam(topY); + botY = topY; + InsertLocalMinimaIntoAEL(botY); + } + } + catch(...) + { + succeeded = false; + } + + if (succeeded) + { + //fix orientations ... + for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) + { + OutRec *outRec = m_PolyOuts[i]; + if (!outRec->Pts || outRec->IsOpen) continue; + if ((outRec->IsHole ^ m_ReverseOutput) == (Area(*outRec) > 0)) + ReversePolyPtLinks(outRec->Pts); + } + + if (!m_Joins.empty()) JoinCommonEdges(); + + //unfortunately FixupOutPolygon() must be done after JoinCommonEdges() + for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) + { + OutRec *outRec = m_PolyOuts[i]; + if (!outRec->Pts) continue; + if (outRec->IsOpen) + FixupOutPolyline(*outRec); + else + FixupOutPolygon(*outRec); + } + + if (m_StrictSimple) DoSimplePolygons(); + } + + ClearJoins(); + ClearGhostJoins(); + return succeeded; +} +//------------------------------------------------------------------------------ + +void Clipper::SetWindingCount(TEdge &edge) +{ + TEdge *e = edge.PrevInAEL; + //find the edge of the same polytype that immediately preceeds 'edge' in AEL + while (e && ((e->PolyTyp != edge.PolyTyp) || (e->WindDelta == 0))) e = e->PrevInAEL; + if (!e) + { + if (edge.WindDelta == 0) + { + PolyFillType pft = (edge.PolyTyp == ptSubject ? m_SubjFillType : m_ClipFillType); + edge.WindCnt = (pft == pftNegative ? -1 : 1); + } + else + edge.WindCnt = edge.WindDelta; + edge.WindCnt2 = 0; + e = m_ActiveEdges; //ie get ready to calc WindCnt2 + } + else if (edge.WindDelta == 0 && m_ClipType != ctUnion) + { + edge.WindCnt = 1; + edge.WindCnt2 = e->WindCnt2; + e = e->NextInAEL; //ie get ready to calc WindCnt2 + } + else if (IsEvenOddFillType(edge)) + { + //EvenOdd filling ... + if (edge.WindDelta == 0) + { + //are we inside a subj polygon ... + bool Inside = true; + TEdge *e2 = e->PrevInAEL; + while (e2) + { + if (e2->PolyTyp == e->PolyTyp && e2->WindDelta != 0) + Inside = !Inside; + e2 = e2->PrevInAEL; + } + edge.WindCnt = (Inside ? 0 : 1); + } + else + { + edge.WindCnt = edge.WindDelta; + } + edge.WindCnt2 = e->WindCnt2; + e = e->NextInAEL; //ie get ready to calc WindCnt2 + } + else + { + //nonZero, Positive or Negative filling ... + if (e->WindCnt * e->WindDelta < 0) + { + //prev edge is 'decreasing' WindCount (WC) toward zero + //so we're outside the previous polygon ... + if (Abs(e->WindCnt) > 1) + { + //outside prev poly but still inside another. + //when reversing direction of prev poly use the same WC + if (e->WindDelta * edge.WindDelta < 0) edge.WindCnt = e->WindCnt; + //otherwise continue to 'decrease' WC ... + else edge.WindCnt = e->WindCnt + edge.WindDelta; + } + else + //now outside all polys of same polytype so set own WC ... + edge.WindCnt = (edge.WindDelta == 0 ? 1 : edge.WindDelta); + } else + { + //prev edge is 'increasing' WindCount (WC) away from zero + //so we're inside the previous polygon ... + if (edge.WindDelta == 0) + edge.WindCnt = (e->WindCnt < 0 ? e->WindCnt - 1 : e->WindCnt + 1); + //if wind direction is reversing prev then use same WC + else if (e->WindDelta * edge.WindDelta < 0) edge.WindCnt = e->WindCnt; + //otherwise add to WC ... + else edge.WindCnt = e->WindCnt + edge.WindDelta; + } + edge.WindCnt2 = e->WindCnt2; + e = e->NextInAEL; //ie get ready to calc WindCnt2 + } + + //update WindCnt2 ... + if (IsEvenOddAltFillType(edge)) + { + //EvenOdd filling ... + while (e != &edge) + { + if (e->WindDelta != 0) + edge.WindCnt2 = (edge.WindCnt2 == 0 ? 1 : 0); + e = e->NextInAEL; + } + } else + { + //nonZero, Positive or Negative filling ... + while ( e != &edge ) + { + edge.WindCnt2 += e->WindDelta; + e = e->NextInAEL; + } + } +} +//------------------------------------------------------------------------------ + +bool Clipper::IsEvenOddFillType(const TEdge& edge) const +{ + if (edge.PolyTyp == ptSubject) + return m_SubjFillType == pftEvenOdd; else + return m_ClipFillType == pftEvenOdd; +} +//------------------------------------------------------------------------------ + +bool Clipper::IsEvenOddAltFillType(const TEdge& edge) const +{ + if (edge.PolyTyp == ptSubject) + return m_ClipFillType == pftEvenOdd; else + return m_SubjFillType == pftEvenOdd; +} +//------------------------------------------------------------------------------ + +bool Clipper::IsContributing(const TEdge& edge) const +{ + PolyFillType pft, pft2; + if (edge.PolyTyp == ptSubject) + { + pft = m_SubjFillType; + pft2 = m_ClipFillType; + } else + { + pft = m_ClipFillType; + pft2 = m_SubjFillType; + } + + switch(pft) + { + case pftEvenOdd: + //return false if a subj line has been flagged as inside a subj polygon + if (edge.WindDelta == 0 && edge.WindCnt != 1) return false; + break; + case pftNonZero: + if (Abs(edge.WindCnt) != 1) return false; + break; + case pftPositive: + if (edge.WindCnt != 1) return false; + break; + default: //pftNegative + if (edge.WindCnt != -1) return false; + } + + switch(m_ClipType) + { + case ctIntersection: + switch(pft2) + { + case pftEvenOdd: + case pftNonZero: + return (edge.WindCnt2 != 0); + case pftPositive: + return (edge.WindCnt2 > 0); + default: + return (edge.WindCnt2 < 0); + } + break; + case ctUnion: + switch(pft2) + { + case pftEvenOdd: + case pftNonZero: + return (edge.WindCnt2 == 0); + case pftPositive: + return (edge.WindCnt2 <= 0); + default: + return (edge.WindCnt2 >= 0); + } + break; + case ctDifference: + if (edge.PolyTyp == ptSubject) + switch(pft2) + { + case pftEvenOdd: + case pftNonZero: + return (edge.WindCnt2 == 0); + case pftPositive: + return (edge.WindCnt2 <= 0); + default: + return (edge.WindCnt2 >= 0); + } + else + switch(pft2) + { + case pftEvenOdd: + case pftNonZero: + return (edge.WindCnt2 != 0); + case pftPositive: + return (edge.WindCnt2 > 0); + default: + return (edge.WindCnt2 < 0); + } + break; + case ctXor: + if (edge.WindDelta == 0) //XOr always contributing unless open + switch(pft2) + { + case pftEvenOdd: + case pftNonZero: + return (edge.WindCnt2 == 0); + case pftPositive: + return (edge.WindCnt2 <= 0); + default: + return (edge.WindCnt2 >= 0); + } + else + return true; + break; + default: + return true; + } +} +//------------------------------------------------------------------------------ + +OutPt* Clipper::AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &Pt) +{ + OutPt* result; + TEdge *e, *prevE; + if (IsHorizontal(*e2) || ( e1->Dx > e2->Dx )) + { + result = AddOutPt(e1, Pt); + e2->OutIdx = e1->OutIdx; + e1->Side = esLeft; + e2->Side = esRight; + e = e1; + if (e->PrevInAEL == e2) + prevE = e2->PrevInAEL; + else + prevE = e->PrevInAEL; + } else + { + result = AddOutPt(e2, Pt); + e1->OutIdx = e2->OutIdx; + e1->Side = esRight; + e2->Side = esLeft; + e = e2; + if (e->PrevInAEL == e1) + prevE = e1->PrevInAEL; + else + prevE = e->PrevInAEL; + } + + if (prevE && prevE->OutIdx >= 0 && prevE->Top.Y < Pt.Y && e->Top.Y < Pt.Y) + { + cInt xPrev = TopX(*prevE, Pt.Y); + cInt xE = TopX(*e, Pt.Y); + if (xPrev == xE && (e->WindDelta != 0) && (prevE->WindDelta != 0) && + SlopesEqual(IntPoint(xPrev, Pt.Y), prevE->Top, IntPoint(xE, Pt.Y), e->Top, m_UseFullRange)) + { + OutPt* outPt = AddOutPt(prevE, Pt); + AddJoin(result, outPt, e->Top); + } + } + return result; +} +//------------------------------------------------------------------------------ + +void Clipper::AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &Pt) +{ + AddOutPt( e1, Pt ); + if (e2->WindDelta == 0) AddOutPt(e2, Pt); + if( e1->OutIdx == e2->OutIdx ) + { + e1->OutIdx = Unassigned; + e2->OutIdx = Unassigned; + } + else if (e1->OutIdx < e2->OutIdx) + AppendPolygon(e1, e2); + else + AppendPolygon(e2, e1); +} +//------------------------------------------------------------------------------ + +void Clipper::AddEdgeToSEL(TEdge *edge) +{ + //SEL pointers in PEdge are reused to build a list of horizontal edges. + //However, we don't need to worry about order with horizontal edge processing. + if( !m_SortedEdges ) + { + m_SortedEdges = edge; + edge->PrevInSEL = 0; + edge->NextInSEL = 0; + } + else + { + edge->NextInSEL = m_SortedEdges; + edge->PrevInSEL = 0; + m_SortedEdges->PrevInSEL = edge; + m_SortedEdges = edge; + } +} +//------------------------------------------------------------------------------ + +bool Clipper::PopEdgeFromSEL(TEdge *&edge) +{ + if (!m_SortedEdges) return false; + edge = m_SortedEdges; + DeleteFromSEL(m_SortedEdges); + return true; +} +//------------------------------------------------------------------------------ + +void Clipper::CopyAELToSEL() +{ + TEdge* e = m_ActiveEdges; + m_SortedEdges = e; + while ( e ) + { + e->PrevInSEL = e->PrevInAEL; + e->NextInSEL = e->NextInAEL; + e = e->NextInAEL; + } +} +//------------------------------------------------------------------------------ + +void Clipper::AddJoin(OutPt *op1, OutPt *op2, const IntPoint OffPt) +{ + Join* j = new Join; + j->OutPt1 = op1; + j->OutPt2 = op2; + j->OffPt = OffPt; + m_Joins.push_back(j); +} +//------------------------------------------------------------------------------ + +void Clipper::ClearJoins() +{ + for (JoinList::size_type i = 0; i < m_Joins.size(); i++) + delete m_Joins[i]; + m_Joins.resize(0); +} +//------------------------------------------------------------------------------ + +void Clipper::ClearGhostJoins() +{ + for (JoinList::size_type i = 0; i < m_GhostJoins.size(); i++) + delete m_GhostJoins[i]; + m_GhostJoins.resize(0); +} +//------------------------------------------------------------------------------ + +void Clipper::AddGhostJoin(OutPt *op, const IntPoint OffPt) +{ + Join* j = new Join; + j->OutPt1 = op; + j->OutPt2 = 0; + j->OffPt = OffPt; + m_GhostJoins.push_back(j); +} +//------------------------------------------------------------------------------ + +void Clipper::InsertLocalMinimaIntoAEL(const cInt botY) +{ + const LocalMinimum *lm; + while (PopLocalMinima(botY, lm)) + { + TEdge* lb = lm->LeftBound; + TEdge* rb = lm->RightBound; + + OutPt *Op1 = 0; + if (!lb) + { + //nb: don't insert LB into either AEL or SEL + InsertEdgeIntoAEL(rb, 0); + SetWindingCount(*rb); + if (IsContributing(*rb)) + Op1 = AddOutPt(rb, rb->Bot); + } + else if (!rb) + { + InsertEdgeIntoAEL(lb, 0); + SetWindingCount(*lb); + if (IsContributing(*lb)) + Op1 = AddOutPt(lb, lb->Bot); + InsertScanbeam(lb->Top.Y); + } + else + { + InsertEdgeIntoAEL(lb, 0); + InsertEdgeIntoAEL(rb, lb); + SetWindingCount( *lb ); + rb->WindCnt = lb->WindCnt; + rb->WindCnt2 = lb->WindCnt2; + if (IsContributing(*lb)) + Op1 = AddLocalMinPoly(lb, rb, lb->Bot); + InsertScanbeam(lb->Top.Y); + } + + if (rb) + { + if (IsHorizontal(*rb)) + { + AddEdgeToSEL(rb); + if (rb->NextInLML) + InsertScanbeam(rb->NextInLML->Top.Y); + } + else InsertScanbeam( rb->Top.Y ); + } + + if (!lb || !rb) continue; + + //if any output polygons share an edge, they'll need joining later ... + if (Op1 && IsHorizontal(*rb) && + m_GhostJoins.size() > 0 && (rb->WindDelta != 0)) + { + for (JoinList::size_type i = 0; i < m_GhostJoins.size(); ++i) + { + Join* jr = m_GhostJoins[i]; + //if the horizontal Rb and a 'ghost' horizontal overlap, then convert + //the 'ghost' join to a real join ready for later ... + if (HorzSegmentsOverlap(jr->OutPt1->Pt.X, jr->OffPt.X, rb->Bot.X, rb->Top.X)) + AddJoin(jr->OutPt1, Op1, jr->OffPt); + } + } + + if (lb->OutIdx >= 0 && lb->PrevInAEL && + lb->PrevInAEL->Curr.X == lb->Bot.X && + lb->PrevInAEL->OutIdx >= 0 && + SlopesEqual(lb->PrevInAEL->Bot, lb->PrevInAEL->Top, lb->Curr, lb->Top, m_UseFullRange) && + (lb->WindDelta != 0) && (lb->PrevInAEL->WindDelta != 0)) + { + OutPt *Op2 = AddOutPt(lb->PrevInAEL, lb->Bot); + AddJoin(Op1, Op2, lb->Top); + } + + if(lb->NextInAEL != rb) + { + + if (rb->OutIdx >= 0 && rb->PrevInAEL->OutIdx >= 0 && + SlopesEqual(rb->PrevInAEL->Curr, rb->PrevInAEL->Top, rb->Curr, rb->Top, m_UseFullRange) && + (rb->WindDelta != 0) && (rb->PrevInAEL->WindDelta != 0)) + { + OutPt *Op2 = AddOutPt(rb->PrevInAEL, rb->Bot); + AddJoin(Op1, Op2, rb->Top); + } + + TEdge* e = lb->NextInAEL; + if (e) + { + while( e != rb ) + { + //nb: For calculating winding counts etc, IntersectEdges() assumes + //that param1 will be to the Right of param2 ABOVE the intersection ... + IntersectEdges(rb , e , lb->Curr); //order important here + e = e->NextInAEL; + } + } + } + + } +} +//------------------------------------------------------------------------------ + +void Clipper::DeleteFromSEL(TEdge *e) +{ + TEdge* SelPrev = e->PrevInSEL; + TEdge* SelNext = e->NextInSEL; + if( !SelPrev && !SelNext && (e != m_SortedEdges) ) return; //already deleted + if( SelPrev ) SelPrev->NextInSEL = SelNext; + else m_SortedEdges = SelNext; + if( SelNext ) SelNext->PrevInSEL = SelPrev; + e->NextInSEL = 0; + e->PrevInSEL = 0; +} +//------------------------------------------------------------------------------ + +#ifdef use_xyz +void Clipper::SetZ(IntPoint& pt, TEdge& e1, TEdge& e2) +{ + if (pt.Z != 0 || !m_ZFill) return; + else if (pt == e1.Bot) pt.Z = e1.Bot.Z; + else if (pt == e1.Top) pt.Z = e1.Top.Z; + else if (pt == e2.Bot) pt.Z = e2.Bot.Z; + else if (pt == e2.Top) pt.Z = e2.Top.Z; + else (*m_ZFill)(e1.Bot, e1.Top, e2.Bot, e2.Top, pt); +} +//------------------------------------------------------------------------------ +#endif + +void Clipper::IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &Pt) +{ + bool e1Contributing = ( e1->OutIdx >= 0 ); + bool e2Contributing = ( e2->OutIdx >= 0 ); + +#ifdef use_xyz + SetZ(Pt, *e1, *e2); +#endif + +#ifdef use_lines + //if either edge is on an OPEN path ... + if (e1->WindDelta == 0 || e2->WindDelta == 0) + { + //ignore subject-subject open path intersections UNLESS they + //are both open paths, AND they are both 'contributing maximas' ... + if (e1->WindDelta == 0 && e2->WindDelta == 0) return; + + //if intersecting a subj line with a subj poly ... + else if (e1->PolyTyp == e2->PolyTyp && + e1->WindDelta != e2->WindDelta && m_ClipType == ctUnion) + { + if (e1->WindDelta == 0) + { + if (e2Contributing) + { + AddOutPt(e1, Pt); + if (e1Contributing) e1->OutIdx = Unassigned; + } + } + else + { + if (e1Contributing) + { + AddOutPt(e2, Pt); + if (e2Contributing) e2->OutIdx = Unassigned; + } + } + } + else if (e1->PolyTyp != e2->PolyTyp) + { + //toggle subj open path OutIdx on/off when Abs(clip.WndCnt) == 1 ... + if ((e1->WindDelta == 0) && abs(e2->WindCnt) == 1 && + (m_ClipType != ctUnion || e2->WindCnt2 == 0)) + { + AddOutPt(e1, Pt); + if (e1Contributing) e1->OutIdx = Unassigned; + } + else if ((e2->WindDelta == 0) && (abs(e1->WindCnt) == 1) && + (m_ClipType != ctUnion || e1->WindCnt2 == 0)) + { + AddOutPt(e2, Pt); + if (e2Contributing) e2->OutIdx = Unassigned; + } + } + return; + } +#endif + + //update winding counts... + //assumes that e1 will be to the Right of e2 ABOVE the intersection + if ( e1->PolyTyp == e2->PolyTyp ) + { + if ( IsEvenOddFillType( *e1) ) + { + int oldE1WindCnt = e1->WindCnt; + e1->WindCnt = e2->WindCnt; + e2->WindCnt = oldE1WindCnt; + } else + { + if (e1->WindCnt + e2->WindDelta == 0 ) e1->WindCnt = -e1->WindCnt; + else e1->WindCnt += e2->WindDelta; + if ( e2->WindCnt - e1->WindDelta == 0 ) e2->WindCnt = -e2->WindCnt; + else e2->WindCnt -= e1->WindDelta; + } + } else + { + if (!IsEvenOddFillType(*e2)) e1->WindCnt2 += e2->WindDelta; + else e1->WindCnt2 = ( e1->WindCnt2 == 0 ) ? 1 : 0; + if (!IsEvenOddFillType(*e1)) e2->WindCnt2 -= e1->WindDelta; + else e2->WindCnt2 = ( e2->WindCnt2 == 0 ) ? 1 : 0; + } + + PolyFillType e1FillType, e2FillType, e1FillType2, e2FillType2; + if (e1->PolyTyp == ptSubject) + { + e1FillType = m_SubjFillType; + e1FillType2 = m_ClipFillType; + } else + { + e1FillType = m_ClipFillType; + e1FillType2 = m_SubjFillType; + } + if (e2->PolyTyp == ptSubject) + { + e2FillType = m_SubjFillType; + e2FillType2 = m_ClipFillType; + } else + { + e2FillType = m_ClipFillType; + e2FillType2 = m_SubjFillType; + } + + cInt e1Wc, e2Wc; + switch (e1FillType) + { + case pftPositive: e1Wc = e1->WindCnt; break; + case pftNegative: e1Wc = -e1->WindCnt; break; + default: e1Wc = Abs(e1->WindCnt); + } + switch(e2FillType) + { + case pftPositive: e2Wc = e2->WindCnt; break; + case pftNegative: e2Wc = -e2->WindCnt; break; + default: e2Wc = Abs(e2->WindCnt); + } + + if ( e1Contributing && e2Contributing ) + { + if ((e1Wc != 0 && e1Wc != 1) || (e2Wc != 0 && e2Wc != 1) || + (e1->PolyTyp != e2->PolyTyp && m_ClipType != ctXor) ) + { + AddLocalMaxPoly(e1, e2, Pt); + } + else + { + AddOutPt(e1, Pt); + AddOutPt(e2, Pt); + SwapSides( *e1 , *e2 ); + SwapPolyIndexes( *e1 , *e2 ); + } + } + else if ( e1Contributing ) + { + if (e2Wc == 0 || e2Wc == 1) + { + AddOutPt(e1, Pt); + SwapSides(*e1, *e2); + SwapPolyIndexes(*e1, *e2); + } + } + else if ( e2Contributing ) + { + if (e1Wc == 0 || e1Wc == 1) + { + AddOutPt(e2, Pt); + SwapSides(*e1, *e2); + SwapPolyIndexes(*e1, *e2); + } + } + else if ( (e1Wc == 0 || e1Wc == 1) && (e2Wc == 0 || e2Wc == 1)) + { + //neither edge is currently contributing ... + + cInt e1Wc2, e2Wc2; + switch (e1FillType2) + { + case pftPositive: e1Wc2 = e1->WindCnt2; break; + case pftNegative : e1Wc2 = -e1->WindCnt2; break; + default: e1Wc2 = Abs(e1->WindCnt2); + } + switch (e2FillType2) + { + case pftPositive: e2Wc2 = e2->WindCnt2; break; + case pftNegative: e2Wc2 = -e2->WindCnt2; break; + default: e2Wc2 = Abs(e2->WindCnt2); + } + + if (e1->PolyTyp != e2->PolyTyp) + { + AddLocalMinPoly(e1, e2, Pt); + } + else if (e1Wc == 1 && e2Wc == 1) + switch( m_ClipType ) { + case ctIntersection: + if (e1Wc2 > 0 && e2Wc2 > 0) + AddLocalMinPoly(e1, e2, Pt); + break; + case ctUnion: + if ( e1Wc2 <= 0 && e2Wc2 <= 0 ) + AddLocalMinPoly(e1, e2, Pt); + break; + case ctDifference: + if (((e1->PolyTyp == ptClip) && (e1Wc2 > 0) && (e2Wc2 > 0)) || + ((e1->PolyTyp == ptSubject) && (e1Wc2 <= 0) && (e2Wc2 <= 0))) + AddLocalMinPoly(e1, e2, Pt); + break; + case ctXor: + AddLocalMinPoly(e1, e2, Pt); + } + else + SwapSides( *e1, *e2 ); + } +} +//------------------------------------------------------------------------------ + +void Clipper::SetHoleState(TEdge *e, OutRec *outrec) +{ + TEdge *e2 = e->PrevInAEL; + TEdge *eTmp = 0; + while (e2) + { + if (e2->OutIdx >= 0 && e2->WindDelta != 0) + { + if (!eTmp) eTmp = e2; + else if (eTmp->OutIdx == e2->OutIdx) eTmp = 0; + } + e2 = e2->PrevInAEL; + } + if (!eTmp) + { + outrec->FirstLeft = 0; + outrec->IsHole = false; + } + else + { + outrec->FirstLeft = m_PolyOuts[eTmp->OutIdx]; + outrec->IsHole = !outrec->FirstLeft->IsHole; + } +} +//------------------------------------------------------------------------------ + +OutRec* GetLowermostRec(OutRec *outRec1, OutRec *outRec2) +{ + //work out which polygon fragment has the correct hole state ... + if (!outRec1->BottomPt) + outRec1->BottomPt = GetBottomPt(outRec1->Pts); + if (!outRec2->BottomPt) + outRec2->BottomPt = GetBottomPt(outRec2->Pts); + OutPt *OutPt1 = outRec1->BottomPt; + OutPt *OutPt2 = outRec2->BottomPt; + if (OutPt1->Pt.Y > OutPt2->Pt.Y) return outRec1; + else if (OutPt1->Pt.Y < OutPt2->Pt.Y) return outRec2; + else if (OutPt1->Pt.X < OutPt2->Pt.X) return outRec1; + else if (OutPt1->Pt.X > OutPt2->Pt.X) return outRec2; + else if (OutPt1->Next == OutPt1) return outRec2; + else if (OutPt2->Next == OutPt2) return outRec1; + else if (FirstIsBottomPt(OutPt1, OutPt2)) return outRec1; + else return outRec2; +} +//------------------------------------------------------------------------------ + +bool OutRec1RightOfOutRec2(OutRec* outRec1, OutRec* outRec2) +{ + do + { + outRec1 = outRec1->FirstLeft; + if (outRec1 == outRec2) return true; + } while (outRec1); + return false; +} +//------------------------------------------------------------------------------ + +OutRec* Clipper::GetOutRec(int Idx) +{ + OutRec* outrec = m_PolyOuts[Idx]; + while (outrec != m_PolyOuts[outrec->Idx]) + outrec = m_PolyOuts[outrec->Idx]; + return outrec; +} +//------------------------------------------------------------------------------ + +void Clipper::AppendPolygon(TEdge *e1, TEdge *e2) +{ + //get the start and ends of both output polygons ... + OutRec *outRec1 = m_PolyOuts[e1->OutIdx]; + OutRec *outRec2 = m_PolyOuts[e2->OutIdx]; + + OutRec *holeStateRec; + if (OutRec1RightOfOutRec2(outRec1, outRec2)) + holeStateRec = outRec2; + else if (OutRec1RightOfOutRec2(outRec2, outRec1)) + holeStateRec = outRec1; + else + holeStateRec = GetLowermostRec(outRec1, outRec2); + + //get the start and ends of both output polygons and + //join e2 poly onto e1 poly and delete pointers to e2 ... + + OutPt* p1_lft = outRec1->Pts; + OutPt* p1_rt = p1_lft->Prev; + OutPt* p2_lft = outRec2->Pts; + OutPt* p2_rt = p2_lft->Prev; + + //join e2 poly onto e1 poly and delete pointers to e2 ... + if( e1->Side == esLeft ) + { + if( e2->Side == esLeft ) + { + //z y x a b c + ReversePolyPtLinks(p2_lft); + p2_lft->Next = p1_lft; + p1_lft->Prev = p2_lft; + p1_rt->Next = p2_rt; + p2_rt->Prev = p1_rt; + outRec1->Pts = p2_rt; + } else + { + //x y z a b c + p2_rt->Next = p1_lft; + p1_lft->Prev = p2_rt; + p2_lft->Prev = p1_rt; + p1_rt->Next = p2_lft; + outRec1->Pts = p2_lft; + } + } else + { + if( e2->Side == esRight ) + { + //a b c z y x + ReversePolyPtLinks(p2_lft); + p1_rt->Next = p2_rt; + p2_rt->Prev = p1_rt; + p2_lft->Next = p1_lft; + p1_lft->Prev = p2_lft; + } else + { + //a b c x y z + p1_rt->Next = p2_lft; + p2_lft->Prev = p1_rt; + p1_lft->Prev = p2_rt; + p2_rt->Next = p1_lft; + } + } + + outRec1->BottomPt = 0; + if (holeStateRec == outRec2) + { + if (outRec2->FirstLeft != outRec1) + outRec1->FirstLeft = outRec2->FirstLeft; + outRec1->IsHole = outRec2->IsHole; + } + outRec2->Pts = 0; + outRec2->BottomPt = 0; + outRec2->FirstLeft = outRec1; + + int OKIdx = e1->OutIdx; + int ObsoleteIdx = e2->OutIdx; + + e1->OutIdx = Unassigned; //nb: safe because we only get here via AddLocalMaxPoly + e2->OutIdx = Unassigned; + + TEdge* e = m_ActiveEdges; + while( e ) + { + if( e->OutIdx == ObsoleteIdx ) + { + e->OutIdx = OKIdx; + e->Side = e1->Side; + break; + } + e = e->NextInAEL; + } + + outRec2->Idx = outRec1->Idx; +} +//------------------------------------------------------------------------------ + +OutPt* Clipper::AddOutPt(TEdge *e, const IntPoint &pt) +{ + if( e->OutIdx < 0 ) + { + OutRec *outRec = CreateOutRec(); + outRec->IsOpen = (e->WindDelta == 0); + OutPt* newOp = new OutPt; + outRec->Pts = newOp; + newOp->Idx = outRec->Idx; + newOp->Pt = pt; + newOp->Next = newOp; + newOp->Prev = newOp; + if (!outRec->IsOpen) + SetHoleState(e, outRec); + e->OutIdx = outRec->Idx; + return newOp; + } else + { + OutRec *outRec = m_PolyOuts[e->OutIdx]; + //OutRec.Pts is the 'Left-most' point & OutRec.Pts.Prev is the 'Right-most' + OutPt* op = outRec->Pts; + + bool ToFront = (e->Side == esLeft); + if (ToFront && (pt == op->Pt)) return op; + else if (!ToFront && (pt == op->Prev->Pt)) return op->Prev; + + OutPt* newOp = new OutPt; + newOp->Idx = outRec->Idx; + newOp->Pt = pt; + newOp->Next = op; + newOp->Prev = op->Prev; + newOp->Prev->Next = newOp; + op->Prev = newOp; + if (ToFront) outRec->Pts = newOp; + return newOp; + } +} +//------------------------------------------------------------------------------ + +OutPt* Clipper::GetLastOutPt(TEdge *e) +{ + OutRec *outRec = m_PolyOuts[e->OutIdx]; + if (e->Side == esLeft) + return outRec->Pts; + else + return outRec->Pts->Prev; +} +//------------------------------------------------------------------------------ + +void Clipper::ProcessHorizontals() +{ + TEdge* horzEdge; + while (PopEdgeFromSEL(horzEdge)) + ProcessHorizontal(horzEdge); +} +//------------------------------------------------------------------------------ + +inline bool IsMinima(TEdge *e) +{ + return e && (e->Prev->NextInLML != e) && (e->Next->NextInLML != e); +} +//------------------------------------------------------------------------------ + +inline bool IsMaxima(TEdge *e, const cInt Y) +{ + return e && e->Top.Y == Y && !e->NextInLML; +} +//------------------------------------------------------------------------------ + +inline bool IsIntermediate(TEdge *e, const cInt Y) +{ + return e->Top.Y == Y && e->NextInLML; +} +//------------------------------------------------------------------------------ + +TEdge *GetMaximaPair(TEdge *e) +{ + if ((e->Next->Top == e->Top) && !e->Next->NextInLML) + return e->Next; + else if ((e->Prev->Top == e->Top) && !e->Prev->NextInLML) + return e->Prev; + else return 0; +} +//------------------------------------------------------------------------------ + +TEdge *GetMaximaPairEx(TEdge *e) +{ + //as GetMaximaPair() but returns 0 if MaxPair isn't in AEL (unless it's horizontal) + TEdge* result = GetMaximaPair(e); + if (result && (result->OutIdx == Skip || + (result->NextInAEL == result->PrevInAEL && !IsHorizontal(*result)))) return 0; + return result; +} +//------------------------------------------------------------------------------ + +void Clipper::SwapPositionsInSEL(TEdge *Edge1, TEdge *Edge2) +{ + if( !( Edge1->NextInSEL ) && !( Edge1->PrevInSEL ) ) return; + if( !( Edge2->NextInSEL ) && !( Edge2->PrevInSEL ) ) return; + + if( Edge1->NextInSEL == Edge2 ) + { + TEdge* Next = Edge2->NextInSEL; + if( Next ) Next->PrevInSEL = Edge1; + TEdge* Prev = Edge1->PrevInSEL; + if( Prev ) Prev->NextInSEL = Edge2; + Edge2->PrevInSEL = Prev; + Edge2->NextInSEL = Edge1; + Edge1->PrevInSEL = Edge2; + Edge1->NextInSEL = Next; + } + else if( Edge2->NextInSEL == Edge1 ) + { + TEdge* Next = Edge1->NextInSEL; + if( Next ) Next->PrevInSEL = Edge2; + TEdge* Prev = Edge2->PrevInSEL; + if( Prev ) Prev->NextInSEL = Edge1; + Edge1->PrevInSEL = Prev; + Edge1->NextInSEL = Edge2; + Edge2->PrevInSEL = Edge1; + Edge2->NextInSEL = Next; + } + else + { + TEdge* Next = Edge1->NextInSEL; + TEdge* Prev = Edge1->PrevInSEL; + Edge1->NextInSEL = Edge2->NextInSEL; + if( Edge1->NextInSEL ) Edge1->NextInSEL->PrevInSEL = Edge1; + Edge1->PrevInSEL = Edge2->PrevInSEL; + if( Edge1->PrevInSEL ) Edge1->PrevInSEL->NextInSEL = Edge1; + Edge2->NextInSEL = Next; + if( Edge2->NextInSEL ) Edge2->NextInSEL->PrevInSEL = Edge2; + Edge2->PrevInSEL = Prev; + if( Edge2->PrevInSEL ) Edge2->PrevInSEL->NextInSEL = Edge2; + } + + if( !Edge1->PrevInSEL ) m_SortedEdges = Edge1; + else if( !Edge2->PrevInSEL ) m_SortedEdges = Edge2; +} +//------------------------------------------------------------------------------ + +TEdge* GetNextInAEL(TEdge *e, Direction dir) +{ + return dir == dLeftToRight ? e->NextInAEL : e->PrevInAEL; +} +//------------------------------------------------------------------------------ + +void GetHorzDirection(TEdge& HorzEdge, Direction& Dir, cInt& Left, cInt& Right) +{ + if (HorzEdge.Bot.X < HorzEdge.Top.X) + { + Left = HorzEdge.Bot.X; + Right = HorzEdge.Top.X; + Dir = dLeftToRight; + } else + { + Left = HorzEdge.Top.X; + Right = HorzEdge.Bot.X; + Dir = dRightToLeft; + } +} +//------------------------------------------------------------------------ + +/******************************************************************************* +* Notes: Horizontal edges (HEs) at scanline intersections (ie at the Top or * +* Bottom of a scanbeam) are processed as if layered. The order in which HEs * +* are processed doesn't matter. HEs intersect with other HE Bot.Xs only [#] * +* (or they could intersect with Top.Xs only, ie EITHER Bot.Xs OR Top.Xs), * +* and with other non-horizontal edges [*]. Once these intersections are * +* processed, intermediate HEs then 'promote' the Edge above (NextInLML) into * +* the AEL. These 'promoted' edges may in turn intersect [%] with other HEs. * +*******************************************************************************/ + +void Clipper::ProcessHorizontal(TEdge *horzEdge) +{ + Direction dir; + cInt horzLeft, horzRight; + bool IsOpen = (horzEdge->WindDelta == 0); + + GetHorzDirection(*horzEdge, dir, horzLeft, horzRight); + + TEdge* eLastHorz = horzEdge, *eMaxPair = 0; + while (eLastHorz->NextInLML && IsHorizontal(*eLastHorz->NextInLML)) + eLastHorz = eLastHorz->NextInLML; + if (!eLastHorz->NextInLML) + eMaxPair = GetMaximaPair(eLastHorz); + + MaximaList::const_iterator maxIt; + MaximaList::const_reverse_iterator maxRit; + if (m_Maxima.size() > 0) + { + //get the first maxima in range (X) ... + if (dir == dLeftToRight) + { + maxIt = m_Maxima.begin(); + while (maxIt != m_Maxima.end() && *maxIt <= horzEdge->Bot.X) maxIt++; + if (maxIt != m_Maxima.end() && *maxIt >= eLastHorz->Top.X) + maxIt = m_Maxima.end(); + } + else + { + maxRit = m_Maxima.rbegin(); + while (maxRit != m_Maxima.rend() && *maxRit > horzEdge->Bot.X) maxRit++; + if (maxRit != m_Maxima.rend() && *maxRit <= eLastHorz->Top.X) + maxRit = m_Maxima.rend(); + } + } + + OutPt* op1 = 0; + + for (;;) //loop through consec. horizontal edges + { + + bool IsLastHorz = (horzEdge == eLastHorz); + TEdge* e = GetNextInAEL(horzEdge, dir); + while(e) + { + + //this code block inserts extra coords into horizontal edges (in output + //polygons) whereever maxima touch these horizontal edges. This helps + //'simplifying' polygons (ie if the Simplify property is set). + if (m_Maxima.size() > 0) + { + if (dir == dLeftToRight) + { + while (maxIt != m_Maxima.end() && *maxIt < e->Curr.X) + { + if (horzEdge->OutIdx >= 0 && !IsOpen) + AddOutPt(horzEdge, IntPoint(*maxIt, horzEdge->Bot.Y)); + maxIt++; + } + } + else + { + while (maxRit != m_Maxima.rend() && *maxRit > e->Curr.X) + { + if (horzEdge->OutIdx >= 0 && !IsOpen) + AddOutPt(horzEdge, IntPoint(*maxRit, horzEdge->Bot.Y)); + maxRit++; + } + } + }; + + if ((dir == dLeftToRight && e->Curr.X > horzRight) || + (dir == dRightToLeft && e->Curr.X < horzLeft)) break; + + //Also break if we've got to the end of an intermediate horizontal edge ... + //nb: Smaller Dx's are to the right of larger Dx's ABOVE the horizontal. + if (e->Curr.X == horzEdge->Top.X && horzEdge->NextInLML && + e->Dx < horzEdge->NextInLML->Dx) break; + + if (horzEdge->OutIdx >= 0 && !IsOpen) //note: may be done multiple times + { +#ifdef use_xyz + if (dir == dLeftToRight) SetZ(e->Curr, *horzEdge, *e); + else SetZ(e->Curr, *e, *horzEdge); +#endif + op1 = AddOutPt(horzEdge, e->Curr); + TEdge* eNextHorz = m_SortedEdges; + while (eNextHorz) + { + if (eNextHorz->OutIdx >= 0 && + HorzSegmentsOverlap(horzEdge->Bot.X, + horzEdge->Top.X, eNextHorz->Bot.X, eNextHorz->Top.X)) + { + OutPt* op2 = GetLastOutPt(eNextHorz); + AddJoin(op2, op1, eNextHorz->Top); + } + eNextHorz = eNextHorz->NextInSEL; + } + AddGhostJoin(op1, horzEdge->Bot); + } + + //OK, so far we're still in range of the horizontal Edge but make sure + //we're at the last of consec. horizontals when matching with eMaxPair + if(e == eMaxPair && IsLastHorz) + { + if (horzEdge->OutIdx >= 0) + AddLocalMaxPoly(horzEdge, eMaxPair, horzEdge->Top); + DeleteFromAEL(horzEdge); + DeleteFromAEL(eMaxPair); + return; + } + + if(dir == dLeftToRight) + { + IntPoint Pt = IntPoint(e->Curr.X, horzEdge->Curr.Y); + IntersectEdges(horzEdge, e, Pt); + } + else + { + IntPoint Pt = IntPoint(e->Curr.X, horzEdge->Curr.Y); + IntersectEdges( e, horzEdge, Pt); + } + TEdge* eNext = GetNextInAEL(e, dir); + SwapPositionsInAEL( horzEdge, e ); + e = eNext; + } //end while(e) + + //Break out of loop if HorzEdge.NextInLML is not also horizontal ... + if (!horzEdge->NextInLML || !IsHorizontal(*horzEdge->NextInLML)) break; + + UpdateEdgeIntoAEL(horzEdge); + if (horzEdge->OutIdx >= 0) AddOutPt(horzEdge, horzEdge->Bot); + GetHorzDirection(*horzEdge, dir, horzLeft, horzRight); + + } //end for (;;) + + if (horzEdge->OutIdx >= 0 && !op1) + { + op1 = GetLastOutPt(horzEdge); + TEdge* eNextHorz = m_SortedEdges; + while (eNextHorz) + { + if (eNextHorz->OutIdx >= 0 && + HorzSegmentsOverlap(horzEdge->Bot.X, + horzEdge->Top.X, eNextHorz->Bot.X, eNextHorz->Top.X)) + { + OutPt* op2 = GetLastOutPt(eNextHorz); + AddJoin(op2, op1, eNextHorz->Top); + } + eNextHorz = eNextHorz->NextInSEL; + } + AddGhostJoin(op1, horzEdge->Top); + } + + if (horzEdge->NextInLML) + { + if(horzEdge->OutIdx >= 0) + { + op1 = AddOutPt( horzEdge, horzEdge->Top); + UpdateEdgeIntoAEL(horzEdge); + if (horzEdge->WindDelta == 0) return; + //nb: HorzEdge is no longer horizontal here + TEdge* ePrev = horzEdge->PrevInAEL; + TEdge* eNext = horzEdge->NextInAEL; + if (ePrev && ePrev->Curr.X == horzEdge->Bot.X && + ePrev->Curr.Y == horzEdge->Bot.Y && ePrev->WindDelta != 0 && + (ePrev->OutIdx >= 0 && ePrev->Curr.Y > ePrev->Top.Y && + SlopesEqual(*horzEdge, *ePrev, m_UseFullRange))) + { + OutPt* op2 = AddOutPt(ePrev, horzEdge->Bot); + AddJoin(op1, op2, horzEdge->Top); + } + else if (eNext && eNext->Curr.X == horzEdge->Bot.X && + eNext->Curr.Y == horzEdge->Bot.Y && eNext->WindDelta != 0 && + eNext->OutIdx >= 0 && eNext->Curr.Y > eNext->Top.Y && + SlopesEqual(*horzEdge, *eNext, m_UseFullRange)) + { + OutPt* op2 = AddOutPt(eNext, horzEdge->Bot); + AddJoin(op1, op2, horzEdge->Top); + } + } + else + UpdateEdgeIntoAEL(horzEdge); + } + else + { + if (horzEdge->OutIdx >= 0) AddOutPt(horzEdge, horzEdge->Top); + DeleteFromAEL(horzEdge); + } +} +//------------------------------------------------------------------------------ + +bool Clipper::ProcessIntersections(const cInt topY) +{ + if( !m_ActiveEdges ) return true; + try { + BuildIntersectList(topY); + size_t IlSize = m_IntersectList.size(); + if (IlSize == 0) return true; + if (IlSize == 1 || FixupIntersectionOrder()) ProcessIntersectList(); + else return false; + } + catch(...) + { + m_SortedEdges = 0; + DisposeIntersectNodes(); + throw clipperException("ProcessIntersections error"); + } + m_SortedEdges = 0; + return true; +} +//------------------------------------------------------------------------------ + +void Clipper::DisposeIntersectNodes() +{ + for (size_t i = 0; i < m_IntersectList.size(); ++i ) + delete m_IntersectList[i]; + m_IntersectList.clear(); +} +//------------------------------------------------------------------------------ + +void Clipper::BuildIntersectList(const cInt topY) +{ + if ( !m_ActiveEdges ) return; + + //prepare for sorting ... + TEdge* e = m_ActiveEdges; + m_SortedEdges = e; + while( e ) + { + e->PrevInSEL = e->PrevInAEL; + e->NextInSEL = e->NextInAEL; + e->Curr.X = TopX( *e, topY ); + e = e->NextInAEL; + } + + //bubblesort ... + bool isModified; + do + { + isModified = false; + e = m_SortedEdges; + while( e->NextInSEL ) + { + TEdge *eNext = e->NextInSEL; + IntPoint Pt; + if(e->Curr.X > eNext->Curr.X) + { + IntersectPoint(*e, *eNext, Pt); + if (Pt.Y < topY) Pt = IntPoint(TopX(*e, topY), topY); + IntersectNode * newNode = new IntersectNode; + newNode->Edge1 = e; + newNode->Edge2 = eNext; + newNode->Pt = Pt; + m_IntersectList.push_back(newNode); + + SwapPositionsInSEL(e, eNext); + isModified = true; + } + else + e = eNext; + } + if( e->PrevInSEL ) e->PrevInSEL->NextInSEL = 0; + else break; + } + while ( isModified ); + m_SortedEdges = 0; //important +} +//------------------------------------------------------------------------------ + + +void Clipper::ProcessIntersectList() +{ + for (size_t i = 0; i < m_IntersectList.size(); ++i) + { + IntersectNode* iNode = m_IntersectList[i]; + { + IntersectEdges( iNode->Edge1, iNode->Edge2, iNode->Pt); + SwapPositionsInAEL( iNode->Edge1 , iNode->Edge2 ); + } + delete iNode; + } + m_IntersectList.clear(); +} +//------------------------------------------------------------------------------ + +bool IntersectListSort(IntersectNode* node1, IntersectNode* node2) +{ + return node2->Pt.Y < node1->Pt.Y; +} +//------------------------------------------------------------------------------ + +inline bool EdgesAdjacent(const IntersectNode &inode) +{ + return (inode.Edge1->NextInSEL == inode.Edge2) || + (inode.Edge1->PrevInSEL == inode.Edge2); +} +//------------------------------------------------------------------------------ + +bool Clipper::FixupIntersectionOrder() +{ + //pre-condition: intersections are sorted Bottom-most first. + //Now it's crucial that intersections are made only between adjacent edges, + //so to ensure this the order of intersections may need adjusting ... + CopyAELToSEL(); + std::sort(m_IntersectList.begin(), m_IntersectList.end(), IntersectListSort); + size_t cnt = m_IntersectList.size(); + for (size_t i = 0; i < cnt; ++i) + { + if (!EdgesAdjacent(*m_IntersectList[i])) + { + size_t j = i + 1; + while (j < cnt && !EdgesAdjacent(*m_IntersectList[j])) j++; + if (j == cnt) return false; + std::swap(m_IntersectList[i], m_IntersectList[j]); + } + SwapPositionsInSEL(m_IntersectList[i]->Edge1, m_IntersectList[i]->Edge2); + } + return true; +} +//------------------------------------------------------------------------------ + +void Clipper::DoMaxima(TEdge *e) +{ + TEdge* eMaxPair = GetMaximaPairEx(e); + if (!eMaxPair) + { + if (e->OutIdx >= 0) + AddOutPt(e, e->Top); + DeleteFromAEL(e); + return; + } + + TEdge* eNext = e->NextInAEL; + while(eNext && eNext != eMaxPair) + { + IntersectEdges(e, eNext, e->Top); + SwapPositionsInAEL(e, eNext); + eNext = e->NextInAEL; + } + + if(e->OutIdx == Unassigned && eMaxPair->OutIdx == Unassigned) + { + DeleteFromAEL(e); + DeleteFromAEL(eMaxPair); + } + else if( e->OutIdx >= 0 && eMaxPair->OutIdx >= 0 ) + { + if (e->OutIdx >= 0) AddLocalMaxPoly(e, eMaxPair, e->Top); + DeleteFromAEL(e); + DeleteFromAEL(eMaxPair); + } +#ifdef use_lines + else if (e->WindDelta == 0) + { + if (e->OutIdx >= 0) + { + AddOutPt(e, e->Top); + e->OutIdx = Unassigned; + } + DeleteFromAEL(e); + + if (eMaxPair->OutIdx >= 0) + { + AddOutPt(eMaxPair, e->Top); + eMaxPair->OutIdx = Unassigned; + } + DeleteFromAEL(eMaxPair); + } +#endif + else throw clipperException("DoMaxima error"); +} +//------------------------------------------------------------------------------ + +void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY) +{ + TEdge* e = m_ActiveEdges; + while( e ) + { + //1. process maxima, treating them as if they're 'bent' horizontal edges, + // but exclude maxima with horizontal edges. nb: e can't be a horizontal. + bool IsMaximaEdge = IsMaxima(e, topY); + + if(IsMaximaEdge) + { + TEdge* eMaxPair = GetMaximaPairEx(e); + IsMaximaEdge = (!eMaxPair || !IsHorizontal(*eMaxPair)); + } + + if(IsMaximaEdge) + { + if (m_StrictSimple) m_Maxima.push_back(e->Top.X); + TEdge* ePrev = e->PrevInAEL; + DoMaxima(e); + if( !ePrev ) e = m_ActiveEdges; + else e = ePrev->NextInAEL; + } + else + { + //2. promote horizontal edges, otherwise update Curr.X and Curr.Y ... + if (IsIntermediate(e, topY) && IsHorizontal(*e->NextInLML)) + { + UpdateEdgeIntoAEL(e); + if (e->OutIdx >= 0) + AddOutPt(e, e->Bot); + AddEdgeToSEL(e); + } + else + { + e->Curr.X = TopX( *e, topY ); + e->Curr.Y = topY; +#ifdef use_xyz + e->Curr.Z = topY == e->Top.Y ? e->Top.Z : (topY == e->Bot.Y ? e->Bot.Z : 0); +#endif + } + + //When StrictlySimple and 'e' is being touched by another edge, then + //make sure both edges have a vertex here ... + if (m_StrictSimple) + { + TEdge* ePrev = e->PrevInAEL; + if ((e->OutIdx >= 0) && (e->WindDelta != 0) && ePrev && (ePrev->OutIdx >= 0) && + (ePrev->Curr.X == e->Curr.X) && (ePrev->WindDelta != 0)) + { + IntPoint pt = e->Curr; +#ifdef use_xyz + SetZ(pt, *ePrev, *e); +#endif + OutPt* op = AddOutPt(ePrev, pt); + OutPt* op2 = AddOutPt(e, pt); + AddJoin(op, op2, pt); //StrictlySimple (type-3) join + } + } + + e = e->NextInAEL; + } + } + + //3. Process horizontals at the Top of the scanbeam ... + m_Maxima.sort(); + ProcessHorizontals(); + m_Maxima.clear(); + + //4. Promote intermediate vertices ... + e = m_ActiveEdges; + while(e) + { + if(IsIntermediate(e, topY)) + { + OutPt* op = 0; + if( e->OutIdx >= 0 ) + op = AddOutPt(e, e->Top); + UpdateEdgeIntoAEL(e); + + //if output polygons share an edge, they'll need joining later ... + TEdge* ePrev = e->PrevInAEL; + TEdge* eNext = e->NextInAEL; + if (ePrev && ePrev->Curr.X == e->Bot.X && + ePrev->Curr.Y == e->Bot.Y && op && + ePrev->OutIdx >= 0 && ePrev->Curr.Y > ePrev->Top.Y && + SlopesEqual(e->Curr, e->Top, ePrev->Curr, ePrev->Top, m_UseFullRange) && + (e->WindDelta != 0) && (ePrev->WindDelta != 0)) + { + OutPt* op2 = AddOutPt(ePrev, e->Bot); + AddJoin(op, op2, e->Top); + } + else if (eNext && eNext->Curr.X == e->Bot.X && + eNext->Curr.Y == e->Bot.Y && op && + eNext->OutIdx >= 0 && eNext->Curr.Y > eNext->Top.Y && + SlopesEqual(e->Curr, e->Top, eNext->Curr, eNext->Top, m_UseFullRange) && + (e->WindDelta != 0) && (eNext->WindDelta != 0)) + { + OutPt* op2 = AddOutPt(eNext, e->Bot); + AddJoin(op, op2, e->Top); + } + } + e = e->NextInAEL; + } +} +//------------------------------------------------------------------------------ + +void Clipper::FixupOutPolyline(OutRec &outrec) +{ + OutPt *pp = outrec.Pts; + OutPt *lastPP = pp->Prev; + while (pp != lastPP) + { + pp = pp->Next; + if (pp->Pt == pp->Prev->Pt) + { + if (pp == lastPP) lastPP = pp->Prev; + OutPt *tmpPP = pp->Prev; + tmpPP->Next = pp->Next; + pp->Next->Prev = tmpPP; + delete pp; + pp = tmpPP; + } + } + + if (pp == pp->Prev) + { + DisposeOutPts(pp); + outrec.Pts = 0; + return; + } +} +//------------------------------------------------------------------------------ + +void Clipper::FixupOutPolygon(OutRec &outrec) +{ + //FixupOutPolygon() - removes duplicate points and simplifies consecutive + //parallel edges by removing the middle vertex. + OutPt *lastOK = 0; + outrec.BottomPt = 0; + OutPt *pp = outrec.Pts; + bool preserveCol = m_PreserveCollinear || m_StrictSimple; + + for (;;) + { + if (pp->Prev == pp || pp->Prev == pp->Next) + { + DisposeOutPts(pp); + outrec.Pts = 0; + return; + } + + //test for duplicate points and collinear edges ... + if ((pp->Pt == pp->Next->Pt) || (pp->Pt == pp->Prev->Pt) || + (SlopesEqual(pp->Prev->Pt, pp->Pt, pp->Next->Pt, m_UseFullRange) && + (!preserveCol || !Pt2IsBetweenPt1AndPt3(pp->Prev->Pt, pp->Pt, pp->Next->Pt)))) + { + lastOK = 0; + OutPt *tmp = pp; + pp->Prev->Next = pp->Next; + pp->Next->Prev = pp->Prev; + pp = pp->Prev; + delete tmp; + } + else if (pp == lastOK) break; + else + { + if (!lastOK) lastOK = pp; + pp = pp->Next; + } + } + outrec.Pts = pp; +} +//------------------------------------------------------------------------------ + +int PointCount(OutPt *Pts) +{ + if (!Pts) return 0; + int result = 0; + OutPt* p = Pts; + do + { + result++; + p = p->Next; + } + while (p != Pts); + return result; +} +//------------------------------------------------------------------------------ + +void Clipper::BuildResult(Paths &polys) +{ + polys.reserve(m_PolyOuts.size()); + for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) + { + if (!m_PolyOuts[i]->Pts) continue; + Path pg; + OutPt* p = m_PolyOuts[i]->Pts->Prev; + int cnt = PointCount(p); + if (cnt < 2) continue; + pg.reserve(cnt); + for (int i = 0; i < cnt; ++i) + { + pg.push_back(p->Pt); + p = p->Prev; + } + polys.push_back(pg); + } +} +//------------------------------------------------------------------------------ + +void Clipper::BuildResult2(PolyTree& polytree) +{ + polytree.Clear(); + polytree.AllNodes.reserve(m_PolyOuts.size()); + //add each output polygon/contour to polytree ... + for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); i++) + { + OutRec* outRec = m_PolyOuts[i]; + int cnt = PointCount(outRec->Pts); + if ((outRec->IsOpen && cnt < 2) || (!outRec->IsOpen && cnt < 3)) continue; + FixHoleLinkage(*outRec); + PolyNode* pn = new PolyNode(); + //nb: polytree takes ownership of all the PolyNodes + polytree.AllNodes.push_back(pn); + outRec->PolyNd = pn; + pn->Parent = 0; + pn->Index = 0; + pn->Contour.reserve(cnt); + OutPt *op = outRec->Pts->Prev; + for (int j = 0; j < cnt; j++) + { + pn->Contour.push_back(op->Pt); + op = op->Prev; + } + } + + //fixup PolyNode links etc ... + polytree.Childs.reserve(m_PolyOuts.size()); + for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); i++) + { + OutRec* outRec = m_PolyOuts[i]; + if (!outRec->PolyNd) continue; + if (outRec->IsOpen) + { + outRec->PolyNd->m_IsOpen = true; + polytree.AddChild(*outRec->PolyNd); + } + else if (outRec->FirstLeft && outRec->FirstLeft->PolyNd) + outRec->FirstLeft->PolyNd->AddChild(*outRec->PolyNd); + else + polytree.AddChild(*outRec->PolyNd); + } +} +//------------------------------------------------------------------------------ + +void SwapIntersectNodes(IntersectNode &int1, IntersectNode &int2) +{ + //just swap the contents (because fIntersectNodes is a single-linked-list) + IntersectNode inode = int1; //gets a copy of Int1 + int1.Edge1 = int2.Edge1; + int1.Edge2 = int2.Edge2; + int1.Pt = int2.Pt; + int2.Edge1 = inode.Edge1; + int2.Edge2 = inode.Edge2; + int2.Pt = inode.Pt; +} +//------------------------------------------------------------------------------ + +inline bool E2InsertsBeforeE1(TEdge &e1, TEdge &e2) +{ + if (e2.Curr.X == e1.Curr.X) + { + if (e2.Top.Y > e1.Top.Y) + return e2.Top.X < TopX(e1, e2.Top.Y); + else return e1.Top.X > TopX(e2, e1.Top.Y); + } + else return e2.Curr.X < e1.Curr.X; +} +//------------------------------------------------------------------------------ + +bool GetOverlap(const cInt a1, const cInt a2, const cInt b1, const cInt b2, + cInt& Left, cInt& Right) +{ + if (a1 < a2) + { + if (b1 < b2) {Left = std::max(a1,b1); Right = std::min(a2,b2);} + else {Left = std::max(a1,b2); Right = std::min(a2,b1);} + } + else + { + if (b1 < b2) {Left = std::max(a2,b1); Right = std::min(a1,b2);} + else {Left = std::max(a2,b2); Right = std::min(a1,b1);} + } + return Left < Right; +} +//------------------------------------------------------------------------------ + +inline void UpdateOutPtIdxs(OutRec& outrec) +{ + OutPt* op = outrec.Pts; + do + { + op->Idx = outrec.Idx; + op = op->Prev; + } + while(op != outrec.Pts); +} +//------------------------------------------------------------------------------ + +void Clipper::InsertEdgeIntoAEL(TEdge *edge, TEdge* startEdge) +{ + if(!m_ActiveEdges) + { + edge->PrevInAEL = 0; + edge->NextInAEL = 0; + m_ActiveEdges = edge; + } + else if(!startEdge && E2InsertsBeforeE1(*m_ActiveEdges, *edge)) + { + edge->PrevInAEL = 0; + edge->NextInAEL = m_ActiveEdges; + m_ActiveEdges->PrevInAEL = edge; + m_ActiveEdges = edge; + } + else + { + if(!startEdge) startEdge = m_ActiveEdges; + while(startEdge->NextInAEL && + !E2InsertsBeforeE1(*startEdge->NextInAEL , *edge)) + startEdge = startEdge->NextInAEL; + edge->NextInAEL = startEdge->NextInAEL; + if(startEdge->NextInAEL) startEdge->NextInAEL->PrevInAEL = edge; + edge->PrevInAEL = startEdge; + startEdge->NextInAEL = edge; + } +} +//---------------------------------------------------------------------- + +OutPt* DupOutPt(OutPt* outPt, bool InsertAfter) +{ + OutPt* result = new OutPt; + result->Pt = outPt->Pt; + result->Idx = outPt->Idx; + if (InsertAfter) + { + result->Next = outPt->Next; + result->Prev = outPt; + outPt->Next->Prev = result; + outPt->Next = result; + } + else + { + result->Prev = outPt->Prev; + result->Next = outPt; + outPt->Prev->Next = result; + outPt->Prev = result; + } + return result; +} +//------------------------------------------------------------------------------ + +bool JoinHorz(OutPt* op1, OutPt* op1b, OutPt* op2, OutPt* op2b, + const IntPoint Pt, bool DiscardLeft) +{ + Direction Dir1 = (op1->Pt.X > op1b->Pt.X ? dRightToLeft : dLeftToRight); + Direction Dir2 = (op2->Pt.X > op2b->Pt.X ? dRightToLeft : dLeftToRight); + if (Dir1 == Dir2) return false; + + //When DiscardLeft, we want Op1b to be on the Left of Op1, otherwise we + //want Op1b to be on the Right. (And likewise with Op2 and Op2b.) + //So, to facilitate this while inserting Op1b and Op2b ... + //when DiscardLeft, make sure we're AT or RIGHT of Pt before adding Op1b, + //otherwise make sure we're AT or LEFT of Pt. (Likewise with Op2b.) + if (Dir1 == dLeftToRight) + { + while (op1->Next->Pt.X <= Pt.X && + op1->Next->Pt.X >= op1->Pt.X && op1->Next->Pt.Y == Pt.Y) + op1 = op1->Next; + if (DiscardLeft && (op1->Pt.X != Pt.X)) op1 = op1->Next; + op1b = DupOutPt(op1, !DiscardLeft); + if (op1b->Pt != Pt) + { + op1 = op1b; + op1->Pt = Pt; + op1b = DupOutPt(op1, !DiscardLeft); + } + } + else + { + while (op1->Next->Pt.X >= Pt.X && + op1->Next->Pt.X <= op1->Pt.X && op1->Next->Pt.Y == Pt.Y) + op1 = op1->Next; + if (!DiscardLeft && (op1->Pt.X != Pt.X)) op1 = op1->Next; + op1b = DupOutPt(op1, DiscardLeft); + if (op1b->Pt != Pt) + { + op1 = op1b; + op1->Pt = Pt; + op1b = DupOutPt(op1, DiscardLeft); + } + } + + if (Dir2 == dLeftToRight) + { + while (op2->Next->Pt.X <= Pt.X && + op2->Next->Pt.X >= op2->Pt.X && op2->Next->Pt.Y == Pt.Y) + op2 = op2->Next; + if (DiscardLeft && (op2->Pt.X != Pt.X)) op2 = op2->Next; + op2b = DupOutPt(op2, !DiscardLeft); + if (op2b->Pt != Pt) + { + op2 = op2b; + op2->Pt = Pt; + op2b = DupOutPt(op2, !DiscardLeft); + }; + } else + { + while (op2->Next->Pt.X >= Pt.X && + op2->Next->Pt.X <= op2->Pt.X && op2->Next->Pt.Y == Pt.Y) + op2 = op2->Next; + if (!DiscardLeft && (op2->Pt.X != Pt.X)) op2 = op2->Next; + op2b = DupOutPt(op2, DiscardLeft); + if (op2b->Pt != Pt) + { + op2 = op2b; + op2->Pt = Pt; + op2b = DupOutPt(op2, DiscardLeft); + }; + }; + + if ((Dir1 == dLeftToRight) == DiscardLeft) + { + op1->Prev = op2; + op2->Next = op1; + op1b->Next = op2b; + op2b->Prev = op1b; + } + else + { + op1->Next = op2; + op2->Prev = op1; + op1b->Prev = op2b; + op2b->Next = op1b; + } + return true; +} +//------------------------------------------------------------------------------ + +bool Clipper::JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2) +{ + OutPt *op1 = j->OutPt1, *op1b; + OutPt *op2 = j->OutPt2, *op2b; + + //There are 3 kinds of joins for output polygons ... + //1. Horizontal joins where Join.OutPt1 & Join.OutPt2 are vertices anywhere + //along (horizontal) collinear edges (& Join.OffPt is on the same horizontal). + //2. Non-horizontal joins where Join.OutPt1 & Join.OutPt2 are at the same + //location at the Bottom of the overlapping segment (& Join.OffPt is above). + //3. StrictSimple joins where edges touch but are not collinear and where + //Join.OutPt1, Join.OutPt2 & Join.OffPt all share the same point. + bool isHorizontal = (j->OutPt1->Pt.Y == j->OffPt.Y); + + if (isHorizontal && (j->OffPt == j->OutPt1->Pt) && + (j->OffPt == j->OutPt2->Pt)) + { + //Strictly Simple join ... + if (outRec1 != outRec2) return false; + op1b = j->OutPt1->Next; + while (op1b != op1 && (op1b->Pt == j->OffPt)) + op1b = op1b->Next; + bool reverse1 = (op1b->Pt.Y > j->OffPt.Y); + op2b = j->OutPt2->Next; + while (op2b != op2 && (op2b->Pt == j->OffPt)) + op2b = op2b->Next; + bool reverse2 = (op2b->Pt.Y > j->OffPt.Y); + if (reverse1 == reverse2) return false; + if (reverse1) + { + op1b = DupOutPt(op1, false); + op2b = DupOutPt(op2, true); + op1->Prev = op2; + op2->Next = op1; + op1b->Next = op2b; + op2b->Prev = op1b; + j->OutPt1 = op1; + j->OutPt2 = op1b; + return true; + } else + { + op1b = DupOutPt(op1, true); + op2b = DupOutPt(op2, false); + op1->Next = op2; + op2->Prev = op1; + op1b->Prev = op2b; + op2b->Next = op1b; + j->OutPt1 = op1; + j->OutPt2 = op1b; + return true; + } + } + else if (isHorizontal) + { + //treat horizontal joins differently to non-horizontal joins since with + //them we're not yet sure where the overlapping is. OutPt1.Pt & OutPt2.Pt + //may be anywhere along the horizontal edge. + op1b = op1; + while (op1->Prev->Pt.Y == op1->Pt.Y && op1->Prev != op1b && op1->Prev != op2) + op1 = op1->Prev; + while (op1b->Next->Pt.Y == op1b->Pt.Y && op1b->Next != op1 && op1b->Next != op2) + op1b = op1b->Next; + if (op1b->Next == op1 || op1b->Next == op2) return false; //a flat 'polygon' + + op2b = op2; + while (op2->Prev->Pt.Y == op2->Pt.Y && op2->Prev != op2b && op2->Prev != op1b) + op2 = op2->Prev; + while (op2b->Next->Pt.Y == op2b->Pt.Y && op2b->Next != op2 && op2b->Next != op1) + op2b = op2b->Next; + if (op2b->Next == op2 || op2b->Next == op1) return false; //a flat 'polygon' + + cInt Left, Right; + //Op1 --> Op1b & Op2 --> Op2b are the extremites of the horizontal edges + if (!GetOverlap(op1->Pt.X, op1b->Pt.X, op2->Pt.X, op2b->Pt.X, Left, Right)) + return false; + + //DiscardLeftSide: when overlapping edges are joined, a spike will created + //which needs to be cleaned up. However, we don't want Op1 or Op2 caught up + //on the discard Side as either may still be needed for other joins ... + IntPoint Pt; + bool DiscardLeftSide; + if (op1->Pt.X >= Left && op1->Pt.X <= Right) + { + Pt = op1->Pt; DiscardLeftSide = (op1->Pt.X > op1b->Pt.X); + } + else if (op2->Pt.X >= Left&& op2->Pt.X <= Right) + { + Pt = op2->Pt; DiscardLeftSide = (op2->Pt.X > op2b->Pt.X); + } + else if (op1b->Pt.X >= Left && op1b->Pt.X <= Right) + { + Pt = op1b->Pt; DiscardLeftSide = op1b->Pt.X > op1->Pt.X; + } + else + { + Pt = op2b->Pt; DiscardLeftSide = (op2b->Pt.X > op2->Pt.X); + } + j->OutPt1 = op1; j->OutPt2 = op2; + return JoinHorz(op1, op1b, op2, op2b, Pt, DiscardLeftSide); + } else + { + //nb: For non-horizontal joins ... + // 1. Jr.OutPt1.Pt.Y == Jr.OutPt2.Pt.Y + // 2. Jr.OutPt1.Pt > Jr.OffPt.Y + + //make sure the polygons are correctly oriented ... + op1b = op1->Next; + while ((op1b->Pt == op1->Pt) && (op1b != op1)) op1b = op1b->Next; + bool Reverse1 = ((op1b->Pt.Y > op1->Pt.Y) || + !SlopesEqual(op1->Pt, op1b->Pt, j->OffPt, m_UseFullRange)); + if (Reverse1) + { + op1b = op1->Prev; + while ((op1b->Pt == op1->Pt) && (op1b != op1)) op1b = op1b->Prev; + if ((op1b->Pt.Y > op1->Pt.Y) || + !SlopesEqual(op1->Pt, op1b->Pt, j->OffPt, m_UseFullRange)) return false; + }; + op2b = op2->Next; + while ((op2b->Pt == op2->Pt) && (op2b != op2))op2b = op2b->Next; + bool Reverse2 = ((op2b->Pt.Y > op2->Pt.Y) || + !SlopesEqual(op2->Pt, op2b->Pt, j->OffPt, m_UseFullRange)); + if (Reverse2) + { + op2b = op2->Prev; + while ((op2b->Pt == op2->Pt) && (op2b != op2)) op2b = op2b->Prev; + if ((op2b->Pt.Y > op2->Pt.Y) || + !SlopesEqual(op2->Pt, op2b->Pt, j->OffPt, m_UseFullRange)) return false; + } + + if ((op1b == op1) || (op2b == op2) || (op1b == op2b) || + ((outRec1 == outRec2) && (Reverse1 == Reverse2))) return false; + + if (Reverse1) + { + op1b = DupOutPt(op1, false); + op2b = DupOutPt(op2, true); + op1->Prev = op2; + op2->Next = op1; + op1b->Next = op2b; + op2b->Prev = op1b; + j->OutPt1 = op1; + j->OutPt2 = op1b; + return true; + } else + { + op1b = DupOutPt(op1, true); + op2b = DupOutPt(op2, false); + op1->Next = op2; + op2->Prev = op1; + op1b->Prev = op2b; + op2b->Next = op1b; + j->OutPt1 = op1; + j->OutPt2 = op1b; + return true; + } + } +} +//---------------------------------------------------------------------- + +static OutRec* ParseFirstLeft(OutRec* FirstLeft) +{ + while (FirstLeft && !FirstLeft->Pts) + FirstLeft = FirstLeft->FirstLeft; + return FirstLeft; +} +//------------------------------------------------------------------------------ + +void Clipper::FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec) +{ + //tests if NewOutRec contains the polygon before reassigning FirstLeft + for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) + { + OutRec* outRec = m_PolyOuts[i]; + OutRec* firstLeft = ParseFirstLeft(outRec->FirstLeft); + if (outRec->Pts && firstLeft == OldOutRec) + { + if (Poly2ContainsPoly1(outRec->Pts, NewOutRec->Pts)) + outRec->FirstLeft = NewOutRec; + } + } +} +//---------------------------------------------------------------------- + +void Clipper::FixupFirstLefts2(OutRec* InnerOutRec, OutRec* OuterOutRec) +{ + //A polygon has split into two such that one is now the inner of the other. + //It's possible that these polygons now wrap around other polygons, so check + //every polygon that's also contained by OuterOutRec's FirstLeft container + //(including 0) to see if they've become inner to the new inner polygon ... + OutRec* orfl = OuterOutRec->FirstLeft; + for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) + { + OutRec* outRec = m_PolyOuts[i]; + + if (!outRec->Pts || outRec == OuterOutRec || outRec == InnerOutRec) + continue; + OutRec* firstLeft = ParseFirstLeft(outRec->FirstLeft); + if (firstLeft != orfl && firstLeft != InnerOutRec && firstLeft != OuterOutRec) + continue; + if (Poly2ContainsPoly1(outRec->Pts, InnerOutRec->Pts)) + outRec->FirstLeft = InnerOutRec; + else if (Poly2ContainsPoly1(outRec->Pts, OuterOutRec->Pts)) + outRec->FirstLeft = OuterOutRec; + else if (outRec->FirstLeft == InnerOutRec || outRec->FirstLeft == OuterOutRec) + outRec->FirstLeft = orfl; + } +} +//---------------------------------------------------------------------- +void Clipper::FixupFirstLefts3(OutRec* OldOutRec, OutRec* NewOutRec) +{ + //reassigns FirstLeft WITHOUT testing if NewOutRec contains the polygon + for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) + { + OutRec* outRec = m_PolyOuts[i]; + OutRec* firstLeft = ParseFirstLeft(outRec->FirstLeft); + if (outRec->Pts && firstLeft == OldOutRec) + outRec->FirstLeft = NewOutRec; + } +} +//---------------------------------------------------------------------- + +void Clipper::JoinCommonEdges() +{ + for (JoinList::size_type i = 0; i < m_Joins.size(); i++) + { + Join* join = m_Joins[i]; + + OutRec *outRec1 = GetOutRec(join->OutPt1->Idx); + OutRec *outRec2 = GetOutRec(join->OutPt2->Idx); + + if (!outRec1->Pts || !outRec2->Pts) continue; + if (outRec1->IsOpen || outRec2->IsOpen) continue; + + //get the polygon fragment with the correct hole state (FirstLeft) + //before calling JoinPoints() ... + OutRec *holeStateRec; + if (outRec1 == outRec2) holeStateRec = outRec1; + else if (OutRec1RightOfOutRec2(outRec1, outRec2)) holeStateRec = outRec2; + else if (OutRec1RightOfOutRec2(outRec2, outRec1)) holeStateRec = outRec1; + else holeStateRec = GetLowermostRec(outRec1, outRec2); + + if (!JoinPoints(join, outRec1, outRec2)) continue; + + if (outRec1 == outRec2) + { + //instead of joining two polygons, we've just created a new one by + //splitting one polygon into two. + outRec1->Pts = join->OutPt1; + outRec1->BottomPt = 0; + outRec2 = CreateOutRec(); + outRec2->Pts = join->OutPt2; + + //update all OutRec2.Pts Idx's ... + UpdateOutPtIdxs(*outRec2); + + if (Poly2ContainsPoly1(outRec2->Pts, outRec1->Pts)) + { + //outRec1 contains outRec2 ... + outRec2->IsHole = !outRec1->IsHole; + outRec2->FirstLeft = outRec1; + + if (m_UsingPolyTree) FixupFirstLefts2(outRec2, outRec1); + + if ((outRec2->IsHole ^ m_ReverseOutput) == (Area(*outRec2) > 0)) + ReversePolyPtLinks(outRec2->Pts); + + } else if (Poly2ContainsPoly1(outRec1->Pts, outRec2->Pts)) + { + //outRec2 contains outRec1 ... + outRec2->IsHole = outRec1->IsHole; + outRec1->IsHole = !outRec2->IsHole; + outRec2->FirstLeft = outRec1->FirstLeft; + outRec1->FirstLeft = outRec2; + + if (m_UsingPolyTree) FixupFirstLefts2(outRec1, outRec2); + + if ((outRec1->IsHole ^ m_ReverseOutput) == (Area(*outRec1) > 0)) + ReversePolyPtLinks(outRec1->Pts); + } + else + { + //the 2 polygons are completely separate ... + outRec2->IsHole = outRec1->IsHole; + outRec2->FirstLeft = outRec1->FirstLeft; + + //fixup FirstLeft pointers that may need reassigning to OutRec2 + if (m_UsingPolyTree) FixupFirstLefts1(outRec1, outRec2); + } + + } else + { + //joined 2 polygons together ... + + outRec2->Pts = 0; + outRec2->BottomPt = 0; + outRec2->Idx = outRec1->Idx; + + outRec1->IsHole = holeStateRec->IsHole; + if (holeStateRec == outRec2) + outRec1->FirstLeft = outRec2->FirstLeft; + outRec2->FirstLeft = outRec1; + + if (m_UsingPolyTree) FixupFirstLefts3(outRec2, outRec1); + } + } +} + +//------------------------------------------------------------------------------ +// ClipperOffset support functions ... +//------------------------------------------------------------------------------ + +DoublePoint GetUnitNormal(const IntPoint &pt1, const IntPoint &pt2) +{ + if(pt2.X == pt1.X && pt2.Y == pt1.Y) + return DoublePoint(0, 0); + + double Dx = (double)(pt2.X - pt1.X); + double dy = (double)(pt2.Y - pt1.Y); + double f = 1 *1.0/ std::sqrt( Dx*Dx + dy*dy ); + Dx *= f; + dy *= f; + return DoublePoint(dy, -Dx); +} + +//------------------------------------------------------------------------------ +// ClipperOffset class +//------------------------------------------------------------------------------ + +ClipperOffset::ClipperOffset(double miterLimit, double arcTolerance) +{ + this->MiterLimit = miterLimit; + this->ArcTolerance = arcTolerance; + m_lowest.X = -1; +} +//------------------------------------------------------------------------------ + +ClipperOffset::~ClipperOffset() +{ + Clear(); +} +//------------------------------------------------------------------------------ + +void ClipperOffset::Clear() +{ + for (int i = 0; i < m_polyNodes.ChildCount(); ++i) + delete m_polyNodes.Childs[i]; + m_polyNodes.Childs.clear(); + m_lowest.X = -1; +} +//------------------------------------------------------------------------------ + +void ClipperOffset::AddPath(const Path& path, JoinType joinType, EndType endType) +{ + int highI = (int)path.size() - 1; + if (highI < 0) return; + PolyNode* newNode = new PolyNode(); + newNode->m_jointype = joinType; + newNode->m_endtype = endType; + + //strip duplicate points from path and also get index to the lowest point ... + if (endType == etClosedLine || endType == etClosedPolygon) + while (highI > 0 && path[0] == path[highI]) highI--; + newNode->Contour.reserve(highI + 1); + newNode->Contour.push_back(path[0]); + int j = 0, k = 0; + for (int i = 1; i <= highI; i++) + if (newNode->Contour[j] != path[i]) + { + j++; + newNode->Contour.push_back(path[i]); + if (path[i].Y > newNode->Contour[k].Y || + (path[i].Y == newNode->Contour[k].Y && + path[i].X < newNode->Contour[k].X)) k = j; + } + if (endType == etClosedPolygon && j < 2) + { + delete newNode; + return; + } + m_polyNodes.AddChild(*newNode); + + //if this path's lowest pt is lower than all the others then update m_lowest + if (endType != etClosedPolygon) return; + if (m_lowest.X < 0) + m_lowest = IntPoint(m_polyNodes.ChildCount() - 1, k); + else + { + IntPoint ip = m_polyNodes.Childs[(int)m_lowest.X]->Contour[(int)m_lowest.Y]; + if (newNode->Contour[k].Y > ip.Y || + (newNode->Contour[k].Y == ip.Y && + newNode->Contour[k].X < ip.X)) + m_lowest = IntPoint(m_polyNodes.ChildCount() - 1, k); + } +} +//------------------------------------------------------------------------------ + +void ClipperOffset::AddPaths(const Paths& paths, JoinType joinType, EndType endType) +{ + for (Paths::size_type i = 0; i < paths.size(); ++i) + AddPath(paths[i], joinType, endType); +} +//------------------------------------------------------------------------------ + +void ClipperOffset::FixOrientations() +{ + //fixup orientations of all closed paths if the orientation of the + //closed path with the lowermost vertex is wrong ... + if (m_lowest.X >= 0 && + !Orientation(m_polyNodes.Childs[(int)m_lowest.X]->Contour)) + { + for (int i = 0; i < m_polyNodes.ChildCount(); ++i) + { + PolyNode& node = *m_polyNodes.Childs[i]; + if (node.m_endtype == etClosedPolygon || + (node.m_endtype == etClosedLine && Orientation(node.Contour))) + ReversePath(node.Contour); + } + } else + { + for (int i = 0; i < m_polyNodes.ChildCount(); ++i) + { + PolyNode& node = *m_polyNodes.Childs[i]; + if (node.m_endtype == etClosedLine && !Orientation(node.Contour)) + ReversePath(node.Contour); + } + } +} +//------------------------------------------------------------------------------ + +void ClipperOffset::Execute(Paths& solution, double delta) +{ + solution.clear(); + FixOrientations(); + DoOffset(delta); + + //now clean up 'corners' ... + Clipper clpr; + clpr.AddPaths(m_destPolys, ptSubject, true); + if (delta > 0) + { + clpr.Execute(ctUnion, solution, pftPositive, pftPositive); + } + else + { + IntRect r = clpr.GetBounds(); + Path outer(4); + outer[0] = IntPoint(r.left - 10, r.bottom + 10); + outer[1] = IntPoint(r.right + 10, r.bottom + 10); + outer[2] = IntPoint(r.right + 10, r.top - 10); + outer[3] = IntPoint(r.left - 10, r.top - 10); + + clpr.AddPath(outer, ptSubject, true); + clpr.ReverseSolution(true); + clpr.Execute(ctUnion, solution, pftNegative, pftNegative); + if (solution.size() > 0) solution.erase(solution.begin()); + } +} +//------------------------------------------------------------------------------ + +void ClipperOffset::Execute(PolyTree& solution, double delta) +{ + solution.Clear(); + FixOrientations(); + DoOffset(delta); + + //now clean up 'corners' ... + Clipper clpr; + clpr.AddPaths(m_destPolys, ptSubject, true); + if (delta > 0) + { + clpr.Execute(ctUnion, solution, pftPositive, pftPositive); + } + else + { + IntRect r = clpr.GetBounds(); + Path outer(4); + outer[0] = IntPoint(r.left - 10, r.bottom + 10); + outer[1] = IntPoint(r.right + 10, r.bottom + 10); + outer[2] = IntPoint(r.right + 10, r.top - 10); + outer[3] = IntPoint(r.left - 10, r.top - 10); + + clpr.AddPath(outer, ptSubject, true); + clpr.ReverseSolution(true); + clpr.Execute(ctUnion, solution, pftNegative, pftNegative); + //remove the outer PolyNode rectangle ... + if (solution.ChildCount() == 1 && solution.Childs[0]->ChildCount() > 0) + { + PolyNode* outerNode = solution.Childs[0]; + solution.Childs.reserve(outerNode->ChildCount()); + solution.Childs[0] = outerNode->Childs[0]; + solution.Childs[0]->Parent = outerNode->Parent; + for (int i = 1; i < outerNode->ChildCount(); ++i) + solution.AddChild(*outerNode->Childs[i]); + } + else + solution.Clear(); + } +} +//------------------------------------------------------------------------------ + +void ClipperOffset::DoOffset(double delta) +{ + m_destPolys.clear(); + m_delta = delta; + + //if Zero offset, just copy any CLOSED polygons to m_p and return ... + if (NEAR_ZERO(delta)) + { + m_destPolys.reserve(m_polyNodes.ChildCount()); + for (int i = 0; i < m_polyNodes.ChildCount(); i++) + { + PolyNode& node = *m_polyNodes.Childs[i]; + if (node.m_endtype == etClosedPolygon) + m_destPolys.push_back(node.Contour); + } + return; + } + + //see offset_triginometry3.svg in the documentation folder ... + if (MiterLimit > 2) m_miterLim = 2/(MiterLimit * MiterLimit); + else m_miterLim = 0.5; + + double y; + if (ArcTolerance <= 0.0) y = def_arc_tolerance; + else if (ArcTolerance > std::fabs(delta) * def_arc_tolerance) + y = std::fabs(delta) * def_arc_tolerance; + else y = ArcTolerance; + //see offset_triginometry2.svg in the documentation folder ... + double steps = pi / std::acos(1 - y / std::fabs(delta)); + if (steps > std::fabs(delta) * pi) + steps = std::fabs(delta) * pi; //ie excessive precision check + m_sin = std::sin(two_pi / steps); + m_cos = std::cos(two_pi / steps); + m_StepsPerRad = steps / two_pi; + if (delta < 0.0) m_sin = -m_sin; + + m_destPolys.reserve(m_polyNodes.ChildCount() * 2); + for (int i = 0; i < m_polyNodes.ChildCount(); i++) + { + PolyNode& node = *m_polyNodes.Childs[i]; + m_srcPoly = node.Contour; + + int len = (int)m_srcPoly.size(); + if (len == 0 || (delta <= 0 && (len < 3 || node.m_endtype != etClosedPolygon))) + continue; + + m_destPoly.clear(); + if (len == 1) + { + if (node.m_jointype == jtRound) + { + double X = 1.0, Y = 0.0; + for (cInt j = 1; j <= steps; j++) + { + m_destPoly.push_back(IntPoint( + Round(m_srcPoly[0].X + X * delta), + Round(m_srcPoly[0].Y + Y * delta))); + double X2 = X; + X = X * m_cos - m_sin * Y; + Y = X2 * m_sin + Y * m_cos; + } + } + else + { + double X = -1.0, Y = -1.0; + for (int j = 0; j < 4; ++j) + { + m_destPoly.push_back(IntPoint( + Round(m_srcPoly[0].X + X * delta), + Round(m_srcPoly[0].Y + Y * delta))); + if (X < 0) X = 1; + else if (Y < 0) Y = 1; + else X = -1; + } + } + m_destPolys.push_back(m_destPoly); + continue; + } + //build m_normals ... + m_normals.clear(); + m_normals.reserve(len); + for (int j = 0; j < len - 1; ++j) + m_normals.push_back(GetUnitNormal(m_srcPoly[j], m_srcPoly[j + 1])); + if (node.m_endtype == etClosedLine || node.m_endtype == etClosedPolygon) + m_normals.push_back(GetUnitNormal(m_srcPoly[len - 1], m_srcPoly[0])); + else + m_normals.push_back(DoublePoint(m_normals[len - 2])); + + if (node.m_endtype == etClosedPolygon) + { + int k = len - 1; + for (int j = 0; j < len; ++j) + OffsetPoint(j, k, node.m_jointype); + m_destPolys.push_back(m_destPoly); + } + else if (node.m_endtype == etClosedLine) + { + int k = len - 1; + for (int j = 0; j < len; ++j) + OffsetPoint(j, k, node.m_jointype); + m_destPolys.push_back(m_destPoly); + m_destPoly.clear(); + //re-build m_normals ... + DoublePoint n = m_normals[len -1]; + for (int j = len - 1; j > 0; j--) + m_normals[j] = DoublePoint(-m_normals[j - 1].X, -m_normals[j - 1].Y); + m_normals[0] = DoublePoint(-n.X, -n.Y); + k = 0; + for (int j = len - 1; j >= 0; j--) + OffsetPoint(j, k, node.m_jointype); + m_destPolys.push_back(m_destPoly); + } + else + { + int k = 0; + for (int j = 1; j < len - 1; ++j) + OffsetPoint(j, k, node.m_jointype); + + IntPoint pt1; + if (node.m_endtype == etOpenButt) + { + int j = len - 1; + pt1 = IntPoint((cInt)Round(m_srcPoly[j].X + m_normals[j].X * + delta), (cInt)Round(m_srcPoly[j].Y + m_normals[j].Y * delta)); + m_destPoly.push_back(pt1); + pt1 = IntPoint((cInt)Round(m_srcPoly[j].X - m_normals[j].X * + delta), (cInt)Round(m_srcPoly[j].Y - m_normals[j].Y * delta)); + m_destPoly.push_back(pt1); + } + else + { + int j = len - 1; + k = len - 2; + m_sinA = 0; + m_normals[j] = DoublePoint(-m_normals[j].X, -m_normals[j].Y); + if (node.m_endtype == etOpenSquare) + DoSquare(j, k); + else + DoRound(j, k); + } + + //re-build m_normals ... + for (int j = len - 1; j > 0; j--) + m_normals[j] = DoublePoint(-m_normals[j - 1].X, -m_normals[j - 1].Y); + m_normals[0] = DoublePoint(-m_normals[1].X, -m_normals[1].Y); + + k = len - 1; + for (int j = k - 1; j > 0; --j) OffsetPoint(j, k, node.m_jointype); + + if (node.m_endtype == etOpenButt) + { + pt1 = IntPoint((cInt)Round(m_srcPoly[0].X - m_normals[0].X * delta), + (cInt)Round(m_srcPoly[0].Y - m_normals[0].Y * delta)); + m_destPoly.push_back(pt1); + pt1 = IntPoint((cInt)Round(m_srcPoly[0].X + m_normals[0].X * delta), + (cInt)Round(m_srcPoly[0].Y + m_normals[0].Y * delta)); + m_destPoly.push_back(pt1); + } + else + { + k = 1; + m_sinA = 0; + if (node.m_endtype == etOpenSquare) + DoSquare(0, 1); + else + DoRound(0, 1); + } + m_destPolys.push_back(m_destPoly); + } + } +} +//------------------------------------------------------------------------------ + +void ClipperOffset::OffsetPoint(int j, int& k, JoinType jointype) +{ + //cross product ... + m_sinA = (m_normals[k].X * m_normals[j].Y - m_normals[j].X * m_normals[k].Y); + if (std::fabs(m_sinA * m_delta) < 1.0) + { + //dot product ... + double cosA = (m_normals[k].X * m_normals[j].X + m_normals[j].Y * m_normals[k].Y ); + if (cosA > 0) // angle => 0 degrees + { + m_destPoly.push_back(IntPoint(Round(m_srcPoly[j].X + m_normals[k].X * m_delta), + Round(m_srcPoly[j].Y + m_normals[k].Y * m_delta))); + return; + } + //else angle => 180 degrees + } + else if (m_sinA > 1.0) m_sinA = 1.0; + else if (m_sinA < -1.0) m_sinA = -1.0; + + if (m_sinA * m_delta < 0) + { + m_destPoly.push_back(IntPoint(Round(m_srcPoly[j].X + m_normals[k].X * m_delta), + Round(m_srcPoly[j].Y + m_normals[k].Y * m_delta))); + m_destPoly.push_back(m_srcPoly[j]); + m_destPoly.push_back(IntPoint(Round(m_srcPoly[j].X + m_normals[j].X * m_delta), + Round(m_srcPoly[j].Y + m_normals[j].Y * m_delta))); + } + else + switch (jointype) + { + case jtMiter: + { + double r = 1 + (m_normals[j].X * m_normals[k].X + + m_normals[j].Y * m_normals[k].Y); + if (r >= m_miterLim) DoMiter(j, k, r); else DoSquare(j, k); + break; + } + case jtSquare: DoSquare(j, k); break; + case jtRound: DoRound(j, k); break; + } + k = j; +} +//------------------------------------------------------------------------------ + +void ClipperOffset::DoSquare(int j, int k) +{ + double dx = std::tan(std::atan2(m_sinA, + m_normals[k].X * m_normals[j].X + m_normals[k].Y * m_normals[j].Y) / 4); + m_destPoly.push_back(IntPoint( + Round(m_srcPoly[j].X + m_delta * (m_normals[k].X - m_normals[k].Y * dx)), + Round(m_srcPoly[j].Y + m_delta * (m_normals[k].Y + m_normals[k].X * dx)))); + m_destPoly.push_back(IntPoint( + Round(m_srcPoly[j].X + m_delta * (m_normals[j].X + m_normals[j].Y * dx)), + Round(m_srcPoly[j].Y + m_delta * (m_normals[j].Y - m_normals[j].X * dx)))); +} +//------------------------------------------------------------------------------ + +void ClipperOffset::DoMiter(int j, int k, double r) +{ + double q = m_delta / r; + m_destPoly.push_back(IntPoint(Round(m_srcPoly[j].X + (m_normals[k].X + m_normals[j].X) * q), + Round(m_srcPoly[j].Y + (m_normals[k].Y + m_normals[j].Y) * q))); +} +//------------------------------------------------------------------------------ + +void ClipperOffset::DoRound(int j, int k) +{ + double a = std::atan2(m_sinA, + m_normals[k].X * m_normals[j].X + m_normals[k].Y * m_normals[j].Y); + int steps = std::max((int)Round(m_StepsPerRad * std::fabs(a)), 1); + + double X = m_normals[k].X, Y = m_normals[k].Y, X2; + for (int i = 0; i < steps; ++i) + { + m_destPoly.push_back(IntPoint( + Round(m_srcPoly[j].X + X * m_delta), + Round(m_srcPoly[j].Y + Y * m_delta))); + X2 = X; + X = X * m_cos - m_sin * Y; + Y = X2 * m_sin + Y * m_cos; + } + m_destPoly.push_back(IntPoint( + Round(m_srcPoly[j].X + m_normals[j].X * m_delta), + Round(m_srcPoly[j].Y + m_normals[j].Y * m_delta))); +} + +//------------------------------------------------------------------------------ +// Miscellaneous public functions +//------------------------------------------------------------------------------ + +void Clipper::DoSimplePolygons() +{ + PolyOutList::size_type i = 0; + while (i < m_PolyOuts.size()) + { + OutRec* outrec = m_PolyOuts[i++]; + OutPt* op = outrec->Pts; + if (!op || outrec->IsOpen) continue; + do //for each Pt in Polygon until duplicate found do ... + { + OutPt* op2 = op->Next; + while (op2 != outrec->Pts) + { + if ((op->Pt == op2->Pt) && op2->Next != op && op2->Prev != op) + { + //split the polygon into two ... + OutPt* op3 = op->Prev; + OutPt* op4 = op2->Prev; + op->Prev = op4; + op4->Next = op; + op2->Prev = op3; + op3->Next = op2; + + outrec->Pts = op; + OutRec* outrec2 = CreateOutRec(); + outrec2->Pts = op2; + UpdateOutPtIdxs(*outrec2); + if (Poly2ContainsPoly1(outrec2->Pts, outrec->Pts)) + { + //OutRec2 is contained by OutRec1 ... + outrec2->IsHole = !outrec->IsHole; + outrec2->FirstLeft = outrec; + if (m_UsingPolyTree) FixupFirstLefts2(outrec2, outrec); + } + else + if (Poly2ContainsPoly1(outrec->Pts, outrec2->Pts)) + { + //OutRec1 is contained by OutRec2 ... + outrec2->IsHole = outrec->IsHole; + outrec->IsHole = !outrec2->IsHole; + outrec2->FirstLeft = outrec->FirstLeft; + outrec->FirstLeft = outrec2; + if (m_UsingPolyTree) FixupFirstLefts2(outrec, outrec2); + } + else + { + //the 2 polygons are separate ... + outrec2->IsHole = outrec->IsHole; + outrec2->FirstLeft = outrec->FirstLeft; + if (m_UsingPolyTree) FixupFirstLefts1(outrec, outrec2); + } + op2 = op; //ie get ready for the Next iteration + } + op2 = op2->Next; + } + op = op->Next; + } + while (op != outrec->Pts); + } +} +//------------------------------------------------------------------------------ + +void ReversePath(Path& p) +{ + std::reverse(p.begin(), p.end()); +} +//------------------------------------------------------------------------------ + +void ReversePaths(Paths& p) +{ + for (Paths::size_type i = 0; i < p.size(); ++i) + ReversePath(p[i]); +} +//------------------------------------------------------------------------------ + +void SimplifyPolygon(const Path &in_poly, Paths &out_polys, PolyFillType fillType) +{ + Clipper c; + c.StrictlySimple(true); + c.AddPath(in_poly, ptSubject, true); + c.Execute(ctUnion, out_polys, fillType, fillType); +} +//------------------------------------------------------------------------------ + +void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType fillType) +{ + Clipper c; + c.StrictlySimple(true); + c.AddPaths(in_polys, ptSubject, true); + c.Execute(ctUnion, out_polys, fillType, fillType); +} +//------------------------------------------------------------------------------ + +void SimplifyPolygons(Paths &polys, PolyFillType fillType) +{ + SimplifyPolygons(polys, polys, fillType); +} +//------------------------------------------------------------------------------ + +inline double DistanceSqrd(const IntPoint& pt1, const IntPoint& pt2) +{ + double Dx = ((double)pt1.X - pt2.X); + double dy = ((double)pt1.Y - pt2.Y); + return (Dx*Dx + dy*dy); +} +//------------------------------------------------------------------------------ + +double DistanceFromLineSqrd( + const IntPoint& pt, const IntPoint& ln1, const IntPoint& ln2) +{ + //The equation of a line in general form (Ax + By + C = 0) + //given 2 points (x�,y�) & (x�,y�) is ... + //(y� - y�)x + (x� - x�)y + (y� - y�)x� - (x� - x�)y� = 0 + //A = (y� - y�); B = (x� - x�); C = (y� - y�)x� - (x� - x�)y� + //perpendicular distance of point (x�,y�) = (Ax� + By� + C)/Sqrt(A� + B�) + //see http://en.wikipedia.org/wiki/Perpendicular_distance + double A = double(ln1.Y - ln2.Y); + double B = double(ln2.X - ln1.X); + double C = A * ln1.X + B * ln1.Y; + C = A * pt.X + B * pt.Y - C; + return (C * C) / (A * A + B * B); +} +//--------------------------------------------------------------------------- + +bool SlopesNearCollinear(const IntPoint& pt1, + const IntPoint& pt2, const IntPoint& pt3, double distSqrd) +{ + //this function is more accurate when the point that's geometrically + //between the other 2 points is the one that's tested for distance. + //ie makes it more likely to pick up 'spikes' ... + if (Abs(pt1.X - pt2.X) > Abs(pt1.Y - pt2.Y)) + { + if ((pt1.X > pt2.X) == (pt1.X < pt3.X)) + return DistanceFromLineSqrd(pt1, pt2, pt3) < distSqrd; + else if ((pt2.X > pt1.X) == (pt2.X < pt3.X)) + return DistanceFromLineSqrd(pt2, pt1, pt3) < distSqrd; + else + return DistanceFromLineSqrd(pt3, pt1, pt2) < distSqrd; + } + else + { + if ((pt1.Y > pt2.Y) == (pt1.Y < pt3.Y)) + return DistanceFromLineSqrd(pt1, pt2, pt3) < distSqrd; + else if ((pt2.Y > pt1.Y) == (pt2.Y < pt3.Y)) + return DistanceFromLineSqrd(pt2, pt1, pt3) < distSqrd; + else + return DistanceFromLineSqrd(pt3, pt1, pt2) < distSqrd; + } +} +//------------------------------------------------------------------------------ + +bool PointsAreClose(IntPoint pt1, IntPoint pt2, double distSqrd) +{ + double Dx = (double)pt1.X - pt2.X; + double dy = (double)pt1.Y - pt2.Y; + return ((Dx * Dx) + (dy * dy) <= distSqrd); +} +//------------------------------------------------------------------------------ + +OutPt* ExcludeOp(OutPt* op) +{ + OutPt* result = op->Prev; + result->Next = op->Next; + op->Next->Prev = result; + result->Idx = 0; + return result; +} +//------------------------------------------------------------------------------ + +void CleanPolygon(const Path& in_poly, Path& out_poly, double distance) +{ + //distance = proximity in units/pixels below which vertices + //will be stripped. Default ~= sqrt(2). + + size_t size = in_poly.size(); + + if (size == 0) + { + out_poly.clear(); + return; + } + + OutPt* outPts = new OutPt[size]; + for (size_t i = 0; i < size; ++i) + { + outPts[i].Pt = in_poly[i]; + outPts[i].Next = &outPts[(i + 1) % size]; + outPts[i].Next->Prev = &outPts[i]; + outPts[i].Idx = 0; + } + + double distSqrd = distance * distance; + OutPt* op = &outPts[0]; + while (op->Idx == 0 && op->Next != op->Prev) + { + if (PointsAreClose(op->Pt, op->Prev->Pt, distSqrd)) + { + op = ExcludeOp(op); + size--; + } + else if (PointsAreClose(op->Prev->Pt, op->Next->Pt, distSqrd)) + { + ExcludeOp(op->Next); + op = ExcludeOp(op); + size -= 2; + } + else if (SlopesNearCollinear(op->Prev->Pt, op->Pt, op->Next->Pt, distSqrd)) + { + op = ExcludeOp(op); + size--; + } + else + { + op->Idx = 1; + op = op->Next; + } + } + + if (size < 3) size = 0; + out_poly.resize(size); + for (size_t i = 0; i < size; ++i) + { + out_poly[i] = op->Pt; + op = op->Next; + } + delete [] outPts; +} +//------------------------------------------------------------------------------ + +void CleanPolygon(Path& poly, double distance) +{ + CleanPolygon(poly, poly, distance); +} +//------------------------------------------------------------------------------ + +void CleanPolygons(const Paths& in_polys, Paths& out_polys, double distance) +{ + out_polys.resize(in_polys.size()); + for (Paths::size_type i = 0; i < in_polys.size(); ++i) + CleanPolygon(in_polys[i], out_polys[i], distance); +} +//------------------------------------------------------------------------------ + +void CleanPolygons(Paths& polys, double distance) +{ + CleanPolygons(polys, polys, distance); +} +//------------------------------------------------------------------------------ + +void Minkowski(const Path& poly, const Path& path, + Paths& solution, bool isSum, bool isClosed) +{ + int delta = (isClosed ? 1 : 0); + size_t polyCnt = poly.size(); + size_t pathCnt = path.size(); + Paths pp; + pp.reserve(pathCnt); + if (isSum) + for (size_t i = 0; i < pathCnt; ++i) + { + Path p; + p.reserve(polyCnt); + for (size_t j = 0; j < poly.size(); ++j) + p.push_back(IntPoint(path[i].X + poly[j].X, path[i].Y + poly[j].Y)); + pp.push_back(p); + } + else + for (size_t i = 0; i < pathCnt; ++i) + { + Path p; + p.reserve(polyCnt); + for (size_t j = 0; j < poly.size(); ++j) + p.push_back(IntPoint(path[i].X - poly[j].X, path[i].Y - poly[j].Y)); + pp.push_back(p); + } + + solution.clear(); + solution.reserve((pathCnt + delta) * (polyCnt + 1)); + for (size_t i = 0; i < pathCnt - 1 + delta; ++i) + for (size_t j = 0; j < polyCnt; ++j) + { + Path quad; + quad.reserve(4); + quad.push_back(pp[i % pathCnt][j % polyCnt]); + quad.push_back(pp[(i + 1) % pathCnt][j % polyCnt]); + quad.push_back(pp[(i + 1) % pathCnt][(j + 1) % polyCnt]); + quad.push_back(pp[i % pathCnt][(j + 1) % polyCnt]); + if (!Orientation(quad)) ReversePath(quad); + solution.push_back(quad); + } +} +//------------------------------------------------------------------------------ + +void MinkowskiSum(const Path& pattern, const Path& path, Paths& solution, bool pathIsClosed) +{ + Minkowski(pattern, path, solution, true, pathIsClosed); + Clipper c; + c.AddPaths(solution, ptSubject, true); + c.Execute(ctUnion, solution, pftNonZero, pftNonZero); +} +//------------------------------------------------------------------------------ + +void TranslatePath(const Path& input, Path& output, const IntPoint delta) +{ + //precondition: input != output + output.resize(input.size()); + for (size_t i = 0; i < input.size(); ++i) + output[i] = IntPoint(input[i].X + delta.X, input[i].Y + delta.Y); +} +//------------------------------------------------------------------------------ + +void MinkowskiSum(const Path& pattern, const Paths& paths, Paths& solution, bool pathIsClosed) +{ + Clipper c; + for (size_t i = 0; i < paths.size(); ++i) + { + Paths tmp; + Minkowski(pattern, paths[i], tmp, true, pathIsClosed); + c.AddPaths(tmp, ptSubject, true); + if (pathIsClosed) + { + Path tmp2; + TranslatePath(paths[i], tmp2, pattern[0]); + c.AddPath(tmp2, ptClip, true); + } + } + c.Execute(ctUnion, solution, pftNonZero, pftNonZero); +} +//------------------------------------------------------------------------------ + +void MinkowskiDiff(const Path& poly1, const Path& poly2, Paths& solution) +{ + Minkowski(poly1, poly2, solution, false, true); + Clipper c; + c.AddPaths(solution, ptSubject, true); + c.Execute(ctUnion, solution, pftNonZero, pftNonZero); +} +//------------------------------------------------------------------------------ + +enum NodeType {ntAny, ntOpen, ntClosed}; + +void AddPolyNodeToPaths(const PolyNode& polynode, NodeType nodetype, Paths& paths) +{ + bool match = true; + if (nodetype == ntClosed) match = !polynode.IsOpen(); + else if (nodetype == ntOpen) return; + + if (!polynode.Contour.empty() && match) + paths.push_back(polynode.Contour); + for (int i = 0; i < polynode.ChildCount(); ++i) + AddPolyNodeToPaths(*polynode.Childs[i], nodetype, paths); +} +//------------------------------------------------------------------------------ + +void PolyTreeToPaths(const PolyTree& polytree, Paths& paths) +{ + paths.resize(0); + paths.reserve(polytree.Total()); + AddPolyNodeToPaths(polytree, ntAny, paths); +} +//------------------------------------------------------------------------------ + +void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths) +{ + paths.resize(0); + paths.reserve(polytree.Total()); + AddPolyNodeToPaths(polytree, ntClosed, paths); +} +//------------------------------------------------------------------------------ + +void OpenPathsFromPolyTree(PolyTree& polytree, Paths& paths) +{ + paths.resize(0); + paths.reserve(polytree.Total()); + //Open paths are top level only, so ... + for (int i = 0; i < polytree.ChildCount(); ++i) + if (polytree.Childs[i]->IsOpen()) + paths.push_back(polytree.Childs[i]->Contour); +} +//------------------------------------------------------------------------------ + +std::ostream& operator <<(std::ostream &s, const IntPoint &p) +{ + s << "(" << p.X << "," << p.Y << ")"; + return s; +} +//------------------------------------------------------------------------------ + +std::ostream& operator <<(std::ostream &s, const Path &p) +{ + if (p.empty()) return s; + Path::size_type last = p.size() -1; + for (Path::size_type i = 0; i < last; i++) + s << "(" << p[i].X << "," << p[i].Y << "), "; + s << "(" << p[last].X << "," << p[last].Y << ")\n"; + return s; +} +//------------------------------------------------------------------------------ + +std::ostream& operator <<(std::ostream &s, const Paths &p) +{ + for (Paths::size_type i = 0; i < p.size(); i++) + s << p[i]; + s << "\n"; + return s; +} +//------------------------------------------------------------------------------ + +} //ClipperLib namespace diff --git a/src/reference/ai_poc/sq_handkp_flower/clipper.hpp b/src/reference/ai_poc/sq_handkp_flower/clipper.hpp new file mode 100644 index 000000000..f6cbe000a --- /dev/null +++ b/src/reference/ai_poc/sq_handkp_flower/clipper.hpp @@ -0,0 +1,389 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _CLIPPER_H_ +#define _CLIPPER_H_ + +#define CLIPPER_VERSION "6.4.2" + +#define use_lines + +//use_deprecated: Enables temporary support for the obsolete functions +//#define use_deprecated + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ClipperLib { + +enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor }; +enum PolyType { ptSubject, ptClip }; +//By far the most widely used winding rules for polygon filling are +//EvenOdd & NonZero (GDI, GDI+, XLib, OpenGL, Cairo, AGG, Quartz, SVG, Gr32) +//Others rules include Positive, Negative and ABS_GTR_EQ_TWO (only in OpenGL) +//see http://glprogramming.com/red/chapter11.html +enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative }; + +#ifdef use_int32 + typedef int cInt; + static cInt const loRange = 0x7FFF; + static cInt const hiRange = 0x7FFF; +#else + typedef signed long long cInt; + static cInt const loRange = 0x3FFFFFFF; + static cInt const hiRange = 0x3FFFFFFFFFFFFFFFLL; + typedef signed long long long64; //used by Int128 class + typedef unsigned long long ulong64; + +#endif + +struct IntPoint { + cInt X; + cInt Y; +#ifdef use_xyz + cInt Z; + IntPoint(cInt x = 0, cInt y = 0, cInt z = 0): X(x), Y(y), Z(z) {}; +#else + IntPoint(cInt x = 0, cInt y = 0): X(x), Y(y) {}; +#endif + + friend inline bool operator== (const IntPoint& a, const IntPoint& b) + { + return a.X == b.X && a.Y == b.Y; + } + friend inline bool operator!= (const IntPoint& a, const IntPoint& b) + { + return a.X != b.X || a.Y != b.Y; + } +}; +//------------------------------------------------------------------------------ + +typedef std::vector< IntPoint > Path; +typedef std::vector< Path > Paths; + +inline Path& operator <<(Path& poly, const IntPoint& p) {poly.push_back(p); return poly;} +inline Paths& operator <<(Paths& polys, const Path& p) {polys.push_back(p); return polys;} + +std::ostream& operator <<(std::ostream &s, const IntPoint &p); +std::ostream& operator <<(std::ostream &s, const Path &p); +std::ostream& operator <<(std::ostream &s, const Paths &p); + +struct DoublePoint +{ + double X; + double Y; + DoublePoint(double x = 0, double y = 0) : X(x), Y(y) {} + DoublePoint(IntPoint ip) : X((double)ip.X), Y((double)ip.Y) {} +}; +//------------------------------------------------------------------------------ + +#ifdef use_xyz +typedef void (*ZFillCallback)(IntPoint& e1bot, IntPoint& e1top, IntPoint& e2bot, IntPoint& e2top, IntPoint& pt); +#endif + +enum InitOptions {ioReverseSolution = 1, ioStrictlySimple = 2, ioPreserveCollinear = 4}; +enum JoinType {jtSquare, jtRound, jtMiter}; +enum EndType {etClosedPolygon, etClosedLine, etOpenButt, etOpenSquare, etOpenRound}; + +class PolyNode; +typedef std::vector< PolyNode* > PolyNodes; + +class PolyNode +{ +public: + PolyNode(); + virtual ~PolyNode(){}; + Path Contour; + PolyNodes Childs; + PolyNode* Parent; + PolyNode* GetNext() const; + bool IsHole() const; + bool IsOpen() const; + int ChildCount() const; +private: + //PolyNode& operator =(PolyNode& other); + unsigned Index; //node index in Parent.Childs + bool m_IsOpen; + JoinType m_jointype; + EndType m_endtype; + PolyNode* GetNextSiblingUp() const; + void AddChild(PolyNode& child); + friend class Clipper; //to access Index + friend class ClipperOffset; +}; + +class PolyTree: public PolyNode +{ +public: + ~PolyTree(){ Clear(); }; + PolyNode* GetFirst() const; + void Clear(); + int Total() const; +private: + //PolyTree& operator =(PolyTree& other); + PolyNodes AllNodes; + friend class Clipper; //to access AllNodes +}; + +bool Orientation(const Path &poly); +double Area(const Path &poly); +int PointInPolygon(const IntPoint &pt, const Path &path); + +void SimplifyPolygon(const Path &in_poly, Paths &out_polys, PolyFillType fillType = pftEvenOdd); +void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType fillType = pftEvenOdd); +void SimplifyPolygons(Paths &polys, PolyFillType fillType = pftEvenOdd); + +void CleanPolygon(const Path& in_poly, Path& out_poly, double distance = 1.415); +void CleanPolygon(Path& poly, double distance = 1.415); +void CleanPolygons(const Paths& in_polys, Paths& out_polys, double distance = 1.415); +void CleanPolygons(Paths& polys, double distance = 1.415); + +void MinkowskiSum(const Path& pattern, const Path& path, Paths& solution, bool pathIsClosed); +void MinkowskiSum(const Path& pattern, const Paths& paths, Paths& solution, bool pathIsClosed); +void MinkowskiDiff(const Path& poly1, const Path& poly2, Paths& solution); + +void PolyTreeToPaths(const PolyTree& polytree, Paths& paths); +void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths); +void OpenPathsFromPolyTree(PolyTree& polytree, Paths& paths); + +void ReversePath(Path& p); +void ReversePaths(Paths& p); + +struct IntRect { cInt left; cInt top; cInt right; cInt bottom; }; + +//enums that are used internally ... +enum EdgeSide { esLeft = 1, esRight = 2}; + +//forward declarations (for stuff used internally) ... +struct TEdge; +struct IntersectNode; +struct LocalMinimum; +struct OutPt; +struct OutRec; +struct Join; + +typedef std::vector < OutRec* > PolyOutList; +typedef std::vector < TEdge* > EdgeList; +typedef std::vector < Join* > JoinList; +typedef std::vector < IntersectNode* > IntersectList; + +//------------------------------------------------------------------------------ + +//ClipperBase is the ancestor to the Clipper class. It should not be +//instantiated directly. This class simply abstracts the conversion of sets of +//polygon coordinates into edge objects that are stored in a LocalMinima list. +class ClipperBase +{ +public: + ClipperBase(); + virtual ~ClipperBase(); + virtual bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed); + bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed); + virtual void Clear(); + IntRect GetBounds(); + bool PreserveCollinear() {return m_PreserveCollinear;}; + void PreserveCollinear(bool value) {m_PreserveCollinear = value;}; +protected: + void DisposeLocalMinimaList(); + TEdge* AddBoundsToLML(TEdge *e, bool IsClosed); + virtual void Reset(); + TEdge* ProcessBound(TEdge* E, bool IsClockwise); + void InsertScanbeam(const cInt Y); + bool PopScanbeam(cInt &Y); + bool LocalMinimaPending(); + bool PopLocalMinima(cInt Y, const LocalMinimum *&locMin); + OutRec* CreateOutRec(); + void DisposeAllOutRecs(); + void DisposeOutRec(PolyOutList::size_type index); + void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2); + void DeleteFromAEL(TEdge *e); + void UpdateEdgeIntoAEL(TEdge *&e); + + typedef std::vector MinimaList; + MinimaList::iterator m_CurrentLM; + MinimaList m_MinimaList; + + bool m_UseFullRange; + EdgeList m_edges; + bool m_PreserveCollinear; + bool m_HasOpenPaths; + PolyOutList m_PolyOuts; + TEdge *m_ActiveEdges; + + typedef std::priority_queue ScanbeamList; + ScanbeamList m_Scanbeam; +}; +//------------------------------------------------------------------------------ + +class Clipper : public virtual ClipperBase +{ +public: + Clipper(int initOptions = 0); + bool Execute(ClipType clipType, + Paths &solution, + PolyFillType fillType = pftEvenOdd); + bool Execute(ClipType clipType, + Paths &solution, + PolyFillType subjFillType, + PolyFillType clipFillType); + bool Execute(ClipType clipType, + PolyTree &polytree, + PolyFillType fillType = pftEvenOdd); + bool Execute(ClipType clipType, + PolyTree &polytree, + PolyFillType subjFillType, + PolyFillType clipFillType); + bool ReverseSolution() { return m_ReverseOutput; }; + void ReverseSolution(bool value) {m_ReverseOutput = value;}; + bool StrictlySimple() {return m_StrictSimple;}; + void StrictlySimple(bool value) {m_StrictSimple = value;}; + //set the callback function for z value filling on intersections (otherwise Z is 0) +#ifdef use_xyz + void ZFillFunction(ZFillCallback zFillFunc); +#endif +protected: + virtual bool ExecuteInternal(); +private: + JoinList m_Joins; + JoinList m_GhostJoins; + IntersectList m_IntersectList; + ClipType m_ClipType; + typedef std::list MaximaList; + MaximaList m_Maxima; + TEdge *m_SortedEdges; + bool m_ExecuteLocked; + PolyFillType m_ClipFillType; + PolyFillType m_SubjFillType; + bool m_ReverseOutput; + bool m_UsingPolyTree; + bool m_StrictSimple; +#ifdef use_xyz + ZFillCallback m_ZFill; //custom callback +#endif + void SetWindingCount(TEdge& edge); + bool IsEvenOddFillType(const TEdge& edge) const; + bool IsEvenOddAltFillType(const TEdge& edge) const; + void InsertLocalMinimaIntoAEL(const cInt botY); + void InsertEdgeIntoAEL(TEdge *edge, TEdge* startEdge); + void AddEdgeToSEL(TEdge *edge); + bool PopEdgeFromSEL(TEdge *&edge); + void CopyAELToSEL(); + void DeleteFromSEL(TEdge *e); + void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2); + bool IsContributing(const TEdge& edge) const; + bool IsTopHorz(const cInt XPos); + void DoMaxima(TEdge *e); + void ProcessHorizontals(); + void ProcessHorizontal(TEdge *horzEdge); + void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt); + OutPt* AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt); + OutRec* GetOutRec(int idx); + void AppendPolygon(TEdge *e1, TEdge *e2); + void IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &pt); + OutPt* AddOutPt(TEdge *e, const IntPoint &pt); + OutPt* GetLastOutPt(TEdge *e); + bool ProcessIntersections(const cInt topY); + void BuildIntersectList(const cInt topY); + void ProcessIntersectList(); + void ProcessEdgesAtTopOfScanbeam(const cInt topY); + void BuildResult(Paths& polys); + void BuildResult2(PolyTree& polytree); + void SetHoleState(TEdge *e, OutRec *outrec); + void DisposeIntersectNodes(); + bool FixupIntersectionOrder(); + void FixupOutPolygon(OutRec &outrec); + void FixupOutPolyline(OutRec &outrec); + bool IsHole(TEdge *e); + bool FindOwnerFromSplitRecs(OutRec &outRec, OutRec *&currOrfl); + void FixHoleLinkage(OutRec &outrec); + void AddJoin(OutPt *op1, OutPt *op2, const IntPoint offPt); + void ClearJoins(); + void ClearGhostJoins(); + void AddGhostJoin(OutPt *op, const IntPoint offPt); + bool JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2); + void JoinCommonEdges(); + void DoSimplePolygons(); + void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec); + void FixupFirstLefts2(OutRec* InnerOutRec, OutRec* OuterOutRec); + void FixupFirstLefts3(OutRec* OldOutRec, OutRec* NewOutRec); +#ifdef use_xyz + void SetZ(IntPoint& pt, TEdge& e1, TEdge& e2); +#endif +}; +//------------------------------------------------------------------------------ + +class ClipperOffset +{ +public: + ClipperOffset(double miterLimit = 2.0, double roundPrecision = 0.25); + ~ClipperOffset(); + void AddPath(const Path& path, JoinType joinType, EndType endType); + void AddPaths(const Paths& paths, JoinType joinType, EndType endType); + void Execute(Paths& solution, double delta); + void Execute(PolyTree& solution, double delta); + void Clear(); + double MiterLimit; + double ArcTolerance; +private: + Paths m_destPolys; + Path m_srcPoly; + Path m_destPoly; + std::vector m_normals; + double m_delta, m_sinA, m_sin, m_cos; + double m_miterLim, m_StepsPerRad; + IntPoint m_lowest; + PolyNode m_polyNodes; + + void FixOrientations(); + void DoOffset(double delta); + void OffsetPoint(int j, int& k, JoinType jointype); + void DoSquare(int j, int k); + void DoMiter(int j, int k, double r); + void DoRound(int j, int k); +}; +//------------------------------------------------------------------------------ + +class clipperException : public std::exception +{ + public: + clipperException(const char* description): m_descr(description) {} + virtual ~clipperException() throw() {} + virtual const char* what() const throw() {return m_descr.c_str();} + private: + std::string m_descr; +}; +//------------------------------------------------------------------------------ + +} //ClipperLib namespace + +#endif //clipper_hpp + + diff --git a/src/reference/ai_poc/sq_handkp_flower/flower_recognition.cc b/src/reference/ai_poc/sq_handkp_flower/flower_recognition.cc new file mode 100644 index 000000000..79da3efd9 --- /dev/null +++ b/src/reference/ai_poc/sq_handkp_flower/flower_recognition.cc @@ -0,0 +1,122 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "flower_recognition.h" +#include "utils.h" + +FlowerRecognition::FlowerRecognition(const char *kmodel_file, const int debug_mode) : AIBase(kmodel_file,"FlowerRecognition",debug_mode) +{ + model_name_ = "FlowerRecognition"; + ai2d_out_tensor_ = get_input_tensor(0); +} + +FlowerRecognition::FlowerRecognition(const char *kmodel_file, FrameCHWSize isp_shape, uintptr_t vaddr, uintptr_t paddr, const int debug_mode) : AIBase(kmodel_file,"FlowerRecognition", debug_mode) +{ + model_name_ = "FlowerRecognition"; + // input->isp(Fixed size) + vaddr_ = vaddr; + isp_shape_ = isp_shape; + dims_t in_shape{1, isp_shape.channel, isp_shape.height, isp_shape.width}; +#if 0 + int in_size = isp_shape.channel * isp_shape.height * isp_shape.width; + ai2d_in_tensor_ = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, { (gsl::byte *)vaddr, in_size }, + true, hrt::pool_shared).expect("cannot create input tensor"); +#else + ai2d_in_tensor_ = hrt::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("create ai2d input tensor failed"); +#endif + // ouput(Fixed size) + dims_t out_shape{1, input_shapes_[0][1], input_shapes_[0][2], input_shapes_[0][3]}; + ai2d_out_tensor_ = get_input_tensor(0); +} + +FlowerRecognition::~FlowerRecognition() +{ +} + +void FlowerRecognition::pre_process(cv::Mat ori_img, Bbox &bbox) +{ + ScopedTiming st(model_name_ + " pre_process image", debug_mode_); + + std::vector chw_vec; + Utils::bgr2rgb_and_hwc2chw(ori_img, chw_vec); + Utils::crop_resize({ori_img.channels(), ori_img.rows, ori_img.cols}, chw_vec, bbox, ai2d_out_tensor_); +} + +void FlowerRecognition::pre_process(Bbox &bbox) +{ + ScopedTiming st(model_name_ + " pre_process_video", debug_mode_); +#if 1 + size_t isp_size = isp_shape_.channel * isp_shape_.height * isp_shape_.width; + auto buf = ai2d_in_tensor_.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(buf.data()), (void *)vaddr_, isp_size); + hrt::sync(ai2d_in_tensor_, sync_op_t::sync_write_back, true).expect("sync write_back failed"); +#endif + Utils::crop_resize(bbox, ai2d_builder_, ai2d_in_tensor_, ai2d_out_tensor_); +} + +void FlowerRecognition::inference() +{ + this->run(); + this->get_output(); +} + +std::string FlowerRecognition::post_process() +{ + ScopedTiming st(model_name_ + " post_process", debug_mode_); + float *output = p_outputs_[0]; + float pred[102] = {0}; + softmax(output, pred, output_shapes_[0][1] ); + auto it = std::max_element(pred, pred + output_shapes_[0][1]); + size_t idx = it - pred; + std::string text = labels[idx] + ":" + std::to_string(round(*it * 100) / 100.0); + std::cout<<"predicted: "< +#include + +#include "utils.h" +#include "ai_base.h" + +/** + * @brief 花卉识别 + * 主要封装了对于每一帧图片,从预处理、运行到后处理给出结果的过程 + */ +class FlowerRecognition : public AIBase +{ +public: + /** + * @brief FlowerRecognition构造函数,加载kmodel,并初始化kmodel输入、输出 + * @param kmodel_file kmodel文件路径 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + FlowerRecognition(const char *kmodel_file, const int debug_mode = 1); + + /** + * @brief FlowerRecognition构造函数,加载kmodel,并初始化kmodel输入、输出 + * @param kmodel_file kmodel文件路径 + * @param isp_shape isp输入大小(chw) + * @param vaddr isp对应虚拟地址 + * @param paddr isp对应物理地址 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + FlowerRecognition(const char *kmodel_file, FrameCHWSize isp_shape, uintptr_t vaddr, uintptr_t paddr, const int debug_mode = 1); + + /** + * @brief FlowerRecognition析构函数 + * @return None + */ + ~FlowerRecognition(); + + /** + * @brief 图片预处理(ai2d for image) + * @param ori_img 原始图片 + * @param bbox 花卉在原图上的位置坐标(x,y,w,h) + + * @return None + */ + void pre_process(cv::Mat ori_img, Bbox &bbox); + + /** + * @brief 视频流预处理(ai2d for isp) + * @param bbox 花卉在原图上的位置坐标(x,y,w,h) + * @return None + */ + void pre_process(Bbox &bbox); + + /** + * @brief kmodel推理 + * @return None + */ + void inference(); + + /** + * @brief kmodel推理结果后处理 + * @return 识别结果 + */ + string post_process(); + + void softmax(float* x, float* dx, uint32_t len); + + std::vector labels + { + "pink primrose", "hard-leaved pocket orchid", "snapdragon", "trumpet creeper", "blackberry lily", "colts foot", "king protea", "spear thistle", "yellow iris", "globe-flower", "purple coneflower", "peruvian lily", "balloon flower", "giant white arum lily", "canterbury bells", "fire lily", "pincushion flower", "fritillary", "red ginger", "grape hyacinth", "corn poppy", "prince of wales feathers", "stemless gentian", "artichoke", "sweet william", "sweet pea", "carnation", "garden phlox", "love in the mist", "mexican aster", "alpine sea holly", "ruby-lipped cattleya", "cape flower", "great masterwort", "siam tulip", "lenten rose", "english marigold", "barbeton daisy", "daffodil", "sword lily", "poinsettia", "bolero deep blue", "wallflower", "marigold", "buttercup", "oxeye daisy", "common dandelion", "tiger lily", "petunia", "wild pansy", "primula", "sunflower", "pelargonium", "bishop of llandaff", "gaura", "geranium", "orange dahlia", "pink-yellow dahlia", "moon orchid", "cautleya spicata", "japanese anemone", "black-eyed susan", "silverbush", "californian poppy", "osteospermum", "spring crocus", "bearded iris", "windflower", "tree poppy", "bird of paradise", "gazania", "azalea", "water lily", "rose", "thorn apple", "morning glory", "passion flower", "lotus lotus", "toad lily", "anthurium", "monkshood", "frangipani", "clematis", "hibiscus", "columbine", "desert-rose", "tree mallow", "magnolia", "cyclamen", "watercress", "canna lily", "globe thistle", "hippeastrum", "bee balm", "ball moss", "foxglove", "bougainvillea", "camellia", "mallow", "mexican petunia", "bromelia", "blanket flower" + }; + +private: + + std::unique_ptr ai2d_builder_; // ai2d构建器 + runtime_tensor ai2d_in_tensor_; // ai2d输入tensor + runtime_tensor ai2d_out_tensor_; // ai2d输出tensor + uintptr_t vaddr_; // isp的虚拟地址 + FrameCHWSize isp_shape_; // isp对应的地址大小 +}; +#endif diff --git a/src/reference/ai_poc/sq_handkp_flower/hand_detection.cc b/src/reference/ai_poc/sq_handkp_flower/hand_detection.cc new file mode 100644 index 000000000..a7e78fabe --- /dev/null +++ b/src/reference/ai_poc/sq_handkp_flower/hand_detection.cc @@ -0,0 +1,200 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "hand_detection.h" +#include + +HandDetection::HandDetection(const char *kmodel_file, float obj_thresh, float nms_thresh, FrameSize frame_size,const int debug_mode) +:obj_thresh_(obj_thresh), nms_thresh_(nms_thresh),frame_size_(frame_size),AIBase(kmodel_file, "HandDetection", debug_mode) +{ + model_name_ = "HandDetection"; + classes_num_ = 1; + int net_len = input_shapes_[0][2]; + ai2d_out_tensor_ = get_input_tensor(0); +} + +HandDetection::HandDetection(const char *kmodel_file, float obj_thresh, float nms_thresh, FrameSize frame_size, FrameCHWSize isp_shape, uintptr_t vaddr, uintptr_t paddr, const int debug_mode) +: obj_thresh_(obj_thresh), nms_thresh_(nms_thresh),frame_size_(frame_size), AIBase(kmodel_file,"HandDetection", debug_mode) +{ + model_name_ = "HandDetection"; + classes_num_ = 1; + vaddr_ = vaddr; + isp_shape_ = isp_shape; + dims_t in_shape{1, isp_shape.channel, isp_shape.height, isp_shape.width}; + int isp_size = isp_shape.channel * isp_shape.height * isp_shape.width; +#if 0 + int in_size = isp_shape.channel * isp_shape.height * isp_shape.width; + ai2d_in_tensor_ = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, { (gsl::byte *)vaddr, in_size }, + true, hrt::pool_shared).expect("cannot create input tensor"); +#else + ai2d_in_tensor_ = hrt::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("create ai2d input tensor failed"); +#endif + ai2d_out_tensor_ = get_input_tensor(0); + Utils::padding_resize(isp_shape, {input_shapes_[0][3], input_shapes_[0][2]}, ai2d_builder_, ai2d_in_tensor_, ai2d_out_tensor_, cv::Scalar(114, 114, 114)); +} + + +HandDetection::~HandDetection() +{ +} + +// ai2d for image +void HandDetection::pre_process(cv::Mat ori_img) +{ + ScopedTiming st(model_name_ + " pre_process image", debug_mode_); + std::vector rgb_chw_vec; + Utils::bgr2rgb_and_hwc2chw(ori_img, rgb_chw_vec); + Utils::padding_resize({ori_img.channels(), ori_img.rows, ori_img.cols}, rgb_chw_vec, {input_shapes_[0][3], input_shapes_[0][2]}, ai2d_out_tensor_, cv::Scalar(114, 114, 114)); +} + +// ai2d for video +void HandDetection::pre_process() +{ + ScopedTiming st(model_name_ + " pre_process_video", debug_mode_); +#if 0 + ai2d_builder_->invoke(ai2d_in_tensor_, ai2d_out_tensor_).expect("error occurred in ai2d running"); +#else + size_t isp_size = isp_shape_.channel * isp_shape_.height * isp_shape_.width; + auto buf = ai2d_in_tensor_.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(buf.data()), (void *)vaddr_, isp_size); + hrt::sync(ai2d_in_tensor_, sync_op_t::sync_write_back, true).expect("sync write_back failed"); + ai2d_builder_->invoke(ai2d_in_tensor_, ai2d_out_tensor_).expect("error occurred in ai2d running"); +#endif +} + +void HandDetection::inference() +{ + this->run(); + this->get_output(); +} + +void HandDetection::post_process(std::vector &result) +{ + auto boxes0 = decode_infer(p_outputs_[0], 8, frame_size_, anchors_0); + result.insert(result.begin(), boxes0.begin(), boxes0.end()); + auto boxes1 = decode_infer(p_outputs_[1], 16, frame_size_, anchors_1); + result.insert(result.begin(), boxes1.begin(), boxes1.end()); + auto boxes2 = decode_infer(p_outputs_[2], 32, frame_size_, anchors_2); + result.insert(result.begin(), boxes2.begin(), boxes2.end()); + nms(result); +} + +void HandDetection::nms(std::vector &input_boxes) +{ + std::sort(input_boxes.begin(), input_boxes.end(), [](BoxInfo a, BoxInfo b) { return a.score > b.score; }); + std::vector vArea(input_boxes.size()); + for (int i = 0; i < int(input_boxes.size()); ++i) + { + vArea[i] = (input_boxes.at(i).x2 - input_boxes.at(i).x1 + 1) + * (input_boxes.at(i).y2 - input_boxes.at(i).y1 + 1); + } + for (int i = 0; i < int(input_boxes.size()); ++i) + { + for (int j = i + 1; j < int(input_boxes.size());) + { + float xx1 = std::max(input_boxes[i].x1, input_boxes[j].x1); + float yy1 = std::max(input_boxes[i].y1, input_boxes[j].y1); + float xx2 = std::min(input_boxes[i].x2, input_boxes[j].x2); + float yy2 = std::min(input_boxes[i].y2, input_boxes[j].y2); + float w = std::max(float(0), xx2 - xx1 + 1); + float h = std::max(float(0), yy2 - yy1 + 1); + float inter = w * h; + float ovr = inter / (vArea[i] + vArea[j] - inter); + if (ovr >= nms_thresh_) + { + input_boxes.erase(input_boxes.begin() + j); + vArea.erase(vArea.begin() + j); + } + else + { + j++; + } + } + } +} + +std::vector HandDetection::decode_infer(float *data, int stride, FrameSize frame_size, float anchors[][2]) +{ +//std::cout << "decode_infer!\n"; + float ratiow = (float)input_shapes_[0][3] / frame_size.width; + float ratioh = (float)input_shapes_[0][2] / frame_size.height; + float gain = ratiow < ratioh ? ratiow : ratioh; + std::vector result; + int grid_size = input_shapes_[0][2] / stride; + int one_rsize = classes_num_ + 5; + float cx, cy, w, h; + for (int shift_y = 0; shift_y < grid_size; shift_y++) + { + for (int shift_x = 0; shift_x < grid_size; shift_x++) + { + int loc = shift_x + shift_y * grid_size; + for (int i = 0; i < 3; i++) + { + float *record = data + (loc * 3 + i) * one_rsize; + float *cls_ptr = record + 5; + for (int cls = 0; cls < classes_num_; cls++) + { + // float score = sigmoid(cls_ptr[cls]) * sigmoid(record[4]); + float score = cls_ptr[cls] * record[4]; + if (score > obj_thresh_) + { + cx = (record[0] * 2.f - 0.5f + (float)shift_x) * (float)stride; + cy = (record[1] * 2.f - 0.5f + (float)shift_y) * (float)stride; + w = pow(record[2] * 2.f, 2) * anchors[i][0]; + h = pow(record[3] * 2.f, 2) * anchors[i][1]; + + cx -= ((input_shapes_[0][3] - frame_size.width * gain) / 2); + cy -= ((input_shapes_[0][2] - frame_size.height * gain) / 2); + cx /= gain; + cy /= gain; + w /= gain; + h /= gain; + BoxInfo box; + box.x1 = std::max(0, std::min(int(frame_size.width), int(cx - w / 2.f))); + box.y1 = std::max(0, std::min(int(frame_size.height), int(cy - h / 2.f))); + box.x2 = std::max(0, std::min(int(frame_size.width), int(cx + w / 2.f))); + box.y2 = std::max(0, std::min(int(frame_size.height), int(cy + h / 2.f))); + + #if defined(CONFIG_BOARD_K230_CANMV) + if (abs(box.y1-box.y2)< 0.1*frame_size.height) + continue; + if ((abs(box.x1-box.x2)< 0.25*frame_size.width) && ((box.x1 < 0.03*frame_size.width) || (box.x2 > 0.97*frame_size.width))) + continue; + if ((abs(box.x1-box.x2)< 0.15*frame_size.width) && ((box.x1 < 0.01*frame_size.width) || (box.x2 > 0.99*frame_size.width))) + continue; + #else + if ((abs(box.x1-box.x2)< 0.1*frame_size.width) || (abs(box.y1-box.y2)< 0.1*frame_size.height)) + continue; + #endif + + box.score = score; + box.label = cls; + result.push_back(box); + } + } + } + } + } + return result; +} diff --git a/src/reference/ai_poc/sq_handkp_flower/hand_detection.h b/src/reference/ai_poc/sq_handkp_flower/hand_detection.h new file mode 100644 index 000000000..2ebd414bf --- /dev/null +++ b/src/reference/ai_poc/sq_handkp_flower/hand_detection.h @@ -0,0 +1,157 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _HAND_DETECTION_H +#define _HAND_DETECTION_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#include +#include +#include + +#include "utils.h" +#include "ai_base.h" + +using namespace nncase; +using namespace nncase::runtime; +using namespace nncase::runtime::detail; +using namespace std; + +/** + * @brief 手掌检测 + * 主要封装了对于每一帧图片,从预处理、运行到后处理给出结果的过程 + */ +class HandDetection:public AIBase +{ +public: + /** + * @brief HandDetection构造函数,加载kmodel,并初始化kmodel输入、输出 + * @param kmodel_file kmodel文件路径 + * @param obj_thresh 手掌检测阈值,用于过滤roi + * @param nms_thresh 手掌检测框阈值,用于过滤重复roi + * @param frame_size 手掌检测输入图片尺寸 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + + // for image + HandDetection(const char *kmodel_file, float obj_thresh, float nms_thresh, FrameSize frame_size,const int debug_mode); + + /** + * @brief HandDetection构造函数,加载kmodel,并初始化kmodel输入、输出和手掌检测阈值 + * @param kmodel_file kmodel文件路径 + * @param obj_thresh 手掌检测阈值,用于过滤roi + * @param nms_thresh 手掌检测框阈值,用于过滤重复roi + * @param frame_size 手掌检测输入图片尺寸 + * @param isp_shape isp输入大小(chw) + * @param vaddr isp对应虚拟地址 + * @param paddr isp对应物理地址 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + + // for_video + HandDetection(const char *kmodel_file, float obj_thresh, float nms_thresh, FrameSize frame_size, FrameCHWSize isp_shape, uintptr_t vaddr, uintptr_t paddr, const int debug_mode); + + /** + * @brief HandDetection析构函数 + * @return None + */ + ~HandDetection(); + + /** + * @brief 图片预处理 + * @param ori_img 原始图片 + * @return None + */ + void pre_process(cv::Mat ori_img); + + /** + * @brief 视频流预处理(ai2d for isp) + * @return None + */ + void pre_process(); + + /** + * @brief kmodel推理 + * @return None + */ + void inference(); + + /** + * @brief kmodel推理结果后处理 + * @param results 后处理之后的基于原始图像的{检测框坐标点、得分和标签}集合 + * @return None + */ + void post_process(std::vector &result); + + std::vector labels_ = {"hand"}; //模型输出类别名称 + + +private: + + std::unique_ptr ai2d_builder_; // ai2d构建器 + runtime_tensor ai2d_in_tensor_; // ai2d输入tensor + runtime_tensor ai2d_out_tensor_; // ai2d输出tensor + uintptr_t vaddr_; // isp的虚拟地址 + FrameCHWSize isp_shape_; // isp对应的地址大小 + + float obj_thresh_; // 手掌检测阈值 + float nms_thresh_; // 手掌检测框nms阈值 + FrameSize frame_size_; // 输入图片尺寸 + int classes_num_; // 模型输出类别数 + + float anchors_0[3][2] = { { 26,27 }, { 53,52 }, { 75,71 } }; + float anchors_1[3][2] = { { 80,99 }, { 106,82 }, { 99,134 } }; + float anchors_2[3][2] = { { 140,113 }, { 161,172 }, { 245,276 } }; + + /** + * @brief 非极大值抑制 + * @param input_boxes 后处理之后的基于原始图像的{检测框坐标点、得分和标签}集合 + * @return None + */ + void nms(std::vector &input_boxes); + + /** + * @brief 预处理模型输出结果 + * @param data 指向模型推理得到的首个roi置信度的指针 + * @param stride 模型推理得到的feature相比模型输入的下采样倍数 + * @param frame_size 原始图像/帧宽高,用于将结果放到原始图像大小 + * @param anchors 模型推理得到的feature对应的anchor + * @return 每个feature对应的结果映射回原始图像的{检测框坐标点、得分和标签}集合 + */ + std::vector decode_infer(float *data, int stride, FrameSize frame_size, float anchors[][2]); +}; +#endif diff --git a/src/reference/ai_poc/sq_handkp_flower/hand_keypoint.cc b/src/reference/ai_poc/sq_handkp_flower/hand_keypoint.cc new file mode 100644 index 000000000..5169fcba9 --- /dev/null +++ b/src/reference/ai_poc/sq_handkp_flower/hand_keypoint.cc @@ -0,0 +1,175 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "hand_keypoint.h" + +HandKeypoint::HandKeypoint(const char *kmodel_file, const int debug_mode) +:AIBase(kmodel_file, "HandKeypoint", debug_mode) +{ + model_name_ = "HandKeypoint"; + ai2d_out_tensor_ = get_input_tensor(0); +} + +HandKeypoint::HandKeypoint(const char *kmodel_file, FrameCHWSize isp_shape, uintptr_t vaddr, uintptr_t paddr, const int debug_mode) +: AIBase(kmodel_file,"HandKeypoint", debug_mode) +{ + model_name_ = "HandKeypoint"; + vaddr_ = vaddr; + isp_shape_ = isp_shape; + dims_t in_shape{1, isp_shape.channel, isp_shape.height, isp_shape.width}; + int isp_size = isp_shape.channel * isp_shape.height * isp_shape.width; +#if 0 + int in_size = isp_shape.channel * isp_shape.height * isp_shape.width; + ai2d_in_tensor_ = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, { (gsl::byte *)vaddr, in_size }, + true, hrt::pool_shared).expect("cannot create input tensor"); +#else + ai2d_in_tensor_ = hrt::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("create ai2d input tensor failed"); +#endif + ai2d_out_tensor_ = get_input_tensor(0); +} + +HandKeypoint::~HandKeypoint() +{ +} + +void HandKeypoint::pre_process(cv::Mat ori_img, Bbox &bbox) +{ + ScopedTiming st(model_name_ + " pre_process image", debug_mode_); + std::vector chw_vec; + Utils::hwc_to_chw(ori_img, chw_vec); + Utils::crop_resize({ori_img.channels(), ori_img.rows, ori_img.cols}, chw_vec, bbox, ai2d_out_tensor_); +} + +// for video +void HandKeypoint::pre_process(Bbox &bbox) +{ + ScopedTiming st(model_name_ + " pre_process_video", debug_mode_); +#if 1 + size_t isp_size = isp_shape_.channel * isp_shape_.height * isp_shape_.width; + auto buf = ai2d_in_tensor_.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(buf.data()), (void *)vaddr_, isp_size); + hrt::sync(ai2d_in_tensor_, sync_op_t::sync_write_back, true).expect("sync write_back failed"); +#endif + Utils::crop_resize(bbox, ai2d_builder_, ai2d_in_tensor_, ai2d_out_tensor_); +} + +void HandKeypoint::inference() +{ + this->run(); + this->get_output(); +} + +void HandKeypoint::draw_keypoints(cv::Mat &img, Bbox &bbox, bool pic_mode) +{ + ScopedTiming st(model_name_ + " draw_keypoints", debug_mode_); + int src_width = img.cols, src_height = img.rows; + float *pred = p_outputs_[0]; + // 绘制关键点像素坐标 + int64_t output_tensor_size = output_shapes_[0][1];// 关键点输出 (x,y)*21= 42 + std::vectorresults(output_tensor_size); + if(pic_mode) + { + for (unsigned i = 0; i < output_tensor_size / 2; i++) + { + float x_kp; + float y_kp; + x_kp = pred[i * 2] * bbox.w + bbox.x; + y_kp = pred[i * 2 + 1] * bbox.h + bbox.y; + + results[i * 2] = static_cast(x_kp); + results[i * 2 + 1] = static_cast(y_kp); + cv::circle(img, cv::Point(results[i * 2], results[i * 2 + 1]), 2, cv::Scalar(255, 155, 0), 3); + + } + + for (unsigned k = 0; k < 5; k++) + { + int i = k*8; + unsigned char R = 255, G = 0, B = 0; + + switch(k) + { + case 0:R = 255; G = 0; B = 0;break; + case 1:R = 255; G = 0; B = 255;break; + case 2:R = 255; G = 255; B = 0;break; + case 3:R = 0; G = 255; B = 0;break; + case 4:R = 0; G = 0; B = 255;break; + default: std::cout << "error" << std::endl; + } + + cv::line(img, cv::Point(results[0], results[1]), cv::Point(results[i + 2], results[i + 3]), cv::Scalar(B,G,R), 2, cv::LINE_AA); + cv::line(img, cv::Point(results[i + 2], results[i + 3]), cv::Point(results[i + 4], results[i + 5]), cv::Scalar(B, G, R), 2, cv::LINE_AA); + cv::line(img, cv::Point(results[i + 4], results[i + 5]), cv::Point(results[i + 6], results[i + 7]), cv::Scalar(B, G, R), 2, cv::LINE_AA); + cv::line(img, cv::Point(results[i + 6], results[i + 7]), cv::Point(results[i + 8], results[i + 9]), cv::Scalar(B, G, R), 2, cv::LINE_AA); + } + } + else + { + int osd_width = img.cols; + int osd_height = img.rows; + int SENSOR_HEIGHT = isp_shape_.height; + int SENSOR_WIDTH = isp_shape_.width; + for (unsigned i = 0; i < output_tensor_size / 2; i++) + { + float x_kp; + float y_kp; + x_kp = pred[i * 2] * bbox.w + bbox.x; + y_kp = pred[i * 2 + 1] * bbox.h + bbox.y; + + results[i * 2] = x_kp / SENSOR_WIDTH * osd_width; + results[i * 2 + 1] = y_kp / SENSOR_HEIGHT * osd_height; + cv::circle(img, cv::Point(results[i * 2], results[i * 2 + 1]), 2, cv::Scalar(255, 255, 155, 0), 3); + + } + + for (unsigned k = 0; k < 5; k++) + { + int i = k*8; + unsigned char R = 255, G = 0, B = 0; + + switch(k) + { + case 0:R = 255; G = 0; B = 0;break; + case 1:R = 255; G = 0; B = 255;break; + case 2:R = 255; G = 255; B = 0;break; + case 3:R = 0; G = 255; B = 0;break; + case 4:R = 0; G = 0; B = 255;break; + default: std::cout << "error" << std::endl; + } + + cv::line(img, cv::Point(results[0], results[1]), cv::Point(results[i + 2], results[i + 3]), cv::Scalar(255, B,G,R), 2, cv::LINE_AA); + cv::line(img, cv::Point(results[i + 2], results[i + 3]), cv::Point(results[i + 4], results[i + 5]), cv::Scalar(255, B, G, R), 2, cv::LINE_AA); + cv::line(img, cv::Point(results[i + 4], results[i + 5]), cv::Point(results[i + 6], results[i + 7]), cv::Scalar(255, B, G, R), 2, cv::LINE_AA); + cv::line(img, cv::Point(results[i + 6], results[i + 7]), cv::Point(results[i + 8], results[i + 9]), cv::Scalar(255, B, G, R), 2, cv::LINE_AA); + } + } + +} + +vector HandKeypoint::get_out() +{ + return p_outputs_; +} + + diff --git a/src/reference/ai_poc/sq_handkp_flower/hand_keypoint.h b/src/reference/ai_poc/sq_handkp_flower/hand_keypoint.h new file mode 100644 index 000000000..f9b07dcd7 --- /dev/null +++ b/src/reference/ai_poc/sq_handkp_flower/hand_keypoint.h @@ -0,0 +1,127 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _HAND_KEYPOINT_H +#define _HAND_KEYPOINT_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +//#include +#include +#include + +#include "utils.h" +#include "ai_base.h" + + +using namespace nncase; +using namespace nncase::runtime; +using namespace nncase::runtime::detail; +using namespace std; + +/** + * @brief 手部关键点检测 + * 主要封装了对于每一帧图片,从预处理、运行到后处理给出结果的过程 + */ +class HandKeypoint: public AIBase +{ +public: + /** + * @brief HandKeypoint构造函数,加载kmodel,并初始化kmodel输入、输出 + * @param kmodel_file kmodel文件路径 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + HandKeypoint(const char *kmodel_file,const int debug_mode=0); + + /** + * @brief HandKeypoint构造函数,加载kmodel,并初始化kmodel输入、输出 + * @param kmodel_file kmodel文件路径 + * @param isp_shape isp输入大小(chw) + * @param vaddr isp对应虚拟地址 + * @param paddr isp对应物理地址 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + // for video + HandKeypoint(const char *kmodel_file, FrameCHWSize isp_shape, uintptr_t vaddr, uintptr_t paddr, const int debug_mode); + + /** + * @brief HandKeypoint析构函数 + * @return None + */ + ~HandKeypoint(); + + /** + * @brief 图片预处理 + * @param ori_img 原始图片 + * @param bbox 原始手掌检测框位置 + * @return None + */ + void pre_process(cv::Mat ori_img, Bbox &bbox); + + /** + * @brief 视频流预处理(ai2d for isp) + * @param bbox 原始手掌检测框位置 + * @return None + */ + void pre_process(Bbox &bbox); + + /** + * @brief kmodel推理 + * @return None + */ + void inference(); + + /** + * @brief 将手部关键点画到原图 + * @param img 原图 + * @param bbox 手部关键点输入框在原图的显示 + * @param pic_mode ture(原图片),false(osd) + * @return None + */ + void draw_keypoints(cv::Mat &img, Bbox &bbox, bool pic_mode); + + vector get_out(); + +private: + std::unique_ptr ai2d_builder_; // ai2d构建器 + runtime_tensor ai2d_in_tensor_; // ai2d输入tensor + runtime_tensor ai2d_out_tensor_; // ai2d输出tensor + uintptr_t vaddr_; // isp的虚拟地址 + FrameCHWSize isp_shape_; // isp对应的地址大小 + +}; +#endif diff --git a/src/reference/ai_poc/sq_handkp_flower/hungarian.cpp b/src/reference/ai_poc/sq_handkp_flower/hungarian.cpp new file mode 100644 index 000000000..27a280d36 --- /dev/null +++ b/src/reference/ai_poc/sq_handkp_flower/hungarian.cpp @@ -0,0 +1,411 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Part of the code is referenced from https://github.com/mcximing/sort-cpp. The orignal code are published under the BSD license. + */ + +#include "hungarian.h" +#include +#include +#include + + +HungarianAlgorithm::HungarianAlgorithm(){} +HungarianAlgorithm::~HungarianAlgorithm(){} + + +//********************************************************// +// A single function wrapper for solving assignment problem. +//********************************************************// +double HungarianAlgorithm::Solve(vector>& DistMatrix, vector& Assignment) +{ + unsigned int nRows = DistMatrix.size(); + unsigned int nCols = DistMatrix[0].size(); + + double *distMatrixIn = new double[nRows * nCols]; + int *assignment = new int[nRows]; + double cost = 0.0; + + // Fill in the distMatrixIn. Mind the index is "i + nRows * j". + // Here the cost matrix of size MxN is defined as a double precision array of N*M elements. + // In the solving functions matrices are seen to be saved MATLAB-internally in row-order. + // (i.e. the matrix [1 2; 3 4] will be stored as a vector [1 3 2 4], NOT [1 2 3 4]). + for (unsigned int i = 0; i < nRows; i++) + for (unsigned int j = 0; j < nCols; j++) + distMatrixIn[i + nRows * j] = DistMatrix[i][j]; + + // call solving function + assignmentoptimal(assignment, &cost, distMatrixIn, nRows, nCols); + + Assignment.clear(); + for (unsigned int r = 0; r < nRows; r++) + Assignment.push_back(assignment[r]); + + delete[] distMatrixIn; + delete[] assignment; + return cost; +} + + +//********************************************************// +// Solve optimal solution for assignment problem using Munkres algorithm, also known as Hungarian Algorithm. +//********************************************************// +void HungarianAlgorithm::assignmentoptimal(int *assignment, double *cost, double *distMatrixIn, int nOfRows, int nOfColumns) +{ + double *distMatrix, *distMatrixTemp, *distMatrixEnd, *columnEnd, value, minValue; + bool *coveredColumns, *coveredRows, *starMatrix, *newStarMatrix, *primeMatrix; + int nOfElements, minDim, row, col; + + /* initialization */ + *cost = 0; + for (row = 0; row nOfColumns) */ + { + minDim = nOfColumns; + + for (col = 0; col= 0) + *cost += distMatrix[row + nOfRows*col]; + } +} + +/********************************************************/ +void HungarianAlgorithm::step2a(int *assignment, double *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, int nOfRows, int nOfColumns, int minDim) +{ + bool *starMatrixTemp, *columnEnd; + int col; + + /* cover every column containing a starred zero */ + for (col = 0; col +#include + +using namespace std; + + +/** + * @brief 匈牙利算法 + * 主要封装了对于跟踪框和检测框的匹配过程 + */ +class HungarianAlgorithm +{ +public: + + /** + * @brief HungarianAlgorithm构造函数 + * @return None + */ + HungarianAlgorithm(); + + /** + * @brief HungarianAlgorithm析构函数 + * @return None + */ + ~HungarianAlgorithm(); + + /** + * @brief 检测框和跟踪框的匹配问题 + * @param DistMatrix 表示检测框和跟踪框之间的成对距离的代价/距离矩阵 + * @param Assignment 将检测框与跟踪框匹配的结果 + * @return 最优化匹配的代价/距离 + */ + double Solve(vector>& DistMatrix, vector& Assignment); + +private: + /** + * @brief 对给定的代价/距离矩阵进行最优分配 + * @param cost 保存最小代价/距离 + * @param distMatrix 表示检测框和跟踪框之间的代价/距离矩阵 + * @param nOfRows 行数 + * @param nOfColumns 列数 + * @return None + */ + void assignmentoptimal(int *assignment, double *cost, double *distMatrix, int nOfRows, int nOfColumns); + + /** + * @brief 根据星标矩阵构建最终的分配方案 + * @param assignment 最终的分配方案 + * @param starMatrix 保存最优分配方案,即每个行的分配结果对应的列索引 + * @param nOfRows 行数 + * @param nOfColumns 列数 + * @return None + */ + void buildassignmentvector(int *assignment, bool *starMatrix, int nOfRows, int nOfColumns); + + /** + * @brief 基于分配方案计算最终的代价,即总距离 + * @param assignment 最终的分配方案 + * @param cost 保存最小代价/距离 + * @param distMatrix 表示检测框和跟踪框之间的代价/距离矩阵 + * @param nOfRows 行数 + * @return None + */ + void computeassignmentcost(int *assignment, double *cost, double *distMatrix, int nOfRows); + + /** + * @brief 执行步骤2a,更新星标矩阵,对于没有被覆盖的0元素,对应位置设为星号 + * @param assignment 当前的分配方案 + * @param distMatrix 表示检测框和跟踪框之间的代价/距离矩阵 + * @param starMatrix 星标矩阵,表示已经分配的分配对 + * @param newStarMatrix 新的星标矩阵,用于更新星标矩阵 + * @param primeMatrix 素数矩阵,用于辅助计算 + * @param coveredColumns 被覆盖的列标记 + * @param coveredRows 被覆盖的行标记 + * @param nOfRows 行数 + * @param nOfColumns 列数 + * @param minDim 行数和列数的最小值 + * @return None + */ + void step2a(int *assignment, double *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, int nOfRows, int nOfColumns, int minDim); + + /** + * @brief 执行步骤2b,检查星号位置的列是否已经被覆盖,如果已覆盖则转移到步骤3,如果未覆盖则转移到步骤3 + * @param assignment 当前的分配方案 + * @param distMatrix 表示检测框和跟踪框之间的代价/距离矩阵 + * @param starMatrix 星标矩阵,表示已经分配的分配对 + * @param newStarMatrix 新的星标矩阵,用于更新星标矩阵 + * @param primeMatrix 素数矩阵,用于辅助计算 + * @param coveredColumns 被覆盖的列标记 + * @param coveredRows 被覆盖的行标记 + * @param nOfRows 行数 + * @param nOfColumns 列数 + * @param minDim 行数和列数的最小值 + * @return None + */ + void step2b(int *assignment, double *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, int nOfRows, int nOfColumns, int minDim); + + /** + * @brief 执行步骤3,更新代价矩阵和覆盖的行列 + * @param assignment 当前的分配方案 + * @param distMatrix 表示检测框和跟踪框之间的代价/距离矩阵 + * @param starMatrix 星标矩阵,表示已经分配的分配对 + * @param newStarMatrix 新的星标矩阵,用于更新星标矩阵 + * @param primeMatrix 素数矩阵,用于辅助计算 + * @param coveredColumns 被覆盖的列标记 + * @param coveredRows 被覆盖的行标记 + * @param nOfRows 行数 + * @param nOfColumns 列数 + * @param minDim 行数和列数的最小值 + * @return None + */ + void step3(int *assignment, double *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, int nOfRows, int nOfColumns, int minDim); + + /** + * @brief 执行步骤4,根据当前处理的位置(row, col),对星号和素数矩阵进行相应操作 + * @param assignment 当前的分配方案 + * @param distMatrix 表示检测框和跟踪框之间的代价/距离矩阵 + * @param starMatrix 星标矩阵,表示已经分配的分配对 + * @param newStarMatrix 新的星标矩阵,用于更新星标矩阵 + * @param primeMatrix 素数矩阵,用于辅助计算 + * @param coveredColumns 被覆盖的列标记 + * @param coveredRows 被覆盖的行标记 + * @param nOfRows 行数 + * @param nOfColumns 列数 + * @param minDim 行数和列数的最小值 + * @param row 当前处理的行索引 + * @param col 当前处理的列索引 + * @return None + */ + void step4(int *assignment, double *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, int nOfRows, int nOfColumns, int minDim, int row, int col); + + /** + * @brief 执行步骤5,根据当前矩阵状态进行相应操作,直到结束或找到无覆盖0元素 + * @param assignment 当前的分配方案 + * @param distMatrix 表示检测框和跟踪框之间的代价/距离矩阵 + * @param starMatrix 星标矩阵,表示已经分配的分配对 + * @param newStarMatrix 新的星标矩阵,用于更新星标矩阵 + * @param primeMatrix 素数矩阵,用于辅助计算 + * @param coveredColumns 被覆盖的列标记 + * @param coveredRows 被覆盖的行标记 + * @param nOfRows 行数 + * @param nOfColumns 列数 + * @param minDim 行数和列数的最小值 + * @return None + */ + void step5(int *assignment, double *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, int nOfRows, int nOfColumns, int minDim); +}; +#endif \ No newline at end of file diff --git a/src/reference/ai_poc/sq_handkp_flower/main.cc b/src/reference/ai_poc/sq_handkp_flower/main.cc new file mode 100644 index 000000000..0fc31b543 --- /dev/null +++ b/src/reference/ai_poc/sq_handkp_flower/main.cc @@ -0,0 +1,361 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include + +#include "utils.h" +#include "vi_vo.h" +#include "hand_detection.h" +#include "hand_keypoint.h" +#include "flower_recognition.h" +#include "sort.h" + +#define CNUM 20 + +std::atomic isp_stop(false); + +void print_usage(const char *name) +{ + cout << "Usage: " << name << " " << endl + << "Options:" << endl + << " kmodel_det 手掌检测kmodel路径\n" + << " input_mode 本地图片(图片路径)/ 摄像头(None) \n" + << " obj_thresh 手掌检测kmodel obj阈值\n" + << " nms_thresh 手掌检测kmodel nms阈值\n" + << " kmodel_kp 手势关键点检测kmodel路径\n" + << " flower_rec 花卉识别kmodel路径 \n" + << " debug_mode 是否需要调试,0、1、2分别表示不调试、简单调试、详细调试\n" + << "\n" + << endl; +} + + +void video_proc(char *argv[]) +{ + vivcap_start(); + // 设置osd参数 + k_video_frame_info vf_info; + void *pic_vaddr = NULL; // osd + memset(&vf_info, 0, sizeof(vf_info)); + vf_info.v_frame.width = osd_width; + vf_info.v_frame.height = osd_height; + vf_info.v_frame.stride[0] = osd_width; + vf_info.v_frame.pixel_format = PIXEL_FORMAT_ARGB_8888; + block = vo_insert_frame(&vf_info, &pic_vaddr); + + // alloc memory,get isp memory + size_t paddr = 0; + void *vaddr = nullptr; + size_t size = SENSOR_CHANNEL * SENSOR_HEIGHT * SENSOR_WIDTH; + int ret = kd_mpi_sys_mmz_alloc_cached(&paddr, &vaddr, "allocate", "anonymous", size); + if (ret) + { + std::cerr << "physical_memory_block::allocate failed: ret = " << ret << ", errno = " << strerror(errno) << std::endl; + std::abort(); + } + { + HandDetection hd(argv[1], atof(argv[3]), atof(argv[4]), {SENSOR_WIDTH, SENSOR_HEIGHT}, {SENSOR_CHANNEL, SENSOR_HEIGHT, SENSOR_WIDTH}, reinterpret_cast(vaddr), reinterpret_cast(paddr), atoi(argv[7])); + HandKeypoint hk(argv[5], {SENSOR_CHANNEL, SENSOR_HEIGHT, SENSOR_WIDTH}, reinterpret_cast(vaddr), reinterpret_cast(paddr), atoi(argv[7])); + + FlowerRecognition fr(argv[6], {SENSOR_CHANNEL, SENSOR_HEIGHT, SENSOR_WIDTH}, reinterpret_cast(vaddr), reinterpret_cast(paddr), atoi(argv[7])); + + std::vector results; + + Sort sort; + int fi = 0; + + while (!isp_stop) + { + ScopedTiming st("total time", 1); + { + ScopedTiming st("read capture", atoi(argv[7])); + // 从vivcap中读取一帧图像到dump_info + memset(&dump_info, 0, sizeof(k_video_frame_info)); + ret = kd_mpi_vicap_dump_frame(vicap_dev, VICAP_CHN_ID_1, VICAP_DUMP_YUV, &dump_info, 1000); + if (ret) + { + printf("sample_vicap...kd_mpi_vicap_dump_frame failed.\n"); + continue; + } + } + { + { + ScopedTiming st("isp copy", atoi(argv[7])); + auto vbvaddr = kd_mpi_sys_mmap_cached(dump_info.v_frame.phys_addr[0], size); + memcpy(vaddr, (void *)vbvaddr, SENSOR_HEIGHT * SENSOR_WIDTH * 3); // 这里以后可以去掉,不用copy + kd_mpi_sys_munmap(vbvaddr, size); + } + + results.clear(); + + hd.pre_process(); + hd.inference(); + // 旋转后图像 + hd.post_process(results); + + std::vector frameTrackingResult = sort.Sortx(results, fi); + fi ++; + + cv::Mat osd_frame(osd_height, osd_width, CV_8UC4, cv::Scalar(0, 0, 0, 0)); + + if (frameTrackingResult.size()>=2 && fi>=5) + { + cv::Point2f left_top, right_bottom; + int index1 = 1; + + for(int i=0;i< frameTrackingResult.size();i++) + { + auto tb = frameTrackingResult[i]; + int rect_x = tb.box.x / SENSOR_WIDTH * osd_width; + int rect_y = tb.box.y / SENSOR_HEIGHT * osd_height; + int rect_w = (float)tb.box.width / SENSOR_WIDTH * osd_width; + int rect_h = (float)tb.box.height / SENSOR_HEIGHT * osd_height; + cv::rectangle(osd_frame, cv::Rect(rect_x, rect_y, rect_w, rect_h), cv::Scalar( 255,255, 0, 255), 2, 2, 0); + std::string num = std::to_string(tb.id); + + int length = std::max(tb.box.width,tb.box.height)/2; + int cx = tb.box.x+tb.box.width/2; + int cy = tb.box.y+tb.box.height/2; + int ratio_num = 1.26*length; + + int x1_1 = std::max(0,cx-ratio_num); + int y1_1 = std::max(0,cy-ratio_num); + int x2_1 = std::min(SENSOR_WIDTH-1, cx+ratio_num); + int y2_1 = std::min(SENSOR_HEIGHT-1, cy+ratio_num); + int w_1 = x2_1 - x1_1 + 1; + int h_1 = y2_1 - y1_1 + 1; + + struct Bbox bbox = {x:x1_1,y:y1_1,w:w_1,h:h_1}; + hk.pre_process(bbox); + + hk.inference(); + + float *pred = hk.get_out()[0]; + int draw_x,draw_y; + + if (i==0) + { + float left_pred_x = std::max(std::min(pred[(index1+1)*4*2], 1.0f), 0.0f); + float left_pred_y = std::max(std::min(pred[(index1+1)*4*2+1], 1.0f), 0.0f); + + left_top.x = left_pred_x * w_1 + x1_1; + left_top.y = left_pred_y * h_1 + y1_1; + + draw_x = left_top.x / SENSOR_WIDTH * osd_width; + draw_y = left_top.y / SENSOR_HEIGHT * osd_height; + } + else if (i==1) + { + float right_pred_x = std::max(std::min(pred[(index1+1)*4*2], 1.0f), 0.0f); + float right_pred_y = std::max(std::min(pred[(index1+1)*4*2+1], 1.0f), 0.0f); + + right_bottom.x = right_pred_x * w_1 + x1_1; + right_bottom.y = right_pred_y * h_1 + y1_1; + + draw_x = right_bottom.x / SENSOR_WIDTH * osd_width; + draw_y = right_bottom.y / SENSOR_HEIGHT * osd_height; + } + + cv::circle(osd_frame, cv::Point(draw_x, draw_y), 6, cv::Scalar(255, 0,0,0), 3); + cv::circle(osd_frame, cv::Point(draw_x, draw_y), 5, cv::Scalar(255, 0,0,0), 3); + + ScopedTiming st("osd draw", atoi(argv[7])); + hk.draw_keypoints(osd_frame, bbox, false); + + } + + int x_min = std::min(left_top.x, right_bottom.x); + int x_max = std::max(left_top.x, right_bottom.x); + int y_min = std::min(left_top.y, right_bottom.y); + int y_max = std::max(left_top.y, right_bottom.y); + Bbox box_info = {x_min,y_min, (x_max-x_min+1),(y_max-y_min+1)}; + + fr.pre_process(box_info); + + fr.inference(); + + std::string text = fr.post_process(); + + int x = 1.0 * x_min/ SENSOR_WIDTH * osd_width; + int y = 1.0 * y_min / SENSOR_HEIGHT * osd_height; + int w = 1.0 * (x_max-x_min) / SENSOR_WIDTH * osd_width; + int h = 1.0 * (y_max-y_min) / SENSOR_HEIGHT * osd_height; + cv::putText(osd_frame, text, cv::Point(x, y-20),cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 0, 0), 2); + cv::rectangle(osd_frame, cv::Rect(x, y , w, h), cv::Scalar( 255,0, 255, 255), 2, 2, 0); + } + { + ScopedTiming st("osd copy", atoi(argv[7])); + memcpy(pic_vaddr, osd_frame.data, osd_width * osd_height * 4); + // 显示通道插入帧 + kd_mpi_vo_chn_insert_frame(osd_id + 3, &vf_info); // K_VO_OSD0 + } + } + + { + ScopedTiming st("vicap release", atoi(argv[7])); + ret = kd_mpi_vicap_dump_release(vicap_dev, VICAP_CHN_ID_1, &dump_info); + if (ret) + { + printf("sample_vicap...kd_mpi_vicap_dump_release failed.\n"); + } + } + } + + } + + vo_osd_release_block(); + vivcap_stop(); + + // free memory + ret = kd_mpi_sys_mmz_free(paddr, vaddr); + if (ret) + { + std::cerr << "free failed: ret = " << ret << ", errno = " << strerror(errno) << std::endl; + std::abort(); + } +} + + +int main(int argc, char *argv[]) +{ + std::cout << "case " << argv[0] << " built at " << __DATE__ << " " << __TIME__ << std::endl; + if (argc != 8) + { + print_usage(argv[0]); + return -1; + } + + if (strcmp(argv[2], "None") == 0) + { + std::thread thread_isp(video_proc, argv); + while (getchar() != 'q') + { + usleep(10000); + } + + isp_stop = true; + thread_isp.join(); + } + else + { + cv::Mat img = cv::imread(argv[2]); + cv::Mat img_draw = img.clone(); + + + int origin_w = img.cols; + int origin_h = img.rows; + FrameSize handimg_size = {origin_w, origin_h}; + + HandDetection hd(argv[1], atof(argv[3]), atof(argv[4]), handimg_size, atoi(argv[7])); + HandKeypoint hk(argv[5], atoi(argv[7])); + + FlowerRecognition fr(argv[6], atoi(argv[7])); + + hd.pre_process(img); + hd.inference(); + + std::vector result_hd; + hd.post_process(result_hd); + + int index1 = 1; + if (result_hd.size()>=2) + { + cv::Point2f left_top, right_bottom; + for(int i=0;i< result_hd.size();i++) + { + BoxInfo r = result_hd[i]; + int w = r.x2 - r.x1 + 1; + int h = r.y2 - r.y1 + 1; + cv::rectangle(img_draw, cv::Rect(static_cast(r.x1), static_cast(r.y1) , w, h), cv::Scalar(255, 255, 255), 2, 2, 0); + + int length = std::max(w,h)/2; + int cx = (r.x1+r.x2)/2; + int cy = (r.y1+r.y2)/2; + int ratio_num = 1.26*length; + + int x1_1 = std::max(0,cx-ratio_num); + int y1_1 = std::max(0,cy-ratio_num); + int x2_1 = std::min(origin_w-1, cx+ratio_num); + int y2_1 = std::min(origin_h-1, cy+ratio_num); + int w_1 = x2_1 - x1_1 + 1; + int h_1 = y2_1 - y1_1 + 1; + + struct Bbox bbox = {x:x1_1, y:y1_1, w:w_1, h:h_1}; + hk.pre_process(img, bbox); + hk.inference(); + + float *pred = hk.get_out()[0]; + + if (i==0) + { + float left_pred_x = std::max(std::min(pred[(index1+1)*4*2], 1.0f), 0.0f); + float left_pred_y = std::max(std::min(pred[(index1+1)*4*2+1], 1.0f), 0.0f); + + left_top.x = left_pred_x * w_1 + x1_1; + left_top.y = left_pred_y * h_1 + y1_1; + + cv::circle(img_draw, left_top, 6, cv::Scalar(0,0,0), 3); + cv::circle(img_draw, left_top, 5, cv::Scalar(0,0,0), 3); + } + if (i==1) + { + float right_pred_x = std::max(std::min(pred[(index1+1)*4*2], 1.0f), 0.0f); + float right_pred_y = std::max(std::min(pred[(index1+1)*4*2+1], 1.0f), 0.0f); + + right_bottom.x = right_pred_x * w_1 + x1_1; + right_bottom.y = right_pred_y * h_1 + y1_1; + + cv::circle(img_draw, right_bottom, 6, cv::Scalar(0,0,0), 3); + cv::circle(img_draw, right_bottom, 5, cv::Scalar(0,0,0), 3); + } + + hk.draw_keypoints(img_draw, bbox, true); + } + { + int x_min = std::min(left_top.x, right_bottom.x); + int x_max = std::max(left_top.x, right_bottom.x); + int y_min = std::min(left_top.y, right_bottom.y); + int y_max = std::max(left_top.y, right_bottom.y); + Bbox box_info = {x_min,y_min, (x_max-x_min+1),(y_max-y_min+1)}; + + fr.pre_process(img, box_info); + + fr.inference(); + + std::string text = fr.post_process(); + cv::putText(img_draw, text, cv::Point(x_min,y_min-20),cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 195, 0), 2); + + cv::rectangle(img_draw, cv::Rect(x_min, y_min , (x_max-x_min), (y_max-y_min)), cv::Scalar(255, 255, 0), 2, 2, 0); + } + } + + cv::imwrite("flower_result.jpg", img_draw); + } + return 0; +} + diff --git a/src/reference/ai_poc/sq_handkp_flower/my_tracker.cpp b/src/reference/ai_poc/sq_handkp_flower/my_tracker.cpp new file mode 100644 index 000000000..a9d65207b --- /dev/null +++ b/src/reference/ai_poc/sq_handkp_flower/my_tracker.cpp @@ -0,0 +1,91 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Part of the code is referenced from https://github.com/mcximing/sort-cpp. The orignal code are published under the BSD license. + */ +#include "my_tracker.h" + +int MyTracker::kf_count = 0; + +void MyTracker::init_kf(StateType stateMat) +{ + statePost = Mat::zeros(4, 1, CV_32F); + statePost.at(0, 0) = stateMat.x + stateMat.width / 2; + statePost.at(1, 0) = stateMat.y + stateMat.height / 2; + statePost.at(2, 0) = stateMat.area(); + statePost.at(3, 0) = stateMat.width / stateMat.height; +} + + +// Predict the estimated bounding box. +StateType MyTracker::predict() +{ + m_age += 1; + + if (m_time_since_update > 0) + m_hit_streak = 0; + m_time_since_update += 1; + + StateType predictBox = get_rect_xysr(statePost.at(0, 0), statePost.at(1, 0), statePost.at(2, 0), statePost.at(3, 0)); + + m_history.push_back(predictBox); + return m_history.back(); +} + + +// Update the state vector with observed bounding box. +void MyTracker::update(StateType stateMat) +{ + m_time_since_update = 0; + m_history.clear(); + m_hits += 1; + m_hit_streak += 1; + + statePost.at(0, 0) = stateMat.x + stateMat.width / 2; + statePost.at(1, 0) = stateMat.y + stateMat.height / 2; + statePost.at(2, 0) = stateMat.area(); + statePost.at(3, 0) = stateMat.width / stateMat.height; +} + +// Return the current state vector +StateType MyTracker::get_state() +{ + return get_rect_xysr(statePost.at(0, 0), statePost.at(1, 0), statePost.at(2, 0), statePost.at(3, 0)); +} + +// Convert bounding box from [cx,cy,s,r] to [x,y,w,h] style. +StateType MyTracker::get_rect_xysr(float cx, float cy, float s, float r) +{ + float w = sqrt(s * r); + float h = s / w; + float x = (cx - w / 2); + float y = (cy - h / 2); + + if (x < 0 && cx > 0) + x = 0; + if (y < 0 && cy > 0) + y = 0; + + return StateType(x, y, w, h); +} diff --git a/src/reference/ai_poc/sq_handkp_flower/my_tracker.h b/src/reference/ai_poc/sq_handkp_flower/my_tracker.h new file mode 100644 index 000000000..52f6bdbee --- /dev/null +++ b/src/reference/ai_poc/sq_handkp_flower/my_tracker.h @@ -0,0 +1,132 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Part of the code is referenced from https://github.com/mcximing/sort-cpp. The orignal code are published under the BSD license. + */ +#ifndef MY_TRACKER_H +#define MY_TRACKER_H + +// #include "opencv2/video/tracking.hpp" +#include "opencv2/highgui/highgui.hpp" + +using namespace std; +using namespace cv; + +#define StateType Rect_ + + +// This class represents the internel state of individual tracked objects observed as bounding box. +/** + * @brief 跟踪器 + * 主要为每一个检测框初始化跟踪器并维护 + */ +class MyTracker +{ +public: + + /** + * @brief MyTracker构造函数 + * @return None + */ + MyTracker() + { + init_kf(StateType()); // 使用默认状态初始化滤波器 + m_time_since_update = 0; // 自上次更新以来的时间 + m_hits = 0; // 成功匹配次数 + m_hit_streak = 0; // 连续成功匹配次数 + m_age = 0; // 目标跟踪的帧数 + m_id = kf_count; // 目标跟踪器的唯一标识符 + } + + /** + * @brief MyTracker带参数构造函数 + * @return None + */ + MyTracker(StateType initRect) + { + init_kf(initRect); // 使用给定的初始状态初始化卡尔曼滤波器 + m_time_since_update = 0; // 自上次更新以来的时间 + m_hits = 0; // 成功匹配次数 + m_hit_streak = 0; // 连续成功匹配次数 + m_age = 0; // 目标跟踪的帧数 + m_id = kf_count; // 目标跟踪器的唯一标识符 + kf_count++; + } + + /** + * @brief MyTracker析构函数 + * @return None + */ + ~MyTracker() + { + m_history.clear(); + } + + /** + * @brief 预测目标的状态 + * @return 返回预测目标的状态 + */ + StateType predict(); + + /** + * @brief 更新目标的状态 + * @return None + */ + void update(StateType stateMat); + + /** + * @brief 获取当前目标的状态 + * @return 返回当前目标的状态 + */ + StateType get_state(); + + /** + * @brief 根据中心点坐标、尺度因子和旋转角度获取状态矩阵 + * @return 返回目标的状态 + */ + StateType get_rect_xysr(float cx, float cy, float s, float r); + + static int kf_count; // 统计目标跟踪器的数量 + int m_time_since_update; // 自上次更新以来的时间 + int m_hits; // 成功匹配次数 + int m_hit_streak; // 连续成功匹配次数 + int m_age; // 目标追踪的帧数 + int m_id; // 目标追踪器的唯一标识符 + +private: + + /** + * @brief // 初始化滤波器 + * @return None + */ + void init_kf(StateType stateMat); + + cv::Mat statePost; // 跟踪器的状态向量 + std::vector m_history; // 目标状态的历史记录 +}; + + + + +#endif \ No newline at end of file diff --git a/src/reference/ai_poc/sq_handkp_flower/scoped_timing.hpp b/src/reference/ai_poc/sq_handkp_flower/scoped_timing.hpp new file mode 100644 index 000000000..874ff1b17 --- /dev/null +++ b/src/reference/ai_poc/sq_handkp_flower/scoped_timing.hpp @@ -0,0 +1,70 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include + +/** + * @brief 计时类 + * 统计在该类实例生命周期内的耗时 + */ +class ScopedTiming +{ +public: + /** + * @brief ScopedTiming构造函数,初始化计时对象名称并开始计时 + * @param info 计时对象名称 + * @param enable_profile 是否开始计时 + * @return None + */ + ScopedTiming(std::string info = "ScopedTiming", int enable_profile = 1) + : m_info(info), enable_profile(enable_profile) + { + if (enable_profile) + { + m_start = std::chrono::steady_clock::now(); + } + } + + /** + * @brief ScopedTiming析构,结束计时,并打印耗时 + * @return None + */ + ~ScopedTiming() + { + if (enable_profile) + { + m_stop = std::chrono::steady_clock::now(); + double elapsed_ms = std::chrono::duration(m_stop - m_start).count(); + std::cout << m_info << " took " << elapsed_ms << " ms" << std::endl; + } + } + +private: + int enable_profile; // 是否统计时间 + std::string m_info; // 计时对象名称 + std::chrono::steady_clock::time_point m_start; // 计时开始时间 + std::chrono::steady_clock::time_point m_stop; // 计时结束时间 +}; \ No newline at end of file diff --git a/src/reference/ai_poc/sq_handkp_flower/sort.cpp b/src/reference/ai_poc/sq_handkp_flower/sort.cpp new file mode 100644 index 000000000..4be58a035 --- /dev/null +++ b/src/reference/ai_poc/sq_handkp_flower/sort.cpp @@ -0,0 +1,222 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Part of the code is referenced from https://github.com/mcximing/sort-cpp. The orignal code are published under the BSD license. + */ +#include "sort.h" +#include "hungarian.h" +#include "my_tracker.h" +#include + +#include +#include +#include + + +double Sort::GetIOU(cv::Rect_ bb_dr, cv::Rect_ bb_gt){ + float in = (bb_dr & bb_gt).area(); + float un = bb_dr.area() + bb_gt.area() - in; + + if(un < DBL_EPSILON) + return 0; + + double iou = in / un; + + return iou; +} + + +std::vector Sort::Sortx(std::vector bbox, int fi){ + int max_age = 30;//max time object disappear + int min_hits = 3; //min time target appear + double iouThreshold = 0.70;//matching IOU + + std::vector detData; + std::vector> predictedBoxes; + std::vector> iouMatrix; + std::vector assignment; + + std::set unmatchedDetections; + std::set unmatchedTrajectories; + std::set allItems; + std::set matchedItems; + std::vector matchedPairs; + std::vector frameTrackingResult; + + unsigned int trkNum = 0; + unsigned int detNum = 0; + auto start_time = std::chrono::high_resolution_clock::now(); + + // bounding boxes in a frame store in detFrameData + for (int i = 0; i < bbox.size() ; i++){ + Sort::TrackingBox tb; + tb.frame = fi + 1; + tb.box = Rect_(cv::Point_(bbox[i].x1, bbox[i].y1), cv::Point_(bbox[i].x2, bbox[i].y2)); + detData.push_back(tb); + } + + detFrameData.push_back(detData); + + if(trackers.size() == 0){ + std::vector first_frame; + + for (unsigned int i = 0; i < detFrameData[fi].size(); i++){ + + MyTracker trk = MyTracker(detFrameData[fi][i].box); + + trackers.push_back(trk); + + } + return first_frame; + } + + /* + 3.1. get predicted locations from existing trackers + */ + for (auto it = trackers.begin(); it != trackers.end();) + { + cv::Rect_ pBox = (*it).predict(); + if (pBox.x >= 0 && pBox.y >= 0) + { + predictedBoxes.push_back(pBox); + it++; + } + else + { + it = trackers.erase(it); + //cerr << "Box invalid at frame: " << frame_count << endl; + } + } + + /* + 3.2. associate detections to tracked object (both represented as bounding boxes) + */ + trkNum = predictedBoxes.size(); + detNum = detFrameData[fi].size(); + iouMatrix.resize(trkNum, std::vector(detNum, 0)); + + + for (unsigned int i = 0; i < trkNum; i++) // compute iou matrix as a distance matrix + { + for (unsigned int j = 0; j < detNum; j++) + { + // use 1-iou because the hungarian algorithm computes a minimum-cost assignment. + iouMatrix[i][j] = 1 - GetIOU(predictedBoxes[i], detFrameData[fi][j].box); + } + } + + // solve the assignment problem using hungarian algorithm. + // the resulting assignment is [track(prediction) : detection], with len=preNum + HungarianAlgorithm HungAlgo; + HungAlgo.Solve(iouMatrix, assignment); + + // find matches, unmatched_detections and unmatched_predictions + if (detNum > trkNum) // there are unmatched detections + { + for (unsigned int n = 0; n < detNum; n++) + allItems.insert(n); + + for (unsigned int i = 0; i < trkNum; ++i) + matchedItems.insert(assignment[i]); + + // calculate the difference between allItems and matchedItems, return to unmatchedDetections + std::set_difference(allItems.begin(), allItems.end(), + matchedItems.begin(), matchedItems.end(), + insert_iterator>(unmatchedDetections, unmatchedDetections.begin())); + } + else if (detNum < trkNum) // there are unmatched trajectory/predictions + { + for (unsigned int i = 0; i < trkNum; ++i) + if (assignment[i] == -1) // unassigned label will be set as -1 in the assignment algorithm + unmatchedTrajectories.insert(i); + } + else + ; + + // filter out matched with low IOU + // output matchedPairs + for (unsigned int i = 0; i < trkNum; ++i) + { + if (assignment[i] == -1) // pass over invalid values + continue; + if (1 - iouMatrix[i][assignment[i]] < iouThreshold) + { + unmatchedTrajectories.insert(i); + unmatchedDetections.insert(assignment[i]); + } + else + matchedPairs.push_back(cv::Point(i, assignment[i])); + } + + /* + 3.3. updating trackers + update matched trackers with assigned detections. + each prediction is corresponding to a tracker + */ + int detIdx, trkIdx; + for (unsigned int i = 0; i < matchedPairs.size(); i++) + { + trkIdx = matchedPairs[i].x; + detIdx = matchedPairs[i].y; + trackers[trkIdx].update(detFrameData[fi][detIdx].box); + } + + // create and initialize new trackers for unmatched detections + for (auto umd : unmatchedDetections) + { + MyTracker tracker = MyTracker(detFrameData[fi][umd].box); + trackers.push_back(tracker); + } + + vector::iterator it = trackers.begin(); + for (; it != trackers.end();) + { + if (it != trackers.end() && (*it).m_time_since_update > max_age) + { + it = trackers.erase(it); + continue; + } + + if (((*it).m_time_since_update < 1) && + ((*it).m_hit_streak >= min_hits )) + { + Sort::TrackingBox res; + res.box = (*it).get_state(); + res.id = (*it).m_id + 1; + res.frame = fi; + frameTrackingResult.push_back(res); + it++; + } + else + { + it++; + } + + } + auto end_time = std::chrono::high_resolution_clock::now(); + auto duration = std::chrono::duration_cast(end_time - start_time); + + return frameTrackingResult; + +} diff --git a/src/reference/ai_poc/sq_handkp_flower/sort.h b/src/reference/ai_poc/sq_handkp_flower/sort.h new file mode 100644 index 000000000..5402435c3 --- /dev/null +++ b/src/reference/ai_poc/sq_handkp_flower/sort.h @@ -0,0 +1,71 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Part of the code is referenced from https://github.com/mcximing/sort-cpp. The orignal code are published under the BSD license. + */ +#ifndef SORT_H +#define SORT_H + +#include +#include +#include "my_tracker.h" +#include "utils.h" + +//using namespace std; + +class Sort +{ +public: + + /** + * @brief 跟踪框信息 + */ + typedef struct TrackingBox{ + int frame; //视频中的第几帧 + int id; //跟踪目标的id + cv::Rect_ box; //跟踪框信息:x,y,w,h + }TrackingBox; + + std::vector trackers; //跟踪目标信息 + std::vector> detFrameData; //检测框的信息 + + /** + * @brief 根据检测框对跟踪目标信息进行更新 + * @param bbox 检测框的信息 + * @param fi 当前帧数 + * @return 已更新的跟踪目标信息 + */ + std::vector Sortx(std::vector bbox, int fi); + + /** + * @brief 计算两个矩形框的IOU(交并比) + * @param bb_dr 需要计算IOU的矩形框1 + * @param bb_gt 需要计算IOU的矩形框2 + * @return 计算得到的IOU值 + */ + double GetIOU(cv::Rect_ bb_dr, cv::Rect_ bb_gt); + +}; + +#endif \ No newline at end of file diff --git a/src/reference/ai_poc/sq_handkp_flower/utils.cc b/src/reference/ai_poc/sq_handkp_flower/utils.cc new file mode 100644 index 000000000..95d9994b0 --- /dev/null +++ b/src/reference/ai_poc/sq_handkp_flower/utils.cc @@ -0,0 +1,804 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +// utils.cpp +#include +#include "utils.h" + +using std::ofstream; +using std::vector; +auto cache = cv::Mat::zeros(1, 1, CV_32FC1); +void Utils::dump_binary_file(const char *file_name, char *data, const size_t size) +{ + // eg:Utils::dump_binary_file(out_name.c_str(),reinterpret_cast(p_outputs_[i]),each_output_size_by_byte_[i+1]-each_output_size_by_byte_[i]); + std::ofstream outf; + outf.open(file_name, std::ofstream::binary); + outf.write(data, size); + outf.close(); +} + +void Utils::dump_gray_image(const char *file_name, const FrameSize &frame_size, unsigned char *data) +{ + cv::Mat gray_image = cv::Mat(frame_size.height, frame_size.width, CV_8UC1, data); + cv::imwrite(file_name, gray_image); +} + +void Utils::dump_color_image(const char *file_name, const FrameSize &frame_size, unsigned char *data) +{ + cv::Mat image_r = cv::Mat(frame_size.height, frame_size.width, CV_8UC1, data); + cv::Mat image_g = cv::Mat(frame_size.height, frame_size.width, CV_8UC1, data+frame_size.height*frame_size.width); + cv::Mat image_b = cv::Mat(frame_size.height, frame_size.width, CV_8UC1, data+2*frame_size.height*frame_size.width); + + std::vector color_vec(3); + color_vec.clear(); + color_vec.push_back(image_b); + color_vec.push_back(image_g); + color_vec.push_back(image_r); + + cv::Mat color_img; + cv::merge(color_vec, color_img); + cv::imwrite(file_name, color_img); +} + +cv::Mat Utils::padding_resize(const cv::Mat img, const FrameSize &frame_size, const cv::Scalar &padding) +{ + int ori_w = img.cols; + int ori_h = img.rows; + float ratiow = (float)frame_size.width / ori_w; + float ratioh = (float)frame_size.height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(frame_size.width - new_w) / 2; + float dh = (float)(frame_size.height - new_h) / 2; + int top = (int)(roundf(0 - 0.1)); + int bottom = (int)(roundf(dh * 2 + 0.1)); + int left = (int)(roundf(0 - 0.1)); + int right = (int)(roundf(dw * 2 - 0.1)); + cv::Mat cropped_img; + + cv::resize(img, cropped_img, cv::Size(new_w, new_h), cv::INTER_AREA); + cv::copyMakeBorder(cropped_img, cropped_img, top, bottom, left, right, cv::BORDER_CONSTANT, padding); + + return cropped_img; +} + +cv::Mat Utils::resize(const cv::Mat img, const FrameSize &frame_size) +{ + cv::Mat cropped_img; + cv::resize(img, cropped_img, cv::Size(frame_size.width, frame_size.height), cv::INTER_LINEAR); + return cropped_img; +} + +cv::Mat Utils::crop(const cv::Mat ori_img, Bbox &crop_info) +{ + cv::Mat cropped_img; + cropped_img = ori_img(cv::Range(static_cast(crop_info.y), static_cast(crop_info.y+crop_info.h)), cv::Range(static_cast(crop_info.x), static_cast(crop_info.x+crop_info.w))); + return cropped_img; +} + +cv::Mat Utils::bgr_to_rgb(cv::Mat ori_img) +{ + cv::Mat rgb_img; + cv::cvtColor(ori_img, rgb_img, cv::COLOR_BGR2RGB); + return rgb_img; +} + +void Utils::hwc_to_chw(cv::Mat &ori_img, std::vector &chw_vec) +{ + // for rgb format + std::vector rgbChannels(3); + cv::split(ori_img, rgbChannels); + for (auto i = 0; i < rgbChannels.size(); i++) + { + std::vector data = std::vector(rgbChannels[i].reshape(1, 1)); + chw_vec.insert(chw_vec.end(), data.begin(), data.end()); + } +} + +void Utils::bgr2rgb_and_hwc2chw(cv::Mat &ori_img, std::vector &chw_vec) +{ + // for bgr format + std::vector bgrChannels(3); + cv::split(ori_img, bgrChannels); + for (auto i = 2; i > -1; i--) + { + std::vector data = std::vector(bgrChannels[i].reshape(1, 1)); + chw_vec.insert(chw_vec.end(), data.begin(), data.end()); + } +} + +void Utils::resize(FrameCHWSize ori_shape, std::vector &chw_vec, runtime_tensor &ai2d_out_tensor) +{ + // build ai2d_in_tensor + dims_t in_shape{1, ori_shape.channel, ori_shape.height, ori_shape.width}; + runtime_tensor ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), chw_vec.data(), chw_vec.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + // ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, typecode_t::dt_uint8, typecode_t::dt_uint8}; + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param { false, 30, 20, 400, 600 }; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, ai2d_pad_mode::constant, {114, 114, 114}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::resize(std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor) +{ + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param { false, 30, 20, 400, 600 }; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, ai2d_pad_mode::constant, {114, 114, 114}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::crop_resize(FrameCHWSize ori_shape, std::vector &chw_vec, Bbox &crop_info, runtime_tensor &ai2d_out_tensor) +{ + // build ai2d_in_tensor + dims_t in_shape{1, ori_shape.channel, ori_shape.height, ori_shape.width}; + runtime_tensor ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), chw_vec.data(), chw_vec.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{true, crop_info.x, crop_info.y, crop_info.w, crop_info.h}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, ai2d_pad_mode::constant, {114, 114, 114}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::crop_resize(Bbox &crop_info, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor) +{ + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, typecode_t::dt_uint8, typecode_t::dt_uint8}; + ai2d_crop_param_t crop_param{true, crop_info.x, crop_info.y, crop_info.w, crop_info.h}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, ai2d_pad_mode::constant, {114, 114, 114}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::padding_resize(FrameCHWSize ori_shape, std::vector &chw_vec, FrameSize resize_shape, runtime_tensor &ai2d_out_tensor, cv::Scalar padding) +{ + int ori_w = ori_shape.width; + int ori_h = ori_shape.height; + int width = resize_shape.width; + int height = resize_shape.height; + float ratiow = (float)width / ori_w; + float ratioh = (float)height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(width - new_w) / 2; + float dh = (float)(height - new_h) / 2; + int top = (int)(roundf(dh - 0.1)); + int bottom = (int)(roundf(dh + 0.1)); + int left = (int)(roundf(dw - 0.1)); + int right = (int)(roundf(dw - 0.1)); + + // create input + dims_t in_shape{1, ori_shape.channel, ori_h, ori_w}; + auto ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), chw_vec.data(), chw_vec.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{true, {{0, 0}, {0, 0}, {top, bottom}, {left, right}}, ai2d_pad_mode::constant, {padding[0], padding[1], padding[2]}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::padding_resize_one_side(FrameCHWSize ori_shape, std::vector &chw_vec, FrameSize resize_shape, runtime_tensor &ai2d_out_tensor, cv::Scalar padding) +{ + int ori_w = ori_shape.width; + int ori_h = ori_shape.height; + int width = resize_shape.width; + int height = resize_shape.height; + float ratiow = (float)width / ori_w; + float ratioh = (float)height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(width - new_w) / 2; + float dh = (float)(height - new_h) / 2; + int top = (int)(roundf(0)); + int bottom = (int)(roundf(dh * 2 + 0.1)); + int left = (int)(roundf(0)); + int right = (int)(roundf(dw * 2 - 0.1)); + + // create input + dims_t in_shape{1, ori_shape.channel, ori_h, ori_w}; + auto ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), chw_vec.data(), chw_vec.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{true, {{0, 0}, {0, 0}, {top, bottom}, {left, right}}, ai2d_pad_mode::constant, {padding[0], padding[1], padding[2]}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::padding_resize(FrameCHWSize ori_shape, FrameSize resize_shape, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor, const cv::Scalar padding) +{ + int ori_w = ori_shape.width; + int ori_h = ori_shape.height; + int width = resize_shape.width; + int height = resize_shape.height; + float ratiow = (float)width / ori_w; + float ratioh = (float)height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(width - new_w) / 2; + float dh = (float)(height - new_h) / 2; + int top = (int)(roundf(dh - 0.1)); + int bottom = (int)(roundf(dh + 0.1)); + int left = (int)(roundf(dw - 0.1)); + int right = (int)(roundf(dw - 0.1)); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{true, {{0, 0}, {0, 0}, {top, bottom}, {left, right}}, ai2d_pad_mode::constant, {padding[0], padding[1], padding[2]}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::padding_resize_one_side(FrameCHWSize ori_shape, FrameSize resize_shape, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor, const cv::Scalar padding) +{ + int ori_w = ori_shape.width; + int ori_h = ori_shape.height; + int width = resize_shape.width; + int height = resize_shape.height; + float ratiow = (float)width / ori_w; + float ratioh = (float)height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(width - new_w) / 2; + float dh = (float)(height - new_h) / 2; + int top = (int)(roundf(0)); + int bottom = (int)(roundf(dh * 2 + 0.1)); + int left = (int)(roundf(0)); + int right = (int)(roundf(dw * 2 - 0.1)); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{true, {{0, 0}, {0, 0}, {top, bottom}, {left, right}}, ai2d_pad_mode::constant, {padding[0], padding[1], padding[2]}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::affine(FrameCHWSize ori_shape, std::vector &ori_data, float *affine_matrix, runtime_tensor &ai2d_out_tensor) +{ + runtime_tensor ai2d_in_tensor; + // init ai2d in/out + dims_t in_shape{1, ori_shape.channel, ori_shape.height, ori_shape.width}; + ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + + // ai2d input + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), ori_data.data(), ori_data.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {10, 0}}, ai2d_pad_mode::constant, {255, 10, 5}}; + ai2d_resize_param_t resize_param{false, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{true, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {affine_matrix[0], affine_matrix[1], affine_matrix[2], affine_matrix[3], affine_matrix[4], affine_matrix[5]}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +// for video(只算一次即可) +void Utils::affine(float *affine_matrix, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor) +{ + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {10, 0}}, ai2d_pad_mode::constant, {255, 10, 5}}; + ai2d_resize_param_t resize_param{false, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{true, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {affine_matrix[0], affine_matrix[1], affine_matrix[2], affine_matrix[3], affine_matrix[4], affine_matrix[5]}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +// void Utils::vaddr2mat(uintptr_t vaddr,cv::Mat& image, FrameSize frame_size) +// { +// int matsize = frame_size.width*frame_size.height; +// std::vector rgb(3); +// memcpy(reinterpret_cast(rgb[0].data), (void *)vaddr, matsize); +// memcpy(reinterpret_cast(rgb[1].data), (void *)vaddr + matsize, matsize); +// memcpy(reinterpret_cast(rgb[2].data), (void *)vaddr + matsize * 2, matsize); +// cv::merge(rgb, image); +// } + + +std::vector sort_indices(const std::vector& vec) +{ + std::vector> indexedVec; + indexedVec.reserve(vec.size()); + + // 创建带有索引的副本 + for (size_t i = 0; i < vec.size(); ++i) { + indexedVec.emplace_back(vec[i], i); + } + + // 按值对副本进行排序 + std::sort(indexedVec.begin(), indexedVec.end(), + [](const auto& a, const auto& b) { + return a.first.x < b.first.x; + }); + + // 提取排序后的索引 + std::vector sortedIndices; + sortedIndices.reserve(vec.size()); + for (const auto& element : indexedVec) { + sortedIndices.push_back(element.second); + } + + return sortedIndices; +} + +void find_rectangle_vertices(const std::vector& points, Point2f& topLeft, Point2f& topRight, Point2f& bottomRight, Point2f& bottomLeft) +{ + //先按照x排序,比较左右,再按照y比较上下 + auto sorted_x_id = sort_indices(points); + + if (points[sorted_x_id[0]].y < points[sorted_x_id[1]].y) + { + topLeft = points[sorted_x_id[0]]; + bottomLeft = points[sorted_x_id[1]]; + } + else + { + topLeft = points[sorted_x_id[1]]; + bottomLeft = points[sorted_x_id[0]]; + } + + if (points[sorted_x_id[2]].y < points[sorted_x_id[3]].y) + { + bottomRight = points[sorted_x_id[3]]; + topRight = points[sorted_x_id[2]]; + + } + else + { + bottomRight = points[sorted_x_id[2]]; + topRight = points[sorted_x_id[3]]; + } + +} + +void Utils::warppersp(cv::Mat src, cv::Mat& dst, Boxb b) +{ + Mat rotation; + vector con; + for(auto i : b.ver_src) + con.push_back(i); + + RotatedRect minrect = minAreaRect(con); + std::vector vtx(4),vtd(4),vt(4); + minrect.points(vtx.data()); + + find_rectangle_vertices(vtx, vtd[0], vtd[1], vtd[2], vtd[3]); + + //w,h tmp_w=dist(p1,p0),tmp_h=dist(p1,p2) + float tmp_w = cv::norm(vtd[1]-vtd[0]); + float tmp_h = cv::norm(vtd[2]-vtd[1]); + float w = std::max(tmp_w,tmp_h); + float h = std::min(tmp_w,tmp_h); + + vt[0].x = 0; + vt[0].y = 0; + vt[1].x = w;//w + vt[1].y = 0; + vt[2].x = w; + vt[2].y = h; + vt[3].x = 0; + vt[3].y = h;//h + rotation = getPerspectiveTransform(vtd, vt); + + warpPerspective(src, dst, rotation, Size(w, h)); +} + +void Utils::paint_ascii(cv::Mat& image,int x_offset,int y_offset,unsigned long offset) +{ + Point p; + p.x = x_offset; + p.y = y_offset; + //存放ascii字膜 + char buff[16]; + //打开ascii字库文件 + FILE *ASCII; + if ((ASCII = fopen("Asci0816.zf", "rb")) == NULL){ + printf("Can't open ascii.zf,Please check the path!"); + //getch(); + exit(0); + } + fseek(ASCII, offset, SEEK_SET); + fread(buff, 16, 1, ASCII); + fclose(ASCII); + int i, j; + Point p1 = p; + for (i = 0; i<16; i++) //十六个char + { + p.x = x_offset; + for (j = 0; j < 8; j++) //一个char八个bit + { + p1 = p; + if (buff[i] & (0x80 >> j)) /*测试当前位是否为1*/ + { + /* + 由于原本ascii字膜是8*16的,不够大, + 所以原本的一个像素点用4个像素点替换, + 替换后就有16*32个像素点 + ps:感觉这样写代码多余了,但目前暂时只想到了这种方法 + */ + circle(image, p1, 0, Scalar(0, 0, 255), -1); + p1.x++; + circle(image, p1, 0, Scalar(0, 0, 255), -1); + p1.y++; + circle(image, p1, 0, Scalar(0, 0, 255), -1); + p1.x--; + circle(image, p1, 0, Scalar(0, 0, 255), -1); + } + p.x+=2; //原来的一个像素点变为四个像素点,所以x和y都应该+2 + } + p.y+=2; + } +} + +void Utils::paint_ascii_video(cv::Mat& image,int x_offset,int y_offset,unsigned long offset) +{ + Point p; + p.x = x_offset; + p.y = y_offset; + //存放ascii字膜 + char buff[16]; + //打开ascii字库文件 + FILE *ASCII; + if ((ASCII = fopen("Asci0816.zf", "rb")) == NULL){ + printf("Can't open ascii.zf,Please check the path!"); + //getch(); + exit(0); + } + fseek(ASCII, offset, SEEK_SET); + fread(buff, 16, 1, ASCII); + fclose(ASCII); + int i, j; + Point p1 = p; + for (i = 0; i<16; i++) //十六个char + { + p.x = x_offset; + for (j = 0; j < 8; j++) //一个char八个bit + { + p1 = p; + if (buff[i] & (0x80 >> j)) /*测试当前位是否为1*/ + { + /* + 由于原本ascii字膜是8*16的,不够大, + 所以原本的一个像素点用4个像素点替换, + 替换后就有16*32个像素点 + ps:感觉这样写代码多余了,但目前暂时只想到了这种方法 + */ + circle(image, p1, 0, Scalar(255, 0, 0, 255), -1); + p1.x--; + circle(image, p1, 0, Scalar(255, 0, 0, 255), -1); + p1.y--; + circle(image, p1, 0, Scalar(255, 0, 0, 255), -1); + p1.x++; + circle(image, p1, 0, Scalar(255, 0, 0, 255), -1); + } + p.x-=2; //原来的一个像素点变为四个像素点,所以x和y都应该+2 + } + p.y-=2; + } +} + +void Utils::paint_chinese(cv::Mat& image,int x_offset,int y_offset,unsigned long offset) +{ + Point p; + p.x=x_offset; + p.y=y_offset; + FILE *HZK; + char buff[72];//72个字节,用来存放汉字的 + if((HZK=fopen("HZKf2424.hz","rb"))==NULL){ + printf("Can't open HZKf2424.hz,Please check the path!"); + exit(0);//退出 + } + fseek(HZK, offset, SEEK_SET);/*将文件指针移动到偏移量的位置*/ + fread(buff, 72, 1, HZK);/*从偏移量的位置读取72个字节,每个汉字占72个字节*/ + fclose(HZK); + bool mat[24][24];//定义一个新的矩阵存放转置后的文字字膜 + int i,j,k; + for (i = 0; i<24; i++) /*24x24点阵汉字,一共有24行*/ + { + for (j = 0; j<3; j++) /*横向有3个字节,循环判断每个字节的*/ + for (k = 0; k<8; k++) /*每个字节有8位,循环判断每位是否为1*/ + if (buff[i * 3 + j] & (0x80 >> k)) /*测试当前位是否为1*/ + { + mat[j * 8 + k][i] = true; /*为1的存入新的字膜中*/ + } + else { + mat[j * 8 + k][i] = false; + } + } + for (i = 0; i < 24; i++) + { + p.x = x_offset; + for (j = 0; j < 24; j++) + { + if (mat[i][j]) + circle(image, p, 1, Scalar(255, 0, 0), -1); //写(替换)像素点 + p.x++; //右移一个像素点 + } + p.y++; //下移一个像素点 + } +} + +void Utils::paint_chinese_video(cv::Mat& image,int x_offset,int y_offset,unsigned long offset) +{ + Point p; + p.x=x_offset; + p.y=y_offset; + FILE *HZK; + char buff[72];//72个字节,用来存放汉字的 + if((HZK=fopen("HZKf2424.hz","rb"))==NULL){ + printf("Can't open HZKf2424.hz,Please check the path!"); + exit(0);//退出 + } + fseek(HZK, offset, SEEK_SET);/*将文件指针移动到偏移量的位置*/ + fread(buff, 72, 1, HZK);/*从偏移量的位置读取72个字节,每个汉字占72个字节*/ + fclose(HZK); + bool mat[24][24];//定义一个新的矩阵存放转置后的文字字膜 + int i,j,k; + for (i = 0; i<24; i++) /*24x24点阵汉字,一共有24行*/ + { + for (j = 0; j<3; j++) /*横向有3个字节,循环判断每个字节的*/ + for (k = 0; k<8; k++) /*每个字节有8位,循环判断每位是否为1*/ + if (buff[i * 3 + j] & (0x80 >> k)) /*测试当前位是否为1*/ + { + mat[j * 8 + k][i] = true; /*为1的存入新的字膜中*/ + } + else { + mat[j * 8 + k][i] = false; + } + } + for (i = 0; i < 24; i++) + { + p.x = x_offset; + for (j = 0; j < 24; j++) + { + if (mat[i][j]) + circle(image, p, 1, Scalar(255, 255, 0, 0), -1); //写(替换)像素点 + p.x--; //右移一个像素点 + } + p.y--; //下移一个像素点 + } +} + +//在图片上添加文本 +void Utils::draw_text(int x_offset,int y_offset,cv::Mat& image,vector vec16) +{ + //x和y就是第一个字在图片上的起始坐标 + //通过图片路径获取图片 + unsigned char qh,wh; //定义区号,位号 + unsigned long offset; //偏移量 + + int text_length=vec16.size(); + std::vector hexcode = vec16; + + int x =x_offset,y = y_offset;//x,y:在图片上绘制文字的起始坐标 + for(int m=0;m0xaf){ + qh=hexcode[m]-0xaf;//使用的字库里是以汉字啊开头,而不是以汉字符号开头 + wh=hexcode[m+1] - 0xa0;//计算位码 + offset=(94*(qh-1)+(wh-1))*72L; + paint_chinese(image,x,y,offset); + /* + 计算在汉字库中的偏移量 + 对于每个汉字,使用24*24的点阵来表示的 + 一行有三个字节,一共24行,所以需要72个字节来表示 + */ + m=m+2;//一个汉字的机内码占两个字节, + x+=24;//一个汉字为24*24个像素点,由于是水平放置,所以是向右移动24个像素点 + } + else{//当读取的字符为ASCII码时 + wh=hexcode[m]; + offset=wh*16l;//计算英文字符的偏移量 + paint_ascii(image,x,y,offset); + m++;//英文字符在文件里表示只占一个字节,所以往后移一位就行了 + x+=16; + } + } +} + +void Utils::draw_text(float x_offset,float y_offset,cv::Mat& image,vector vec16, FrameSize osd_frame_size, FrameSize sensor_frame_size) +{ + //x和y就是第一个字在图片上的起始坐标 + //通过图片路径获取图片 + unsigned char qh,wh; //定义区号,位号 + unsigned long offset; //偏移量 + + int text_length=vec16.size(); + std::vector hexcode = vec16; + + int y = int ((x_offset/sensor_frame_size.width) * osd_frame_size.height); + int x = int (osd_frame_size.width - (y_offset/sensor_frame_size.height) * osd_frame_size.width);//x,y:在图片上绘制文字的起始坐标 + for(int m=0;m0xaf){ + qh=hexcode[m]-0xaf;//使用的字库里是以汉字啊开头,而不是以汉字符号开头 + wh=hexcode[m+1] - 0xa0;//计算位码 + offset=(94*(qh-1)+(wh-1))*72L; + paint_chinese_video(image,x,y,offset); + /* + 计算在汉字库中的偏移量 + 对于每个汉字,使用24*24的点阵来表示的 + 一行有三个字节,一共24行,所以需要72个字节来表示 + */ + m=m+2;//一个汉字的机内码占两个字节, + x-=24;//一个汉字为24*24个像素点,由于是水平放置,所以是向右移动24个像素点 + } + else{//当读取的字符为ASCII码时 + wh=hexcode[m]; + offset=wh*16l;//计算英文字符的偏移量 + paint_ascii_video(image,x,y,offset); + m++;//英文字符在文件里表示只占一个字节,所以往后移一位就行了 + x-=16; + } + } +} + +void Utils::draw_detections(cv::Mat& frame, vector& detections) +{ + for(int i = 0; i < detections.size(); i++) + { + std::vector vec; + vec.clear(); + for(int j = 0; j < 4; j++) + { + vec.push_back(detections[i].vertices[j]); + } + cv::RotatedRect rect = minAreaRect(vec); + cv::Point2f ver[4]; + rect.points(ver); + for(int i = 0; i < 4; i++) + line(frame, ver[i], ver[(i + 1) % 4], Scalar(255, 0, 0), 3); + std::string text = "score:" + std::to_string(round(detections[i].score * 100) / 100.0).substr(0, 4); + + cv::putText(frame, text, cv::Point(detections[i].meanx, detections[i].meany), + cv::FONT_HERSHEY_SIMPLEX, 0.8, cv::Scalar(255, 255, 0), 2); + } +} + +void Utils::draw_detections(cv::Mat& frame, vector& detections, FrameSize osd_frame_size, FrameSize sensor_frame_size) +{ + for(int i = 0; i < detections.size(); i++) + { + std::vector vec; + vec.clear(); + + for(int j = 0; j < 4; j++) + { + cv::Point tmp0 = detections[i].vertices[j]; + cv::Point tmp; + tmp.y = (float(tmp0.x)/sensor_frame_size.width)*osd_frame_size.height; + tmp.x = osd_frame_size.width - (float(tmp0.y)/sensor_frame_size.height)*osd_frame_size.width; + vec.push_back(tmp); + } + cv::RotatedRect rect = minAreaRect(vec); + cv::Point2f ver[4]; + rect.points(ver); + for(int i = 0; i < 4; i++) + line(frame, ver[i], ver[(i + 1) % 4], Scalar(255,255, 0, 0), 3); + // std::string text = "score:" + std::to_string(round(detections[i].score * 100) / 100.0).substr(0, 4); + + // cv::putText(frame, text, cv::Point(detections[i].meanx, detections[i].meany), + // cv::FONT_HERSHEY_SIMPLEX, 0.8, cv::Scalar(255,255, 255, 0), 2); + } +} \ No newline at end of file diff --git a/src/reference/ai_poc/sq_handkp_flower/utils.h b/src/reference/ai_poc/sq_handkp_flower/utils.h new file mode 100644 index 000000000..07246d8ae --- /dev/null +++ b/src/reference/ai_poc/sq_handkp_flower/utils.h @@ -0,0 +1,437 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +// utils.h +#ifndef UTILS_H +#define UTILS_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace nncase; +using namespace nncase::runtime; +using namespace nncase::runtime::k230; +using namespace nncase::F::k230; + + +using namespace std; +using namespace cv; +using cv::Mat; +using std::cout; +using std::endl; +using std::ifstream; +using std::vector; + +/** + * @brief 手掌检测框 + */ +typedef struct BoxInfo +{ + float x1; // 手掌检测框的左上顶点x坐标 + float y1; // 手掌检测框的左上顶点y坐标 + float x2; // 手掌检测框的右下顶点x坐标 + float y2; // 手掌检测框的右下顶点y坐标 + float score; // 手掌检测框的得分 + int label; // 手掌检测框的类别 +} BoxInfo; + +/** + * @brief 人脸检测框 + */ +typedef struct Bbox +{ + float x; // 人脸检测框的左顶点x坐标 + float y; // 人脸检测框的左顶点x坐标 + float w; + float h; +} Bbox; + +/** + * @brief 人脸五官点 + */ +typedef struct SparseLandmarks +{ + float points[10]; // 人脸五官点,依次是图片的左眼(x,y)、右眼(x,y),鼻子(x,y),左嘴角(x,y),右嘴角 +} SparseLandmarks; + +/** + * @brief 单张/帧图片大小 + */ +typedef struct FrameSize +{ + size_t width; // 宽 + size_t height; // 高 +} FrameSize; + +/** + * @brief 单张/帧图片大小 + */ +typedef struct FrameCHWSize +{ + size_t channel; // 通道 + size_t height; // 高 + size_t width; // 宽 +} FrameCHWSize; + +typedef struct Boxb +{ + float meanx; + float meany; + Point2f vertices[4]; + Point2f ver_src[4]; + float score; +} Boxb; + +struct CenterPrior +{ + int x; + int y; + int stride; +}; + +/** + * @brief AI Demo工具类 + * 封装了AI Demo常用的函数,包括二进制文件读取、文件保存、图片预处理等操作 + */ +class Utils +{ +public: + /** + * @brief 读取2进制文件 + * @param file_name 文件路径 + * @return 文件对应类型的数据 + */ + template + static vector read_binary_file(const char *file_name) + { + ifstream ifs(file_name, std::ios::binary); + ifs.seekg(0, ifs.end); + size_t len = ifs.tellg(); + vector vec(len / sizeof(T), 0); + ifs.seekg(0, ifs.beg); + ifs.read(reinterpret_cast(vec.data()), len); + ifs.close(); + return vec; + } + + /** + * @brief 打印数据 + * @param data 需打印数据对应指针 + * @param size 需打印数据大小 + * @return None + */ + template + static void dump(const T *data, size_t size) + { + for (size_t i = 0; i < size; i++) + { + cout << data[i] << " "; + } + cout << endl; + } + + // 静态成员函数不依赖于类的实例,可以直接通过类名调用 + /** + * @brief 将数据以2进制方式保存为文件 + * @param file_name 保存文件路径+文件名 + * @param data 需要保存的数据 + * @param size 需要保存的长度 + * @return None + */ + static void dump_binary_file(const char *file_name, char *data, const size_t size); + + /** + * @brief 将数据保存为灰度图片 + * @param file_name 保存图片路径+文件名 + * @param frame_size 保存图片的宽、高 + * @param data 需要保存的数据 + * @return None + */ + static void dump_gray_image(const char *file_name, const FrameSize &frame_size, unsigned char *data); + + /** + * @brief 将数据保存为彩色图片 + * @param file_name 保存图片路径+文件名 + * @param frame_size 保存图片的宽、高 + * @param data 需要保存的数据 + * @return None + */ + static void dump_color_image(const char *file_name, const FrameSize &frame_size, unsigned char *data); + + + /*************************for img process********************/ + /** + * @brief 对图片进行先padding后resize的处理 + * @param ori_img 原始图片 + * @param frame_size 需要resize图像的宽高 + * @param padding 需要padding的像素,默认是cv::Scalar(104, 117, 123),BGR + * @return 处理后图像 + */ + static cv::Mat padding_resize(const cv::Mat img, const FrameSize &frame_size, const cv::Scalar &padding = cv::Scalar(104, 117, 123)); + + /** + * @brief 对图片resize + * @param ori_img 原始图片 + * @param frame_size 需要resize图像的宽高 + * @return 处理后图像 + */ + static cv::Mat resize(const cv::Mat ori_img, const FrameSize &frame_size); + + /** + * @brief 对图片crop + * @param ori_img 原始图片 + * @param crop_info 需要crop的位置,x,y,w,h + * @return 处理后图像 + */ + static cv::Mat crop(const cv::Mat ori_img, Bbox &crop_info); + + /** + * @brief 将图片从bgr转为rgb + * @param ori_img 原始图片 + * @return 处理后图像 + */ + static cv::Mat bgr_to_rgb(cv::Mat ori_img); + + /** + * @brief 将RGB或RGB图片从hwc转为chw + * @param ori_img 原始图片 + * @param chw_vec 转为chw后的数据 + * @return None + */ + static void hwc_to_chw(cv::Mat &ori_img, std::vector &chw_vec); // for rgb data + + /** + * @brief 将BGR图片从hwc转为chw + * @param ori_img 原始图片 + * @param chw_vec 转为chw后的数据 + * @return None + */ + static void bgr2rgb_and_hwc2chw(cv::Mat &ori_img, std::vector &chw_vec); + + /*************************for ai2d ori_img process********************/ + // resize + /** + * @brief resize函数,对chw数据进行resize + * @param ori_shape 原始数据chw + * @param chw_vec 原始数据 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + static void resize(FrameCHWSize ori_shape, std::vector &chw_vec, runtime_tensor &ai2d_out_tensor); + + /** + * @brief resize函数 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + static void resize(std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor); + + // crop resize + /** + * @brief resize函数,对chw数据进行crop & resize + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + static void crop_resize(FrameCHWSize ori_shape, std::vector &chw_vec, Bbox &crop_info, runtime_tensor &ai2d_out_tensor); + + /** + * @brief crop_resize函数,对chw数据进行crop & resize + * @param crop_info 需要crop的位置,x,y,w,h + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + static void crop_resize(Bbox &crop_info, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor); + + // padding resize + /** + * @brief padding_resize函数(上下左右padding),对chw数据进行padding & resize + * @param ori_shape 原始数据chw + * @param chw_vec 原始数据 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + static void padding_resize(FrameCHWSize ori_shape, std::vector &chw_vec, FrameSize resize_shape, runtime_tensor &ai2d_out_tensor, cv::Scalar padding); + + /** + * @brief padding_resize函数(右或下padding),对chw数据进行padding & resize + * @param ori_shape 原始数据chw + * @param chw_vec 原始数据 + * @param resize_shape resize之后的大小 + * @param ai2d_out_tensor ai2d输出 + * @param padding 填充值,用于resize时的等比例变换 + * @return None + */ + static void padding_resize_one_side(FrameCHWSize ori_shape, std::vector &chw_vec, FrameSize resize_shape, runtime_tensor &ai2d_out_tensor, cv::Scalar padding); + + /** + * @brief padding_resize函数(上下左右padding),对chw数据进行padding & resize + * @param ori_shape 原始数据chw + * @param resize_shape resize之后的大小 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @param padding 填充值,用于resize时的等比例变换 + * @return None + */ + static void padding_resize(FrameCHWSize ori_shape, FrameSize resize_shape, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor, cv::Scalar padding); + + /** + * @brief padding_resize函数(右或下padding),对chw数据进行padding & resize + * @param ori_shape 原始数据chw + * @param resize_shape resize之后的大小 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @param padding 填充值,用于resize时的等比例变换 + * @return None + */ + static void padding_resize_one_side(FrameCHWSize ori_shape, FrameSize resize_shape, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor, const cv::Scalar padding); + + // affine + /** + * @brief 仿射变换函数,对chw数据进行仿射变换(for imgae) + * @param ori_shape 原始数据chw大小 + * @param ori_data 原始数据 + * @param affine_matrix 仿射变换矩阵 + * @param ai2d_out_tensor 仿射变换后的数据 + * @return None + */ + static void affine(FrameCHWSize ori_shape, std::vector &ori_data, float *affine_matrix, runtime_tensor &ai2d_out_tensor); + + /** + * @brief 仿射变换函数,对chw数据进行仿射变换(for video) + * @param affine_matrix 仿射变换矩阵 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + static void affine(float *affine_matrix, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor); + + /** + * @brief 透射变换后crop + * @param src 原始图像 + * @param dst 处理后的图像 + * @param b ocr检测出的四边形角点对 + * @return None + */ + static void warppersp(cv::Mat src, cv::Mat& dst, Boxb b); + + /** + * @brief 单图 画英文 + * @param image 作图的图像 + * @param x_offset 写字起始横坐标 + * @param y_offset 写字起始纵坐标 + * @param offset 英文字符的偏移量 + * @return None + */ + static void paint_ascii(cv::Mat& image,int x_offset,int y_offset,unsigned long offset); + + /** + * @brief video 画英文 + * @param image 作图的图像 + * @param x_offset 写字起始横坐标 + * @param y_offset 写字起始纵坐标 + * @param offset 英文字符的偏移量 + * @return None + */ + static void paint_ascii_video(cv::Mat& image,int x_offset,int y_offset,unsigned long offset); + + /** + * @brief 单图 画中文 + * @param image 作图的图像 + * @param x_offset 写字起始横坐标 + * @param y_offset 写字起始纵坐标 + * @param offset 中文字符的偏移量 + * @return None + */ + static void paint_chinese(cv::Mat& image,int x_offset,int y_offset,unsigned long offset); + + /** + * @brief video 画中文 + * @param image 作图的图像 + * @param x_offset 写字起始横坐标 + * @param y_offset 写字起始纵坐标 + * @param offset 中文字符的偏移量 + * @return None + */ + static void paint_chinese_video(cv::Mat& image,int x_offset,int y_offset,unsigned long offset); + + /** + * @brief 单图 写文本 + * @param x_offset 作图起始横坐标 + * @param y_offset 作图起始纵坐标 + * @param image 作图的图像 + * @param vec16 文字的16进制表示 + * @return None + */ + static void draw_text(int x_offset,int y_offset,cv::Mat& image,vector vec16); + + /** + * @brief video 写文本 + * @param x_offset 作图起始横坐标 + * @param y_offset 作图起始纵坐标 + * @param image 作图的图像 + * @param vec16 文字的16进制表示 + * @param osd_frame_size osd宽高 + * @param sensor_frame_size sensor宽高 + * @return None + */ + static void draw_text(float x_offset,float y_offset,cv::Mat& image,vector vec16, FrameSize osd_frame_size, FrameSize sensor_frame_size); + + /** + * @brief 将ocr检测结果画在图像中 + * @param frame 原始图像 + * @param detections 检测框的点对 + * @return None + */ + static void draw_detections(cv::Mat& frame, vector& detections); + + /** + * @brief 将ocr检测结果画在屏幕的osd中 + * @param frame 原始图像 + * @param detections 检测框的点对 + * @param osd_frame_size osd的宽高 + * @param sensor_frame_size sensor的宽高 + * @return None + */ + static void draw_detections(cv::Mat& frame, vector& detections, FrameSize osd_frame_size, FrameSize sensor_frame_size); +}; + +#endif diff --git a/src/reference/ai_poc/sq_handkp_flower/vi_vo.h b/src/reference/ai_poc/sq_handkp_flower/vi_vo.h new file mode 100644 index 000000000..e3d8bdba4 --- /dev/null +++ b/src/reference/ai_poc/sq_handkp_flower/vi_vo.h @@ -0,0 +1,627 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include "mpi_sys_api.h" + +/* vicap */ +#include +#include +#include +#include +#include + +#include "k_module.h" +#include "k_type.h" +#include "k_vb_comm.h" +#include "k_video_comm.h" +#include "k_sys_comm.h" +#include "mpi_vb_api.h" +#include "mpi_vicap_api.h" +#include "mpi_isp_api.h" +#include "mpi_sys_api.h" +#include "k_vo_comm.h" +#include "mpi_vo_api.h" + +#include "vo_test_case.h" + +#include "k_connector_comm.h" +#include "mpi_connector_api.h" +#include "k_autoconf_comm.h" + + +#if defined(CONFIG_BOARD_K230_CANMV) +#define SENSOR_CHANNEL (3) // isp通道数 +#define SENSOR_HEIGHT (720) // isp高度,ai输入,竖屏 +#define SENSOR_WIDTH (1280) // isp宽度,ai输入,竖屏 +#define ISP_CHN0_WIDTH (1920)//(1920) +#define ISP_CHN0_HEIGHT (1080)//(1080) +#define vicap_install_osd (1) +#define osd_id K_VO_OSD3 +#define osd_width (1920) +#define osd_height (1080) +#else +#define SENSOR_CHANNEL (3) // isp通道数 +#define SENSOR_HEIGHT (1280) // isp高度,ai输入,竖屏 +#define SENSOR_WIDTH (720) // isp宽度,ai输入,竖屏 +#define ISP_CHN0_WIDTH (1088)//(1920) +#define ISP_CHN0_HEIGHT (1920)//(1080) +#define vicap_install_osd (1) +#define osd_id K_VO_OSD3 +#define osd_width (1080) +#define osd_height (1920) +#endif + + +k_vb_config config; +k_vicap_dev vicap_dev; +k_vicap_chn vicap_chn; +k_vicap_dev_attr dev_attr; +k_vicap_chn_attr chn_attr; +k_vicap_sensor_info sensor_info; +k_vicap_sensor_type sensor_type; +k_mpp_chn vicap_mpp_chn; +k_mpp_chn vo_mpp_chn; + +k_video_frame_info dump_info; + +k_vo_draw_frame vo_frame = (k_vo_draw_frame) { + 1, + 16, + 16, + 128, + 128, + 1 +}; + +static k_vb_blk_handle block; +k_u32 g_pool_id; + +int vo_creat_layer_test(k_vo_layer chn_id, layer_info *info) +{ + k_vo_video_layer_attr attr; + + // check layer + if ((chn_id >= K_MAX_VO_LAYER_NUM) || ((info->func & K_VO_SCALER_ENABLE) && (chn_id != K_VO_LAYER0)) + || ((info->func != 0) && (chn_id == K_VO_LAYER2))) + { + printf("input layer num failed \n"); + return -1 ; + } + + // check scaler + + // set offset + attr.display_rect = info->offset; + // set act + attr.img_size = info->act_size; + // sget size + info->size = info->act_size.height * info->act_size.width * 3 / 2; + //set pixel format + attr.pixel_format = info->format; + if (info->format != PIXEL_FORMAT_YVU_PLANAR_420) + { + printf("input pix format failed \n"); + return -1; + } + // set stride + attr.stride = (info->act_size.width / 8 - 1) + ((info->act_size.height - 1) << 16); + // set function + attr.func = info->func; + // set scaler attr + attr.scaler_attr = info->attr; + + // set video layer atrr + kd_mpi_vo_set_video_layer_attr(chn_id, &attr); + + // enable layer + kd_mpi_vo_enable_video_layer(chn_id); + + return 0; +} + +k_vb_blk_handle vo_insert_frame(k_video_frame_info *vf_info, void **pic_vaddr) +{ + k_u64 phys_addr = 0; + k_u32 *virt_addr; + k_vb_blk_handle handle; + k_s32 size; + + if (vf_info == NULL) + return K_FALSE; + + if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_ABGR_8888 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_ARGB_8888) + size = vf_info->v_frame.height * vf_info->v_frame.width * 4; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_RGB_565 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_BGR_565) + size = vf_info->v_frame.height * vf_info->v_frame.width * 2; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_ABGR_4444 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_ARGB_4444) + size = vf_info->v_frame.height * vf_info->v_frame.width * 2; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_RGB_888 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_BGR_888) + size = vf_info->v_frame.height * vf_info->v_frame.width * 3; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_ARGB_1555 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_ABGR_1555) + size = vf_info->v_frame.height * vf_info->v_frame.width * 2; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_YVU_PLANAR_420) + size = vf_info->v_frame.height * vf_info->v_frame.width * 3 / 2; + + size = size + 4096; // 强制4K ,后边得删了 + + printf("vb block size is %x \n", size); + + handle = kd_mpi_vb_get_block(g_pool_id, size, NULL); + if (handle == VB_INVALID_HANDLE) + { + printf("%s get vb block error\n", __func__); + return K_FAILED; + } + + phys_addr = kd_mpi_vb_handle_to_phyaddr(handle); + if (phys_addr == 0) + { + printf("%s get phys addr error\n", __func__); + return K_FAILED; + } + + virt_addr = (k_u32 *)kd_mpi_sys_mmap(phys_addr, size); + // virt_addr = (k_u32 *)kd_mpi_sys_mmap_cached(phys_addr, size); + + if (virt_addr == NULL) + { + printf("%s mmap error\n", __func__); + return K_FAILED; + } + + vf_info->mod_id = K_ID_VO; + vf_info->pool_id = g_pool_id; + vf_info->v_frame.phys_addr[0] = phys_addr; + if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_YVU_PLANAR_420) + vf_info->v_frame.phys_addr[1] = phys_addr + (vf_info->v_frame.height * vf_info->v_frame.stride[0]); + *pic_vaddr = virt_addr; + + printf("phys_addr is %lx g_pool_id is %d \n", phys_addr, g_pool_id); + + return handle; +} + +k_u32 vo_creat_osd_test(k_vo_osd osd, osd_info *info) +{ + k_vo_video_osd_attr attr; + + // set attr + attr.global_alptha = info->global_alptha; + + if (info->format == PIXEL_FORMAT_ABGR_8888 || info->format == PIXEL_FORMAT_ARGB_8888) + { + info->size = info->act_size.width * info->act_size.height * 4; + info->stride = info->act_size.width * 4 / 8; + } + else if (info->format == PIXEL_FORMAT_RGB_565 || info->format == PIXEL_FORMAT_BGR_565) + { + info->size = info->act_size.width * info->act_size.height * 2; + info->stride = info->act_size.width * 2 / 8; + } + else if (info->format == PIXEL_FORMAT_RGB_888 || info->format == PIXEL_FORMAT_BGR_888) + { + info->size = info->act_size.width * info->act_size.height * 3; + info->stride = info->act_size.width * 3 / 8; + } + else if(info->format == PIXEL_FORMAT_ARGB_4444 || info->format == PIXEL_FORMAT_ABGR_4444) + { + info->size = info->act_size.width * info->act_size.height * 2; + info->stride = info->act_size.width * 2 / 8; + } + else if(info->format == PIXEL_FORMAT_ARGB_1555 || info->format == PIXEL_FORMAT_ABGR_1555) + { + info->size = info->act_size.width * info->act_size.height * 2; + info->stride = info->act_size.width * 2 / 8; + } + else + { + printf("set osd pixel format failed \n"); + } + + attr.stride = info->stride; + attr.pixel_format = info->format; + attr.display_rect = info->offset; + attr.img_size = info->act_size; + kd_mpi_vo_set_video_osd_attr(osd, &attr); + + kd_mpi_vo_osd_enable(osd); + + return 0; +} + +void sample_vicap_install_osd(void) +{ + osd_info osd; + + osd.act_size.width = osd_width ; + osd.act_size.height = osd_height; + osd.offset.x = 0; + osd.offset.y = 0; + osd.global_alptha = 0xff; + // osd.global_alptha = 0x32; + osd.format = PIXEL_FORMAT_ARGB_8888;//PIXEL_FORMAT_ARGB_4444; //PIXEL_FORMAT_ARGB_1555;//PIXEL_FORMAT_ARGB_8888; + + vo_creat_osd_test(osd_id, &osd); +} + +void vo_osd_release_block(void) +{ + if(vicap_install_osd == 1) + { + kd_mpi_vo_osd_disable(osd_id); + kd_mpi_vb_release_block(block); + } + +} + +static k_s32 sample_connector_init(void) +{ + k_u32 ret = 0; + k_s32 connector_fd; +#if defined(CONFIG_BOARD_K230_CANMV) + k_connector_type connector_type = LT9611_MIPI_4LAN_1920X1080_30FPS;// HX8377_V2_MIPI_4LAN_1080X1920_30FPS; +#else + k_connector_type connector_type = HX8377_V2_MIPI_4LAN_1080X1920_30FPS; +#endif + k_connector_info connector_info; + + memset(&connector_info, 0, sizeof(k_connector_info)); + + //connector get sensor info + ret = kd_mpi_get_connector_info(connector_type, &connector_info); + if (ret) { + printf("sample_vicap, the sensor type not supported!\n"); + return ret; + } + + connector_fd = kd_mpi_connector_open(connector_info.connector_name); + if (connector_fd < 0) { + printf("%s, connector open failed.\n", __func__); + return K_ERR_VO_NOTREADY; + } + + // set connect power + kd_mpi_connector_power_set(connector_fd, K_TRUE); + // connector init + kd_mpi_connector_init(connector_fd, connector_info); + + return 0; +} + +static k_s32 vo_layer_vdss_bind_vo_config(void) +{ + layer_info info; + + k_vo_layer chn_id = K_VO_LAYER1; + + memset(&info, 0, sizeof(info)); + + sample_connector_init(); + + // config lyaer + info.act_size.width = ISP_CHN0_WIDTH;//ISP_CHN0_HEIGHT;//1080;//640;//1080; + info.act_size.height = ISP_CHN0_HEIGHT;//ISP_CHN0_WIDTH;//1920;//480;//1920; + info.format = PIXEL_FORMAT_YVU_PLANAR_420; + info.func = 0;//K_ROTATION_180;////K_ROTATION_90; + info.global_alptha = 0xff; + info.offset.x = 0;//(1080-w)/2, + info.offset.y = 0;//(1920-h)/2; + vo_creat_layer_test(chn_id, &info); + + if(vicap_install_osd == 1) + sample_vicap_install_osd(); + + //exit ; + return 0; +} + +static void sample_vicap_bind_vo(k_mpp_chn vicap_mpp_chn, k_mpp_chn vo_mpp_chn) +{ + k_s32 ret; + + ret = kd_mpi_sys_bind(&vicap_mpp_chn, &vo_mpp_chn); + if (ret) { + printf("kd_mpi_sys_unbind failed:0x%x\n", ret); + } + + return; +} + +static void sample_vicap_unbind_vo(k_mpp_chn vicap_mpp_chn, k_mpp_chn vo_mpp_chn) +{ + k_s32 ret; + + ret = kd_mpi_sys_unbind(&vicap_mpp_chn, &vo_mpp_chn); + if (ret) { + printf("kd_mpi_sys_unbind failed:0x%x\n", ret); + } + + return; +} + +int vivcap_start() +{ + k_s32 ret = 0; + + k_u32 pool_id; + k_vb_pool_config pool_config; + + printf("sample_vicap ...\n"); + +#if defined(CONFIG_BOARD_K230_CANMV) + sensor_type = OV_OV5647_MIPI_CSI0_1920X1080_30FPS_10BIT_LINEAR; + kd_mpi_vicap_set_mclk(VICAP_MCLK0, VICAP_PLL0_CLK_DIV4, 16, 1); +#else + sensor_type = IMX335_MIPI_2LANE_RAW12_2592X1944_30FPS_LINEAR; +#endif + vicap_dev = VICAP_DEV_ID_0; + + memset(&config, 0, sizeof(config)); + config.max_pool_cnt = 64; + //VB for YUV420SP output + config.comm_pool[0].blk_cnt = 5; + config.comm_pool[0].mode = VB_REMAP_MODE_NOCACHE; + config.comm_pool[0].blk_size = VICAP_ALIGN_UP((ISP_CHN0_WIDTH * ISP_CHN0_HEIGHT * 3 / 2), VICAP_ALIGN_1K); + + //VB for RGB888 output + config.comm_pool[1].blk_cnt = 5; + config.comm_pool[1].mode = VB_REMAP_MODE_NOCACHE; + config.comm_pool[1].blk_size = VICAP_ALIGN_UP((SENSOR_HEIGHT * SENSOR_WIDTH * 3 ), VICAP_ALIGN_1K); + + ret = kd_mpi_vb_set_config(&config); + if (ret) { + printf("vb_set_config failed ret:%d\n", ret); + return ret; + } + + k_vb_supplement_config supplement_config; + memset(&supplement_config, 0, sizeof(supplement_config)); + supplement_config.supplement_config |= VB_SUPPLEMENT_JPEG_MASK; + + ret = kd_mpi_vb_set_supplement_config(&supplement_config); + if (ret) { + printf("vb_set_supplement_config failed ret:%d\n", ret); + return ret; + } + + ret = kd_mpi_vb_init(); + if (ret) { + printf("vb_init failed ret:%d\n", ret); + return ret; + } + printf("sample_vicap ...kd_mpi_vicap_get_sensor_info\n"); + + // dwc_dsi_init(); + vo_layer_vdss_bind_vo_config(); + + if(vicap_install_osd == 1) + { + memset(&pool_config, 0, sizeof(pool_config)); + pool_config.blk_size = VICAP_ALIGN_UP((osd_width * osd_height * 4 * 2), VICAP_ALIGN_1K); + pool_config.blk_cnt = 4; + pool_config.mode = VB_REMAP_MODE_NOCACHE; + pool_id = kd_mpi_vb_create_pool(&pool_config); // osd0 - 3 argb 320 x 240 + g_pool_id = pool_id; + + printf("--------aa--------------g_pool_id is %d pool_id is %d \n",g_pool_id, pool_id); + } + + memset(&sensor_info, 0, sizeof(k_vicap_sensor_info)); + ret = kd_mpi_vicap_get_sensor_info(sensor_type, &sensor_info); + if (ret) { + printf("sample_vicap, the sensor type not supported!\n"); + return ret; + } + + memset(&dev_attr, 0, sizeof(k_vicap_dev_attr)); + dev_attr.acq_win.h_start = 0; + dev_attr.acq_win.v_start = 0; +#if defined (CONFIG_BOARD_K230_CANMV) + dev_attr.acq_win.width = ISP_CHN0_WIDTH; + dev_attr.acq_win.height = ISP_CHN0_HEIGHT; +#else + dev_attr.acq_win.width = 2592;//SENSOR_HEIGHT; + dev_attr.acq_win.height = 1944;//SENSOR_WIDTH; +#endif + dev_attr.mode = VICAP_WORK_ONLINE_MODE; + + dev_attr.pipe_ctrl.data = 0xFFFFFFFF; + dev_attr.pipe_ctrl.bits.af_enable = 0; + dev_attr.pipe_ctrl.bits.ahdr_enable = 0; + + + dev_attr.cpature_frame = 0; + memcpy(&dev_attr.sensor_info, &sensor_info, sizeof(k_vicap_sensor_info)); + + ret = kd_mpi_vicap_set_dev_attr(vicap_dev, dev_attr); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_set_dev_attr failed.\n"); + return ret; + } + + memset(&chn_attr, 0, sizeof(k_vicap_chn_attr)); + + //set chn0 output yuv420sp + chn_attr.out_win.h_start = 0; + chn_attr.out_win.v_start = 0; + chn_attr.out_win.width = ISP_CHN0_WIDTH; + chn_attr.out_win.height = ISP_CHN0_HEIGHT; + + +#if defined(CONFIG_BOARD_K230_CANMV) + chn_attr.crop_win = dev_attr.acq_win; +#else + // chn_attr.crop_win = dev_attr.acq_win; + chn_attr.crop_win.h_start = 768; + chn_attr.crop_win.v_start = 16; + chn_attr.crop_win.width = ISP_CHN0_WIDTH; + chn_attr.crop_win.height = ISP_CHN0_HEIGHT; +#endif + + chn_attr.scale_win = chn_attr.out_win; + chn_attr.crop_enable = K_FALSE; + chn_attr.scale_enable = K_FALSE; + // chn_attr.dw_enable = K_FALSE; + chn_attr.chn_enable = K_TRUE; + chn_attr.pix_format = PIXEL_FORMAT_YVU_PLANAR_420; + chn_attr.buffer_num = VICAP_MAX_FRAME_COUNT;//at least 3 buffers for isp + chn_attr.buffer_size = config.comm_pool[0].blk_size; + vicap_chn = VICAP_CHN_ID_0; + + printf("sample_vicap ...kd_mpi_vicap_set_chn_attr, buffer_size[%d]\n", chn_attr.buffer_size); + ret = kd_mpi_vicap_set_chn_attr(vicap_dev, vicap_chn, chn_attr); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_set_chn_attr failed.\n"); + return ret; + } + + //bind vicap chn 0 to vo + vicap_mpp_chn.mod_id = K_ID_VI; + vicap_mpp_chn.dev_id = vicap_dev; + vicap_mpp_chn.chn_id = vicap_chn; + + vo_mpp_chn.mod_id = K_ID_VO; + vo_mpp_chn.dev_id = K_VO_DISPLAY_DEV_ID; + vo_mpp_chn.chn_id = K_VO_DISPLAY_CHN_ID1; + + sample_vicap_bind_vo(vicap_mpp_chn, vo_mpp_chn); + printf("sample_vicap ...dwc_dsi_init\n"); + + //set chn1 output rgb888p + chn_attr.out_win.h_start = 0; + chn_attr.out_win.v_start = 0; + chn_attr.out_win.width = SENSOR_WIDTH ; + chn_attr.out_win.height = SENSOR_HEIGHT; + // chn_attr.crop_win = dev_attr.acq_win; + +#if defined(CONFIG_BOARD_K230_CANMV) + chn_attr.crop_win = dev_attr.acq_win; +#else + chn_attr.crop_win.h_start = 768; + chn_attr.crop_win.v_start = 16; + chn_attr.crop_win.width = ISP_CHN0_WIDTH; + chn_attr.crop_win.height = ISP_CHN0_HEIGHT; +#endif + + chn_attr.scale_win = chn_attr.out_win; + chn_attr.crop_enable = K_FALSE; + chn_attr.scale_enable = K_FALSE; + // chn_attr.dw_enable = K_FALSE; + chn_attr.chn_enable = K_TRUE; + chn_attr.pix_format = PIXEL_FORMAT_BGR_888_PLANAR; + chn_attr.buffer_num = VICAP_MAX_FRAME_COUNT;//at least 3 buffers for isp + chn_attr.buffer_size = config.comm_pool[1].blk_size; + + printf("sample_vicap ...kd_mpi_vicap_set_chn_attr, buffer_size[%d]\n", chn_attr.buffer_size); + ret = kd_mpi_vicap_set_chn_attr(vicap_dev, VICAP_CHN_ID_1, chn_attr); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_set_chn_attr failed.\n"); + return ret; + } + + printf("sample_vicap ...kd_mpi_vicap_init\n"); + ret = kd_mpi_vicap_init(vicap_dev); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_init failed.\n"); + // goto err_exit; + } + + printf("sample_vicap ...kd_mpi_vicap_start_stream\n"); + ret = kd_mpi_vicap_start_stream(vicap_dev); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_init failed.\n"); + // goto err_exit; + } + + return ret; +} + +int vivcap_stop() +{ + printf("sample_vicap ...kd_mpi_vicap_stop_stream\n"); + int ret = kd_mpi_vicap_stop_stream(vicap_dev); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_init failed.\n"); + return ret; + } + + ret = kd_mpi_vicap_deinit(vicap_dev); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_deinit failed.\n"); + return ret; + } + + kd_mpi_vo_disable_video_layer(K_VO_LAYER1); + + vicap_mpp_chn.mod_id = K_ID_VI; + vicap_mpp_chn.dev_id = vicap_dev; + vicap_mpp_chn.chn_id = vicap_chn; + + vo_mpp_chn.mod_id = K_ID_VO; + vo_mpp_chn.dev_id = K_VO_DISPLAY_DEV_ID; + vo_mpp_chn.chn_id = K_VO_DISPLAY_CHN_ID1; + + sample_vicap_unbind_vo(vicap_mpp_chn, vo_mpp_chn); + + /*Allow one frame time for the VO to release the VB block*/ + k_u32 display_ms = 1000 / 33; + usleep(1000 * display_ms); + + ret = kd_mpi_vb_exit(); + if (ret) { + printf("sample_vicap, kd_mpi_vb_exit failed.\n"); + return ret; + } + + return 0; +} + +void yuv_rotate_90(char *des, char *src,int width,int height) +{ + int n = 0; + int hw = width>>1; + int hh = height>>1; + int size = width * height; + int hsize = size>>2; + + int pos = 0; + + for(int i = width-1;i >= 0;i--) + { + pos = 0; + for(int j= 0;j < height;j++) + { + des[n++]= src[pos+i]; + pos += width; + } + } + +} \ No newline at end of file diff --git a/src/reference/ai_poc/translate_en_ch/CMakeLists.txt b/src/reference/ai_poc/translate_en_ch/CMakeLists.txt new file mode 100644 index 000000000..6e0c319bd --- /dev/null +++ b/src/reference/ai_poc/translate_en_ch/CMakeLists.txt @@ -0,0 +1,14 @@ +set(src ai_base.cc main.cc etranslate.cc dtranslate.cc) +set(bin translate_en_ch.elf) + +include_directories(${PROJECT_SOURCE_DIR}) +include_directories(${nncase_sdk_root}/riscv64/rvvlib/include) + +link_directories(${PROJECT_SOURCE_DIR}/../../big/kmodel/ai_poc/utils/) +link_directories(${nncase_sdk_root}/riscv64/rvvlib/) + +add_executable(${bin} ${src}) +target_link_libraries(${bin} sentencepiece.a) +target_link_libraries(${bin} -Wl,--start-group rvv Nncase.Runtime.Native nncase.rt_modules.k230 functional_k230 sys) + +install(TARGETS ${bin} DESTINATION bin) diff --git a/src/reference/ai_poc/translate_en_ch/README.md b/src/reference/ai_poc/translate_en_ch/README.md new file mode 100644 index 000000000..4bf9a9809 --- /dev/null +++ b/src/reference/ai_poc/translate_en_ch/README.md @@ -0,0 +1,27 @@ +# 1.简介 + +机器翻译模型应用了transformer结构。使用该应用,可以实现简单的英翻中翻译任务。 + +# 2.应用使用说明 + +## 2.1 使用帮助 +开发板需求:当前模型无特殊要求;若是需要更大的模型,则需要用lp4(2G)开发板 + +``` +"Usage: " << name << " " +各参数释义如下: +kmodel_encoder 编码器kmodel路径 +kmodel_decoder 解码器kmodel路径 +src_model_file 原语言分词器模型路径 +tag_model_file 翻译后语言分词器模型路径 +debug_mode 是否需要调试,0、1、2分别表示不调试、简单调试、详细调试 + + #推理示例:(translate_en_ch.sh) +translate_en_ch.elf translate_encoder.kmodel translate_decoder.kmodel trans_src.model trans_tag.model 0 +``` +## 2.2 效果展示 +translate_result.jpg + + + + diff --git a/src/reference/ai_poc/translate_en_ch/ai_base.cc b/src/reference/ai_poc/translate_en_ch/ai_base.cc new file mode 100644 index 000000000..b149a68bc --- /dev/null +++ b/src/reference/ai_poc/translate_en_ch/ai_base.cc @@ -0,0 +1,183 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "ai_base.h" + +#include +#include +#include +#include + +#include + +using std::cout; +using std::endl; +using namespace nncase; +using namespace nncase::runtime::detail; + +AIBase::AIBase(const char *kmodel_file,const string model_name, const int debug_mode) : debug_mode_(debug_mode),model_name_(model_name) +{ + if (debug_mode > 1) + cout << "kmodel_file:" << kmodel_file << endl; + std::ifstream ifs(kmodel_file, std::ios::binary); + kmodel_interp_.load_model(ifs).expect("Invalid kmodel"); + set_input_init(); + set_output_init(); +} + +AIBase::~AIBase() +{ +} + +void AIBase::set_input_init() +{ + ScopedTiming st(model_name_ + " set_input init", debug_mode_); + int input_total_size = 0; + each_input_size_by_byte_.push_back(0); // 先补0,为之后做准备 + for (int i = 0; i < kmodel_interp_.inputs_size(); ++i) + { + auto desc = kmodel_interp_.input_desc(i); + auto shape = kmodel_interp_.input_shape(i); + auto tensor = host_runtime_tensor::create(desc.datatype, shape, hrt::pool_shared).expect("cannot create input tensor"); + kmodel_interp_.input_tensor(i, tensor).expect("cannot set input tensor"); + vector in_shape; + if (debug_mode_ > 1) + cout<<"input "<< std::to_string(i) <<" : "< 1) + cout << shape[j] << ","; + } + if (debug_mode_ > 1) + cout << endl; + input_shapes_.push_back(in_shape); + // DEFINE_TYPECODE(uint8, u8, 0x06) + // DEFINE_TYPECODE(float32, f32, 0x0B) + if (desc.datatype == dt_int8 || desc.datatype == dt_uint8) + { + input_total_size += dsize; + } + else if (desc.datatype == dt_int16 || desc.datatype == dt_uint16 || desc.datatype == dt_float16 || desc.datatype == dt_bfloat16) + { + input_total_size += (dsize * 2); + } + else if (desc.datatype == dt_int32 || desc.datatype == dt_uint32 || desc.datatype == dt_float32) + { + input_total_size += (dsize * 4); + } + else if(desc.datatype == dt_int64 || desc.datatype == dt_uint64 || desc.datatype == dt_float64) + { + input_total_size += (dsize * 8); + } + else + { + printf("input data type:%d",desc.datatype); + assert(("unsupported kmodel output data type", 0)); + } + each_input_size_by_byte_.push_back(input_total_size); + + } + each_input_size_by_byte_.push_back(input_total_size); // 最后一个保存总大小 +} + +runtime_tensor AIBase::get_input_tensor(size_t idx) +{ + return kmodel_interp_.input_tensor(idx).expect("cannot get input tensor"); +} + +void AIBase::set_output_init() +{ + ScopedTiming st(model_name_ + " set_output_init", debug_mode_); + each_output_size_by_byte_.clear(); + int output_total_size = 0; + each_output_size_by_byte_.push_back(0); + for (size_t i = 0; i < kmodel_interp_.outputs_size(); i++) + { + auto desc = kmodel_interp_.output_desc(i); + auto shape = kmodel_interp_.output_shape(i); + vector out_shape; + if (debug_mode_ > 1) + cout<<"output "< 1) + cout << shape[j] << ","; + } + if (debug_mode_ > 1) + cout << endl; + output_shapes_.push_back(out_shape); + if (desc.datatype == dt_int8 || desc.datatype == dt_uint8) + { + output_total_size += dsize; + } + else if (desc.datatype == dt_int16 || desc.datatype == dt_uint16 || desc.datatype == dt_float16 || desc.datatype == dt_bfloat16) + { + output_total_size += (dsize * 2); + } + else if (desc.datatype == dt_int32 || desc.datatype == dt_uint32 || desc.datatype == dt_float32) + { + output_total_size += (dsize * 4); + } + else if(desc.datatype == dt_int64 || desc.datatype == dt_uint64 || desc.datatype == dt_float64) + { + output_total_size += (dsize * 8); + } + else + { + printf("output data type:%d",desc.datatype); + assert(("unsupported kmodel output data type", 0)); + } + + each_output_size_by_byte_.push_back(output_total_size); + auto tensor = host_runtime_tensor::create(desc.datatype, shape, hrt::pool_shared).expect("cannot create output tensor"); + kmodel_interp_.output_tensor(i, tensor).expect("cannot set output tensor"); + } +} + +void AIBase::run() +{ + ScopedTiming st(model_name_ + " run", debug_mode_); + kmodel_interp_.run().expect("error occurred in running model"); +} + +void AIBase::get_output() +{ + ScopedTiming st(model_name_ + " get_output", debug_mode_); + p_outputs_.clear(); + for (int i = 0; i < kmodel_interp_.outputs_size(); i++) + { + auto out = kmodel_interp_.output_tensor(i).expect("cannot get output tensor"); + // auto mapped_buf = std::move(hrt::map(out, map_access_::map_read).unwrap()); + // float *p_out = reinterpret_cast(mapped_buf.buffer().data()); + auto buf = out.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_read).unwrap().buffer(); + float *p_out = reinterpret_cast(buf.data()); + p_outputs_.push_back(p_out); + } +} diff --git a/src/reference/ai_poc/translate_en_ch/ai_base.h b/src/reference/ai_poc/translate_en_ch/ai_base.h new file mode 100644 index 000000000..7486c9d35 --- /dev/null +++ b/src/reference/ai_poc/translate_en_ch/ai_base.h @@ -0,0 +1,104 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +// ai_base.h +#ifndef AI_BASE_H +#define AI_BASE_H + +#include +#include +#include + +#include +#include "scoped_timing.hpp" + +using std::string; +using std::vector; +using namespace nncase::runtime; + +/** + * @brief AI基类,封装nncase相关操作 + * 主要封装了nncase的加载、设置输入、运行、获取输出操作,后续开发demo只需要关注模型的前处理、后处理即可 + */ +class AIBase +{ +public: + /** + * @brief AI基类构造函数,加载kmodel,并初始化kmodel输入、输出 + * @param kmodel_file kmodel文件路径 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + AIBase(const char *kmodel_file,const string model_name, const int debug_mode = 1); + + /** + * @brief AI基类析构函数 + * @return None + */ + ~AIBase(); + + /** + * @brief 根据索引获取kmodel输入tensor + * @param idx 输入数据指针 + * @return None + */ + runtime_tensor get_input_tensor(size_t idx); + + /** + * @brief 推理kmodel + * @return None + */ + void run(); + + /** + * @brief 获取kmodel输出,结果保存在对应的类属性中 + * @return None + */ + void get_output(); + +protected: + string model_name_; // 模型名字 + int debug_mode_; // 调试模型,0(不打印),1(打印时间),2(打印所有) + vector p_outputs_; // kmodel输出对应的指针列表 + vector> input_shapes_; //{{N,C,H,W},{N,C,H,W}...} + vector> output_shapes_; //{{N,C,H,W},{N,C,H,W}...}} 或 {{N,C},{N,C}...}}等 + vector each_input_size_by_byte_; //{0,layer1_length,layer1_length+layer2_length,...} + vector each_output_size_by_byte_; //{0,layer1_length,layer1_length+layer2_length,...} +private: + /** + * @brief 首次初始化kmodel输入,并获取输入shape + * @return None + */ + void set_input_init(); + + /** + * @brief 首次初始化kmodel输出,并获取输出shape + * @return None + */ + void set_output_init(); + + interpreter kmodel_interp_; // kmodel解释器,从kmodel文件构建,负责模型的加载、输入输出设置和推理 + vector kmodel_vec_; // 通过读取kmodel文件得到整个kmodel数据,用于传给kmodel解释器加载kmodel +}; +#endif \ No newline at end of file diff --git a/src/reference/ai_poc/translate_en_ch/dtranslate.cc b/src/reference/ai_poc/translate_en_ch/dtranslate.cc new file mode 100644 index 000000000..0fe8dc452 --- /dev/null +++ b/src/reference/ai_poc/translate_en_ch/dtranslate.cc @@ -0,0 +1,166 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "dtranslate.h" + + +DTranslate::DTranslate(const char *kmodel_file, const char *tag_model_file, const int debug_mode) +:AIBase(kmodel_file, "DTranslate", debug_mode) +{ + const auto tag_status = sp_tag.Load(tag_model_file); + if (!tag_status.ok()) { + std::cerr << tag_status.ToString() << std::endl; + } + pad_id = sp_tag.pad_id(); + bos_id = sp_tag.bos_id(); + eos_id = sp_tag.eos_id(); + + in_tensor_0 = get_input_tensor(0); + in_tensor_1 = get_input_tensor(1); + in_tensor_2 = get_input_tensor(2); + in_tensor_3 = get_input_tensor(3); +} + +DTranslate::~DTranslate() +{ + delete[] dst_mask; + delete[] src_dst_mask; +} + +void DTranslate::pre_process(int index, vector &input_y, float *encoder_kv, int src_token_size) +{ + ScopedTiming st("Decoder preprocess", debug_mode_); + if (index == 0) + { + maxlen = input_shapes_[0][1]; + d_model = input_shapes_[1][2]; + vocab_size = output_shapes_[0][2]; + input_y = vector(maxlen,pad_id); + input_y[0] = bos_id; + dst_mask = new uint8_t[maxlen*maxlen]; + src_dst_mask = new uint8_t[maxlen*maxlen]; + + for (int i = 0; i < maxlen; i++) + { + for (int j = 0; j < maxlen; j++) + { + if (i < 1 and j < 1) + { + dst_mask[i*maxlen + j] = 0; + } + else + { + dst_mask[i*maxlen + j] = 1; + } + } + } + + for (int i = 0; i < maxlen; i++) + { + for (int j = 0; j < maxlen; j++) + { + if (i < 1 and j < src_token_size) + { + src_dst_mask[i*maxlen + j] = 0; + } + else + { + src_dst_mask[i*maxlen + j] = 1; + } + } + } + } + else + { + for (int i = 0; i < index + 1; i++) + { + dst_mask[i*maxlen + index] = 0; + } + for (int j = 0; j < index + 1; j++) + { + dst_mask[index*maxlen + j] = 0; + } + + for (int j = 0; j < src_token_size; j++) + { + src_dst_mask[index*maxlen + j] = 0; + } + } + + size_t in_tensor_0_size = maxlen; + size_t in_tensor_1_size = maxlen*d_model; + size_t in_tensor_2_size = maxlen*maxlen; + size_t in_tensor_3_size = maxlen*maxlen; + auto buf_0 = in_tensor_0.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + auto buf_1 = in_tensor_1.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + auto buf_2 = in_tensor_2.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + auto buf_3 = in_tensor_3.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(buf_0.data()), input_y.data(), in_tensor_0_size*8); + memcpy(reinterpret_cast(buf_1.data()), encoder_kv, in_tensor_1_size*4); + memcpy(reinterpret_cast(buf_2.data()), dst_mask, in_tensor_2_size); + memcpy(reinterpret_cast(buf_3.data()), src_dst_mask, in_tensor_3_size); + hrt::sync(in_tensor_0, sync_op_t::sync_write_back, true).expect("sync write_back failed"); + hrt::sync(in_tensor_1, sync_op_t::sync_write_back, true).expect("sync write_back failed"); + hrt::sync(in_tensor_2, sync_op_t::sync_write_back, true).expect("sync write_back failed"); + hrt::sync(in_tensor_3, sync_op_t::sync_write_back, true).expect("sync write_back failed"); +} + + +void DTranslate::inference() +{ + this->run(); + this->get_output(); +} + +void DTranslate::post_process(int next_index, vector &result,vector &int_res, bool *stop) +{ + ScopedTiming st("Decoder postprocess", debug_mode_); + output = p_outputs_[0]; + int max_index = 0; + float max_value = FLT_MIN; + + for(int i = 0; i < vocab_size; i++) + { + if(output[(next_index-1)*vocab_size + i] > max_value) + { + max_value = output[(next_index-1)*vocab_size + i]; + max_index = i; + } + } + + result[next_index] = max_index; + int_res.push_back(max_index); + if (max_index == eos_id) + { + *stop = true; + } +} + +string DTranslate::decode_post(vector int_res) +{ + ScopedTiming st("Decoder decode", debug_mode_); + string result; + sp_tag.Decode(int_res, &result); + return result; +} \ No newline at end of file diff --git a/src/reference/ai_poc/translate_en_ch/dtranslate.h b/src/reference/ai_poc/translate_en_ch/dtranslate.h new file mode 100644 index 000000000..1c061673a --- /dev/null +++ b/src/reference/ai_poc/translate_en_ch/dtranslate.h @@ -0,0 +1,127 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _DTRANSLATE_H +#define _DTRANSLATE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "sentencepiece_processor.h" +#include "ai_base.h" + +using namespace nncase; +using namespace nncase::runtime; +using namespace nncase::runtime::detail; +using namespace std; + + +/** + * @brief 翻译 + * 主要封装了解码器对被翻译的句子,从预处理、运行到后处理给出结果的过程 + */ +class DTranslate:public AIBase +{ +public: + /** + * @brief DTranslate构造函数,加载kmodel,并初始化kmodel输入、输出 + * @param kmodel_file kmodel文件路径 + * @param tag_model_file 分词器模型路径 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + DTranslate(const char *kmodel_file, const char *tag_model_file, const int debug_mode); + + /** + * @brief DTranslate析构函数 + * @return None + */ + ~DTranslate(); + + /** + * @brief 解码器预处理 + * @param index 翻译指定位置 + * @param input_y 解码器输入 + * @param encoder_kv 编码器输出 + * @param src_pad_mask 被翻译句子token掩码 + * @return None + */ + void pre_process(int index, vector &input_y, float *encoder_kv, int src_token_size); + + /** + * @brief kmodel推理 + * @return None + */ + void inference(); + + /** + * @brief 解码器kmodel推理结果后处理 + * @param next_index 翻译后的填写位置 + * @param result 解码器输入 + * @param int_res 翻译结果 + * @param stop 是否停止翻译 + * @return None + */ + void post_process(int next_index, vector &result, vector &int_res, bool *stop); + + /** + * @brief 解码器解码 + * @param int_res 翻译结果 + * @return string 翻译后的句子 + */ + string decode_post(vector int_res); + +private: + + runtime_tensor in_tensor_0; // 第1个输入tensor + runtime_tensor in_tensor_1; // 第2个输出tensor + runtime_tensor in_tensor_2; // 第3个输入tensor + runtime_tensor in_tensor_3; // 第4个输出tensor + + int maxlen; //模型最大输入token长度 + int d_model; //模型单个token编码长度 + sentencepiece::SentencePieceProcessor sp_tag; //翻译后语言分词器 + uint8_t *dst_mask; //翻译后语言句子掩码 + uint8_t *src_dst_mask; //翻译前和翻译后句子结合掩码 + int pad_id; //翻译后语言的 token pad 值 + int bos_id; //翻译后语言的起始符编号 + int eos_id; //翻译后语言的终止符编号 + int vocab_size; //翻译后语言字典长度 + float *output; //编码器模型输出 +}; +#endif diff --git a/src/reference/ai_poc/translate_en_ch/etranslate.cc b/src/reference/ai_poc/translate_en_ch/etranslate.cc new file mode 100644 index 000000000..8e54872a0 --- /dev/null +++ b/src/reference/ai_poc/translate_en_ch/etranslate.cc @@ -0,0 +1,121 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "etranslate.h" + + +ETranslate::ETranslate(const char *kmodel_file, const char *src_model_file, const int debug_mode) +:AIBase(kmodel_file, "ETranslate", debug_mode) +{ + const auto src_status = sp_src.Load(src_model_file); + if (!src_status.ok()) { + std::cerr << src_status.ToString() << std::endl; + } + + bos_id = sp_src.bos_id(); + eos_id = sp_src.eos_id(); + pad_id = sp_src.pad_id(); + + in_tensor_0 = get_input_tensor(0); + in_tensor_1 = get_input_tensor(1); +} + +ETranslate::~ETranslate() +{ +} + +void ETranslate::pre_process(string ori_sen) +{ + ScopedTiming st("Encoder preprocess", debug_mode_); + maxlen = input_shapes_[0][1]; + std::vector ids; + sp_src.Encode(ori_sen, &ids); + + source_seq = new int64_t[maxlen]; + source_seq[0] = bos_id; + for(int i = 1; i < ids.size()+1; i++) + { + source_seq[i] = ids[i-1]; + } + source_seq[ids.size()+1] = eos_id; + src_token_size = ids.size()+2; + + if (maxlen < ids.size()+2) { + std::cerr << " 输入的句子词数超出上限 " << std::endl; + } + + for(int i = 0; i < maxlen-ids.size()-2; i++) + { + source_seq[ids.size()+2 + i] = pad_id; + } + + src_mask = new uint8_t[maxlen*maxlen]; + for (int i = 0; i < maxlen; i++) + { + for (int j = 0; j < maxlen; j++) + { + if (i < ids.size()+2 and j < ids.size()+2) + { + src_mask[i*maxlen + j] = 0; + } + else + { + src_mask[i*maxlen + j] = 1; + } + } + } + + size_t in_tensor_0_size = maxlen; + size_t in_tensor_1_size = maxlen*maxlen; + auto buf_0 = in_tensor_0.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + auto buf_1 = in_tensor_1.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(buf_0.data()), source_seq, in_tensor_0_size*8); + memcpy(reinterpret_cast(buf_1.data()), src_mask, in_tensor_1_size); + hrt::sync(in_tensor_0, sync_op_t::sync_write_back, true).expect("sync write_back failed"); + hrt::sync(in_tensor_1, sync_op_t::sync_write_back, true).expect("sync write_back failed"); + + delete[] src_mask; + delete[] source_seq; +} + + +void ETranslate::inference() +{ + this->run(); + this->get_output(); +} + +void ETranslate::post_process(vector &result) +{ + ScopedTiming st("Encoder postprocess", debug_mode_); + EncoderStruct eresult; + eresult.encoder_kv = p_outputs_[0]; + eresult.src_token_size = src_token_size; + result.push_back(eresult); +} + +int ETranslate::get_maxlen() +{ + return maxlen; +} \ No newline at end of file diff --git a/src/reference/ai_poc/translate_en_ch/etranslate.h b/src/reference/ai_poc/translate_en_ch/etranslate.h new file mode 100644 index 000000000..db784f4d5 --- /dev/null +++ b/src/reference/ai_poc/translate_en_ch/etranslate.h @@ -0,0 +1,124 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _ETRANSLATE_H +#define _ETRANSLATE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "sentencepiece_processor.h" +#include "ai_base.h" + +using namespace nncase; +using namespace nncase::runtime; +using namespace nncase::runtime::detail; +using namespace std; + +/** + * @brief Encoder 输出 + */ +typedef struct EncoderStruct +{ + float *encoder_kv; // 经过编码器的编码结果 + int src_token_size; //被翻译句子token长度 +} EncoderStruct; + + +/** + * @brief 翻译 + * 主要封装了编码器对被翻译的句子,从预处理、运行到后处理给出结果的过程 + */ +class ETranslate:public AIBase +{ +public: + /** + * @brief ETranslate构造函数,加载kmodel,并初始化kmodel输入、输出 + * @param kmodel_file kmodel文件路径 + * @param src_model_file 分词器模型路径 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + ETranslate(const char *kmodel_file, const char *src_model_file, const int debug_mode); + + /** + * @brief ETranslate析构函数 + * @return None + */ + ~ETranslate(); + + /** + * @brief 被翻译句子预处理 + * @param ori_sen 被翻译句子 + * @return None + */ + void pre_process(string ori_sen); + + /** + * @brief kmodel推理 + * @return None + */ + void inference(); + + /** + * @brief kmodel推理结果后处理 + * @param result 编码器输出结果 + * @return None + */ + void post_process(vector &result); + + /** + * @brief 获取最大token长度 + * @return int 返回最大token长度 + */ + int get_maxlen(); + +private: + + runtime_tensor in_tensor_0; // 第1个输入tensor + runtime_tensor in_tensor_1; // 第2个输出tensor + + int maxlen; //模型最大输入token长度 + int src_token_size; //被翻译句子的token长度 + sentencepiece::SentencePieceProcessor sp_src; //被翻译语言的分词器 + uint8_t *src_mask; //被翻译句子的掩码 + int64_t *source_seq; //被翻译句子token列表 + int bos_id; //被翻译语言的起始符编号 + int eos_id; //被翻译语言的终止符编号 + int pad_id; //被翻译语言的token pad值 +}; +#endif diff --git a/src/reference/ai_poc/translate_en_ch/main.cc b/src/reference/ai_poc/translate_en_ch/main.cc new file mode 100644 index 000000000..6303a673e --- /dev/null +++ b/src/reference/ai_poc/translate_en_ch/main.cc @@ -0,0 +1,109 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include + +#include "etranslate.h" +#include "dtranslate.h" + + +void print_usage(const char *name) +{ + cout << "Usage: " << name << " " << endl + << "Options:" << endl + << " kmodel_encoder 编码器kmodel路径\n" + << " kmodel_decoder 解码器kmodel路径\n" + << " src_model_file 原语言分词器模型路径\n" + << " tag_model_file 翻译后语言分词器模型路径\n" + << " debug_mode 是否需要调试,0、1、2分别表示不调试、简单调试、详细调试\n" + << "\n" + << endl; +} + +void translate_proc(char *argv[]) +{ + ETranslate encoder(argv[1], argv[3], atoi(argv[5])); + sync(); + DTranslate decoder(argv[2], argv[4], atoi(argv[5])); + sync(); + + char src_str[400]; + + std::vector int_res; + vector eresult; + + while (true) + { + std::cout << "Please enter : " << "(Enter q End)" << std::endl; + gets(src_str); + + ScopedTiming st("total time", atoi(argv[5])); + if(string(src_str) == "q") + { + break; + } + + int_res.clear(); + eresult.clear(); + + encoder.pre_process(string(src_str)); + encoder.inference(); + encoder.post_process(eresult); + + int maxlen = encoder.get_maxlen(); + vector input_y; + bool tran_stop = false; + for(int i = 0; i < maxlen-1; i++) + { + decoder.pre_process(i, input_y, eresult[0].encoder_kv, eresult[0].src_token_size); + decoder.inference(); + decoder.post_process(i+1, input_y,int_res, &tran_stop); + if (tran_stop) + { + break; + } + } + + string translate_str = decoder.decode_post(int_res); + std::cout << "Result : " << translate_str << std::endl; + } + +} + + +int main(int argc, char *argv[]) +{ + std::cout << "case " << argv[0] << " built at " << __DATE__ << " " << __TIME__ << std::endl; + if (argc != 6) + { + print_usage(argv[0]); + return -1; + } + + translate_proc(argv); + return 0; +} diff --git a/src/reference/ai_poc/translate_en_ch/scoped_timing.hpp b/src/reference/ai_poc/translate_en_ch/scoped_timing.hpp new file mode 100644 index 000000000..874ff1b17 --- /dev/null +++ b/src/reference/ai_poc/translate_en_ch/scoped_timing.hpp @@ -0,0 +1,70 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include + +/** + * @brief 计时类 + * 统计在该类实例生命周期内的耗时 + */ +class ScopedTiming +{ +public: + /** + * @brief ScopedTiming构造函数,初始化计时对象名称并开始计时 + * @param info 计时对象名称 + * @param enable_profile 是否开始计时 + * @return None + */ + ScopedTiming(std::string info = "ScopedTiming", int enable_profile = 1) + : m_info(info), enable_profile(enable_profile) + { + if (enable_profile) + { + m_start = std::chrono::steady_clock::now(); + } + } + + /** + * @brief ScopedTiming析构,结束计时,并打印耗时 + * @return None + */ + ~ScopedTiming() + { + if (enable_profile) + { + m_stop = std::chrono::steady_clock::now(); + double elapsed_ms = std::chrono::duration(m_stop - m_start).count(); + std::cout << m_info << " took " << elapsed_ms << " ms" << std::endl; + } + } + +private: + int enable_profile; // 是否统计时间 + std::string m_info; // 计时对象名称 + std::chrono::steady_clock::time_point m_start; // 计时开始时间 + std::chrono::steady_clock::time_point m_stop; // 计时结束时间 +}; \ No newline at end of file diff --git a/src/reference/ai_poc/translate_en_ch/sentencepiece_processor.h b/src/reference/ai_poc/translate_en_ch/sentencepiece_processor.h new file mode 100644 index 000000000..14b1e8cd8 --- /dev/null +++ b/src/reference/ai_poc/translate_en_ch/sentencepiece_processor.h @@ -0,0 +1,727 @@ +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License.! + +#ifndef SENTENCEPIECE_PROCESSOR_H_ +#define SENTENCEPIECE_PROCESSOR_H_ + +#include +#include +#include +#include +#include +#include + +#ifndef SWIG +namespace absl { +using std::string_view; +} // namespace absl +#endif // SWIG + +namespace sentencepiece { +namespace util { + +enum class StatusCode : int { + kOk = 0, + kCancelled = 1, + kUnknown = 2, + kInvalidArgument = 3, + kDeadlineExceeded = 4, + kNotFound = 5, + kAlreadyExists = 6, + kPermissionDenied = 7, + kResourceExhausted = 8, + kFailedPrecondition = 9, + kAborted = 10, + kOutOfRange = 11, + kUnimplemented = 12, + kInternal = 13, + kUnavailable = 14, + kDataLoss = 15, + kUnauthenticated = 16, +}; + +class Status { + public: + Status(); + ~Status(); + Status(StatusCode code, absl::string_view error_message); + Status(const Status &s); + void operator=(const Status &s); + bool operator==(const Status &s) const; + bool operator!=(const Status &s) const; + inline bool ok() const { return rep_ == nullptr; } + + void set_error_message(const char *str); + const char *error_message() const; + const char *message() const { return error_message(); } + StatusCode code() const; + std::string ToString() const; + + void IgnoreError(); + + private: + struct Rep; + std::unique_ptr rep_; +}; +} // namespace util + +// SentencePieceProcessor: +// Simple and language independent tokenizer and de-tokenizer for +// Neural Network Machine Translation. +// +// SentencePieceProcessor provides Encode() and Decode() methods, +// which correspond to tokenization and de-tokenization respectively. +// +// - Encode: +// Given a raw source sentence, encode it into a sequence +// of pieces or vocabulary ids. +// +// - Decode: +// Given a sequence of pieces or vocabulary ids, decode it +// into a de-tokenized raw sentence. +// +// SentencePieceProcessor provides a lossless data conversion +// that allows the original raw sentence to be perfectly reconstructed +// from the encoded data, i.e., Decode(Encode(input)) == input. +// This characteristics is useful, as we can make the de-tokenization +// completely language independent. +// +// Usage: +// SentencePieceProcessor sp; +// sp.Load("//path/to/model"); +// +// vector sps; +// sp.Encode("hello world.", &sps).IgnoreError(); +// +// vector ids; +// sp.Encode("hello world.", &ids).IgnoreError(); +// +// string detok; +// sp.Decode(sps, &detok); +// CHECK_EQ("hello world.", detok).IgnoreError(); +// +// sp.Decode(ids, &detok); +// CHECK_EQ("hello world.", detok).IgnoreError(); +// +// We can also use SentencePieceText which manages the byte-offsets +// between user input (output) and internal sentence pieces. +// +// SentencePieceText spt; +// sp.Encode("hello world.", &spt); +// // Emits the byte range of each piece. +// for (const auto &piece : spt.pieces()) { +// LOG(INFO) << piece.begin() << " " << piece.end(); +// } +// +// sp.Decode({0, 1, 2, 3..}, &spt); +// for (const auto &piece : spt.pieces()) { +// LOG(INFO) << piece.begin() << " " << piece.end(); +// } +// + +class NBestSentencePieceText; +class ModelInterface; +class SentencePieceText; +class ModelProto; + +namespace normalizer { +class Normalizer; +} // namespace normalizer + +#ifndef SWIGGO +namespace util { +// Redefine std::string for serialized_proto interface as Python's string is +// a Unicode string. We can enforce the return value to be raw byte sequence +// with SWIG's typemap. +using bytes = std::string; +} // namespace util +#endif // SWIGGO + +class NBestSentencePieceText; +class ModelInterface; +class SentencePieceText; +class SentencePieceText_SentencePiece; + +// Wrapper class of SentencePieceText +// This wrapper only allows an immutable access to the proto and +// hides the actual implementation of protobuf. +// See sentencepiece.proto for the details of this class. +class ImmutableSentencePieceText_ImmutableSentencePiece { + public: + ImmutableSentencePieceText_ImmutableSentencePiece(); + ~ImmutableSentencePieceText_ImmutableSentencePiece() = default; + + const std::string &piece() const; + const std::string &surface() const; + uint32_t id() const; + uint32_t begin() const; + uint32_t end() const; + + friend class ImmutableSentencePieceText; + + private: + explicit ImmutableSentencePieceText_ImmutableSentencePiece( + const SentencePieceText_SentencePiece &sp); + const SentencePieceText_SentencePiece *sp_ = nullptr; +}; + +class ImmutableSentencePieceText { + public: + ImmutableSentencePieceText(); + virtual ~ImmutableSentencePieceText(); + + std::vector pieces() const; + + size_t pieces_size() const; + ImmutableSentencePieceText_ImmutableSentencePiece pieces(int index) const; + + const std::string &text() const; + float score() const; + + util::bytes SerializeAsString() const; + + // Returns the actual mutable proto. + // Do not use this outside of SentencePieceProcessor, as + // it returns the raw pointer managed by the shared_ptr. + SentencePieceText *mutable_proto(); + + // Converts the utf8 byte spans into Unicode char span. + void ConvertToUnicodeSpans(); + + friend class ImmutableNBestSentencePieceText; + + private: + explicit ImmutableSentencePieceText(const SentencePieceText &spt); + const SentencePieceText *spt_ = nullptr; + std::shared_ptr rep_; +}; + +// Wrapper class of SentencePieceText +// This wrapper only allows an immutable access to the proto and +// hides the actual implementation of protobuf. +// See sentencepiece.proto for the details of this class. +class ImmutableNBestSentencePieceText { + public: + ImmutableNBestSentencePieceText(); + virtual ~ImmutableNBestSentencePieceText(); + + std::vector nbests() const; + + size_t nbests_size() const; + ImmutableSentencePieceText nbests(int index) const; + + util::bytes SerializeAsString() const; + + // Returns the actual mutable proto. + // Do not use this outside of SentencePieceProcessor, as + // it returns the raw pointer managed by the shared_ptr. + NBestSentencePieceText *mutable_proto(); + + void ConvertToUnicodeSpans(); + + private: + std::shared_ptr rep_; +}; + +class SentencePieceProcessor { + public: + SentencePieceProcessor(); + virtual ~SentencePieceProcessor(); + + // Loads model from `filename`. + // Returns false if `filename` cannot be loaded. + virtual util::Status Load(absl::string_view filename); + + // Loads model from `filename`. + // Crash if `filename` cannot be loaded. + virtual void LoadOrDie(absl::string_view filename); + + // Loads model from `model_proto`. + // `model_proto` is copied. + virtual util::Status Load(const ModelProto &model_proto); + + // Loads model from `model_proto`. + // `model_proto` is moved. + virtual util::Status Load(std::unique_ptr model_proto); + + // Loads model from `serialized`, which is a string-serialized model proto. + // Useful to load the model from a platform independent blob object. + virtual util::Status LoadFromSerializedProto(absl::string_view serialized); + + // Returns the status. Encode/Decode methods are valid when status is OK. + virtual util::Status status() const; + + // Sets encode extra_option sequence. + virtual util::Status SetEncodeExtraOptions(absl::string_view extra_option); + + // Sets decode extra_option sequence. + virtual util::Status SetDecodeExtraOptions(absl::string_view extra_option); + + ////////////////////////////////////////////////////////////// + // Vocabulary restriction. + // Background: + // https://github.com/rsennrich/subword-nmt#best-practice-advice-for-byte-pair-encoding-in-nmt + + // Restricts the vocabulary set. + // The input sentences are encoded into the tokens in `valid_vocab`. + virtual util::Status SetVocabulary( + const std::vector &valid_vocab); + + // Reverts the vocabulary restriction. + virtual util::Status ResetVocabulary(); + + // Loads the valid vocabulary set from `filename` in TSV format. + // Format: . + // Any token with frequency < threshold will be treated as OOV. + virtual util::Status LoadVocabulary(absl::string_view filename, + int threshold); + + ////////////////////////////////////////////////////////////// + // Simple Encode and Decode API. + // + // Given a UTF8 input, encodes it into a sequence of sentence pieces. + virtual util::Status Encode(absl::string_view input, + std::vector *pieces) const; + + // Given a UTF8 input, encodes it into a sequence of ids. + virtual util::Status Encode(absl::string_view input, + std::vector *ids) const; + + // Given a sequence of pieces, decodes it into a detokenized output. + virtual util::Status Decode(const std::vector &pieces, + std::string *detokenized) const; + + // Given a sequence of pieces, decodes it into a detokenized output. + virtual util::Status Decode(const std::vector &pieces, + std::string *detokenized) const; + + // Given a sequence of ids, decodes it into a detokenized output. + virtual util::Status Decode(const std::vector &ids, + std::string *detokenized) const; + + ////////////////////////////////////////////////////////////// + // NBest API. + // + // Same as Encode, but returns nbest results. + virtual util::Status NBestEncode( + absl::string_view input, int nbest_size, + std::vector> *pieces) const; + + // Same as Encode, but returns nbest results. + virtual util::Status NBestEncode(absl::string_view input, int nbest_size, + std::vector> *ids) const; + + ////////////////////////////////////////////////////////////// + // Sampling API. + // + // Unigram and BPE support sampling mode. + // - Unigram (--model_type=unigram): + // `nbest_size`: When `nbest_size` is positive value, approximately samples + // one segmentation from nbest candidates. When `nbest_size` is negative + // value, samples one segmentation from the hypotheses (Lattice) according to + // the generation probabilities using forward-filtering and backward-sampling + // algorithm. + // `alpha`: Smoothing parameter (inverse temperature). The best segmentation + // (Viterbi segmentation) is more likely sampled when setting larger alpha. + // When alpha is 0.0, one segmentation is uniformly sampled from the nbest or + // lattice. `nbest_size` and `alpha` correspond to parameters `l` and `alpha` + // in https://arxiv.org/abs/1804.10959 (nbest_size < 0 means l = infinity) + // + // - BPE (--model_type=bpe): + // `alpha`: The dropout probability `p` of bpe merge operations in + // https://arxiv.org/abs/1910.13267 Nbest-based sampling is not supported so + // nbest_size parameter is ignored in BPE. + virtual util::Status SampleEncode(absl::string_view input, int nbest_size, + float alpha, + std::vector *pieces) const; + + // Same as above, but returns a sequence of ids. + virtual util::Status SampleEncode(absl::string_view input, int nbest_size, + float alpha, std::vector *ids) const; + + ////////////////////////////////////////////////////////////// + // SampleEncodeAndScore API. + // + // Sample `samples` many tokenisations from the segmentation lattice. + // These methods are only available in model_type=unigram. + // + // `alpha`: smoothing parameter (inverse temperature). The same as `alpha` in + // `Sample` method. + // 'wor`: If `wor` is true, the samples are taken without replacement, and the + // scores are the inclusion probabilities of the elements in the sample; + // otherwise the samples are taken with replacement and the scores are the + // log-probs of sample elements + // `include_best`: If `include_best` is true, the best tokenisation is always + // included in the sample, and the remaining elements are sampled excluding + // the best. + virtual util::Status SampleEncodeAndScore( + absl::string_view input, int num_samples, float alpha, bool wor, + bool include_best, + std::vector, float>> *pieces) const; + + // Same as above, but returns a sequence of ids. + virtual util::Status SampleEncodeAndScore( + absl::string_view input, int num_samples, float alpha, bool wor, + bool include_best, + std::vector, float>> *ids) const; + + ////////////////////////////////////////////////////////////// + // Entropy API. + // + // This only available in model_type=unigram. + // Calculate entropy of possible tokenisations + virtual util::Status CalculateEntropy(absl::string_view input, float alpha, + float *entropy) const; + + ////////////////////////////////////////////////////////////// + // Advanced API returning SentencePieceText, which manages + // utf8-byte alignments between user-input/detokenized text + // and internal sentencepiece sequence. + // + // Given a UTF8 input, encodes it into SentencePieceText. + // + // When using these APIs, sentencepiece.pb.h header files must be included. + // We can also use ImutableSentencePieceText as follows. + // + // ImmutableSentencePieceText spt; + // Encode("hello", spt.mutable_proto()).IgnoreError(); + // std::cout << spt.pieces_size() << std::endl; + virtual util::Status Encode(absl::string_view input, + SentencePieceText *spt) const; + + virtual util::Status NBestEncode(absl::string_view input, int nbest_size, + NBestSentencePieceText *nbest_spt) const; + + virtual util::Status SampleEncode(absl::string_view input, int nbest_size, + float alpha, SentencePieceText *spt) const; + + virtual util::Status SampleEncodeAndScore( + absl::string_view input, int num_samples, float alpha, bool wor, + bool include_best, NBestSentencePieceText *samples_spt) const; + + // DEPRECATED: Remove this API and use std::vector + virtual util::Status Decode(const std::vector &pieces, + SentencePieceText *spt) const; + + virtual util::Status Decode(const std::vector &pieces, + SentencePieceText *spt) const; + + virtual util::Status Decode(const std::vector &ids, + SentencePieceText *spt) const; +#ifdef SWIG +#define SPP_SWIG_CHECK_AND_THROW \ + if (!status.ok()) throw status; +#else +#define SPP_SWIG_CHECK_AND_THROW \ + if (!status.ok()) { \ + } +#endif // SWIG + +#define DEFINE_SPP_DIRECT_FUNC_IMPL(FuncName, OutType, ...) \ + OutType output; \ + const auto status = FuncName(__VA_ARGS__, &output); \ + SPP_SWIG_CHECK_AND_THROW; \ + return output; + +#define DEFINE_SPP_SERIALIZED_PROTO_IMPL(FuncName, OutType, ...) \ + OutType output; \ + const auto status = FuncName(__VA_ARGS__, output.mutable_proto()); \ + SPP_SWIG_CHECK_AND_THROW; \ + return output.SerializeAsString(); + +#define DEFINE_SPP_IMMUTABLE_PROTO_IMPL(FuncName, OutType, ...) \ + OutType output; \ + const auto status = FuncName(__VA_ARGS__, output.mutable_proto()); \ + SPP_SWIG_CHECK_AND_THROW; \ + return output; + + ////////////////////////////////////////////////////////////// + // Handy methods that return the result directly. + // These functions ignore internal errors. + virtual std::vector EncodeAsPieces( + absl::string_view input) const { + DEFINE_SPP_DIRECT_FUNC_IMPL(Encode, std::vector, input); + } + + virtual std::vector EncodeAsIds(absl::string_view input) const { + DEFINE_SPP_DIRECT_FUNC_IMPL(Encode, std::vector, input); + } + + virtual std::vector> NBestEncodeAsPieces( + absl::string_view input, int nbest_size) const { + DEFINE_SPP_DIRECT_FUNC_IMPL( + NBestEncode, std::vector>, input, nbest_size); + } + + virtual std::vector> NBestEncodeAsIds( + absl::string_view input, int nbest_size) const { + DEFINE_SPP_DIRECT_FUNC_IMPL(NBestEncode, std::vector>, + input, nbest_size); + } + + virtual std::vector SampleEncodeAsPieces(absl::string_view input, + int nbest_size, + float alpha) const { + DEFINE_SPP_DIRECT_FUNC_IMPL(SampleEncode, std::vector, input, + nbest_size, alpha); + } + + virtual std::vector SampleEncodeAsIds(absl::string_view input, + int nbest_size, + float alpha) const { + DEFINE_SPP_DIRECT_FUNC_IMPL(SampleEncode, std::vector, input, + nbest_size, alpha); + } + + virtual std::vector, float>> + SampleEncodeAndScoreAsPieces(absl::string_view input, int num_samples, + float alpha, bool wor, bool include_best) const { + using _T = std::vector, float>>; + DEFINE_SPP_DIRECT_FUNC_IMPL(SampleEncodeAndScore, _T, input, num_samples, + alpha, wor, include_best); + } + + virtual std::vector, float>> + SampleEncodeAndScoreAsIds(absl::string_view input, int num_samples, + float alpha, bool wor, bool include_best) const { + using _T = std::vector, float>>; + DEFINE_SPP_DIRECT_FUNC_IMPL(SampleEncodeAndScore, _T, input, num_samples, + alpha, wor, include_best); + } + + // DEPRECATED: Remove this API and use std::vector + virtual std::string DecodePieces( + const std::vector &pieces) const { + DEFINE_SPP_DIRECT_FUNC_IMPL(Decode, std::string, pieces); + } + + virtual std::string DecodePieces( + const std::vector &pieces) const { + DEFINE_SPP_DIRECT_FUNC_IMPL(Decode, std::string, pieces); + } + + virtual std::string DecodeIds(const std::vector &ids) const { + DEFINE_SPP_DIRECT_FUNC_IMPL(Decode, std::string, ids); + } + + virtual float CalculateEntropy(absl::string_view text, float alpha) const { + DEFINE_SPP_DIRECT_FUNC_IMPL(CalculateEntropy, float, text, alpha); + } + + ////////////////////////////////////////////////////////////// + // SerializedProto API. (DEPRECATED). Use ImmutableProto API. + // They are used in Python interface. Returns serialized proto. + // In python module, we can get access to the full Proto after + // deserialzing the returned byte sequence. + virtual util::bytes EncodeAsSerializedProto(absl::string_view input) const { + DEFINE_SPP_SERIALIZED_PROTO_IMPL(Encode, ImmutableSentencePieceText, input); + } + + virtual util::bytes SampleEncodeAsSerializedProto(absl::string_view input, + int nbest_size, + float alpha) const { + DEFINE_SPP_SERIALIZED_PROTO_IMPL(SampleEncode, ImmutableSentencePieceText, + input, nbest_size, alpha); + } + + virtual util::bytes NBestEncodeAsSerializedProto(absl::string_view input, + int nbest_size) const { + DEFINE_SPP_SERIALIZED_PROTO_IMPL( + NBestEncode, ImmutableNBestSentencePieceText, input, nbest_size); + } + + virtual util::bytes SampleEncodeAndScoreAsSerializedProto( + absl::string_view input, int num_samples, float alpha, bool wor, + bool include_best) const { + DEFINE_SPP_SERIALIZED_PROTO_IMPL(SampleEncodeAndScore, + ImmutableNBestSentencePieceText, input, + num_samples, alpha, wor, include_best); + } + + // TODO(taku): Remove this API and use std::vector + virtual util::bytes DecodePiecesAsSerializedProto( + const std::vector &pieces) const { + DEFINE_SPP_SERIALIZED_PROTO_IMPL(Decode, ImmutableSentencePieceText, + pieces); + } + + virtual util::bytes DecodePiecesAsSerializedProto( + const std::vector &pieces) const { + DEFINE_SPP_SERIALIZED_PROTO_IMPL(Decode, ImmutableSentencePieceText, + pieces); + } + + virtual util::bytes DecodeIdsAsSerializedProto( + const std::vector &ids) const { + DEFINE_SPP_SERIALIZED_PROTO_IMPL(Decode, ImmutableSentencePieceText, ids); + } + + ////////////////////////////////////////////////////////////// + // ImmutableProto API. + virtual ImmutableSentencePieceText EncodeAsImmutableProto( + absl::string_view input) const { + DEFINE_SPP_IMMUTABLE_PROTO_IMPL(Encode, ImmutableSentencePieceText, input); + } + + virtual ImmutableSentencePieceText SampleEncodeAsImmutableProto( + absl::string_view input, int nbest_size, float alpha) const { + DEFINE_SPP_IMMUTABLE_PROTO_IMPL(SampleEncode, ImmutableSentencePieceText, + input, nbest_size, alpha); + } + + virtual ImmutableNBestSentencePieceText NBestEncodeAsImmutableProto( + absl::string_view input, int nbest_size) const { + DEFINE_SPP_IMMUTABLE_PROTO_IMPL( + NBestEncode, ImmutableNBestSentencePieceText, input, nbest_size); + } + + virtual ImmutableNBestSentencePieceText SampleEncodeAndScoreAsImmutableProto( + absl::string_view input, int num_samples, float alpha, bool wor, + bool include_best) const { + DEFINE_SPP_IMMUTABLE_PROTO_IMPL(SampleEncodeAndScore, + ImmutableNBestSentencePieceText, input, + num_samples, alpha, wor, include_best); + } + + // TODO(taku): Remove this API and use std::vector + virtual ImmutableSentencePieceText DecodePiecesAsImmutableProto( + const std::vector &pieces) const { + DEFINE_SPP_IMMUTABLE_PROTO_IMPL(Decode, ImmutableSentencePieceText, pieces); + } + + virtual ImmutableSentencePieceText DecodePiecesAsImmutableProto( + const std::vector &pieces) const { + DEFINE_SPP_IMMUTABLE_PROTO_IMPL(Decode, ImmutableSentencePieceText, pieces); + } + + virtual ImmutableSentencePieceText DecodeIdsAsImmutableProto( + const std::vector &ids) const { + DEFINE_SPP_IMMUTABLE_PROTO_IMPL(Decode, ImmutableSentencePieceText, ids); + } + +#undef DEFINE_SPP_DIRECT_FUNC_IMPL +#undef DEFINE_SPP_SERIALIZED_PROTO_IMPL +#undef DEFINE_SPP_IMMUTABLE_PROTO_IMPL + + ////////////////////////////////////////////////////////////// + // Vocabulary management methods. + // + // Returns the size of sentence pieces, which is the same as + // the size of vocabulary for NMT. + virtual int GetPieceSize() const; + + // Returns the vocab id of `piece`. + // Returns UNK(0) if `piece` is unknown. + virtual int PieceToId(absl::string_view piece) const; + + // Returns the string representation of vocab with `id`. + virtual const std::string &IdToPiece(int id) const; + + // Returns the score of `id`. + // Usually score is an emission log probability of unigram language + // model. + virtual float GetScore(int id) const; + + // Returns true if `id` is unknown symbol. + virtual bool IsUnknown(int id) const; + + // Returns true if `id` is control symbol. + virtual bool IsControl(int id) const; + + // Returns true if `id` is unused symbol. + virtual bool IsUnused(int id) const; + + // Returns true if `id` is byte symbol. + virtual bool IsByte(int id) const; + + // Returns the reserved id. + // Returns -1 if not defined. + + // Returns unknown () id. + virtual int unk_id() const; + + // Returns BOS () id. + virtual int bos_id() const; + + // Returns EOS () id. + virtual int eos_id() const; + + // Returns PAD () id. + virtual int pad_id() const; + + ////////////////////////////////////////////////////////////// + // Model management. + // + // Allows injection of a mock model instance. `model` is moved. + void SetModel(std::unique_ptr &&model); + + // Allows injection of a normalizer instance. `normalizer` is moved. + void SetNormalizer(std::unique_ptr &&normalizer); + + // Returns immutable model proto. Useful to obtain extended + // or experimental parameters encoded in model_proto. + const ModelProto &model_proto() const; + + // returns immutable model proto as std::string. + // Useful to save the state of this instance via Python's pickle object. + util::bytes serialized_model_proto() const; + + private: + enum ExtraOption { REVERSE, BOS, EOS, UNK_PIECE }; + + util::Status ParseExtraOptions(absl::string_view extra_option, + std::vector *extra_options) const; + + util::Status ApplyExtraOptions(const std::vector &extra_options, + SentencePieceText *spt) const; + + util::Status PopulateSentencePieceText( + absl::string_view input, absl::string_view normalized, + const std::vector &norm_to_orig, + const std::vector> &result, + SentencePieceText *spt) const; + + std::unique_ptr model_; + std::unique_ptr normalizer_; + std::unique_ptr denormalizer_; + + // Underlying model protocol buffer. The same lifetime as model_. + std::unique_ptr model_proto_; + + std::vector encode_extra_options_; + std::vector decode_extra_options_; +}; + +// Set seed value of random generator. +// Do not set static_cast(-1), +// as this seed is reserved for initializing from +// std::random_device. +void SetRandomGeneratorSeed(unsigned int seed); + +// IO related functions to absorb model formats. +namespace io { +// Loads `model_proto` from `filename`. +// We can instantiate SentencePieceProcessor as follows: +// +// auto model_proto = absl::make_unique(); +// io::LoadModelProto("//path/spm.model", model_proto.get()); +// SentencePieceProcessor sp; +// CHECK_OK(sp.Load(std::move(model_proto))); +util::Status LoadModelProto(absl::string_view, ModelProto *model_proto); + +// Saves `model_proto` as `filename`. +util::Status SaveModelProto(absl::string_view, const ModelProto &model_proto); +} // namespace io +} // namespace sentencepiece +#endif // SENTENCEPIECE_PROCESSOR_H_ diff --git a/src/reference/ai_poc/version b/src/reference/ai_poc/version index 3a6a8d03e..89a6e74b5 100644 --- a/src/reference/ai_poc/version +++ b/src/reference/ai_poc/version @@ -1 +1 @@ -v1.1 +v1.2 diff --git a/src/reference/ai_poc/virtual_keyboard/CMakeLists.txt b/src/reference/ai_poc/virtual_keyboard/CMakeLists.txt new file mode 100644 index 000000000..fd6201c77 --- /dev/null +++ b/src/reference/ai_poc/virtual_keyboard/CMakeLists.txt @@ -0,0 +1,18 @@ +set(src main.cc utils.cc ai_base.cc hand_detection.cc hand_keypoint.cc key.cc) +set(bin virtual_keyboard.elf) + +include_directories(${PROJECT_SOURCE_DIR}) +include_directories(${nncase_sdk_root}/riscv64/rvvlib/include) +include_directories(${k230_sdk}/src/big/mpp/userapps/api/) +include_directories(${k230_sdk}/src/big/mpp/include) +include_directories(${k230_sdk}/src/big/mpp/include/comm) +include_directories(${k230_sdk}/src/big/mpp/userapps/sample/sample_vo) +link_directories(${nncase_sdk_root}/riscv64/rvvlib/) + +add_executable(${bin} ${src}) +target_link_libraries(${bin} -Wl,--start-group rvv Nncase.Runtime.Native nncase.rt_modules.k230 functional_k230 sys vicap vb cam_device cam_engine + hal oslayer ebase fpga isp_drv binder auto_ctrol common cam_caldb isi 3a buffer_management cameric_drv video_in virtual_hal start_engine cmd_buffer + switch cameric_reg_drv t_database_c t_mxml_c t_json_c t_common_c vo connector sensor atomic dma -Wl,--end-group) + +target_link_libraries(${bin} opencv_imgcodecs opencv_imgproc opencv_core zlib libjpeg-turbo libopenjp2 libpng libtiff libwebp csi_cv) +install(TARGETS ${bin} DESTINATION bin) diff --git a/src/reference/ai_poc/virtual_keyboard/README.md b/src/reference/ai_poc/virtual_keyboard/README.md new file mode 100644 index 000000000..062b4d8b6 --- /dev/null +++ b/src/reference/ai_poc/virtual_keyboard/README.md @@ -0,0 +1,31 @@ +# 1.简介 + +手掌检测采用了yolov5网络结构,backbone选取了1.0-mobilenetV2,手掌关键点检测采用了resnet50网络结构。使用该应用,可以使用屏幕上的虚拟键盘输出字符。 + +# 2.应用使用说明 + +## 2.1 使用帮助 + +``` +"Usage: " << virtual_keyboard.elf << " " + +各参数释义如下: +kmodel_det 手掌检测 kmodel路径 +obj_thresh 手掌检测阈值 +nms_thresh 手掌检测非极大值抑制阈值 +kmodel_kp 手掌关键点检测 kmodel路径 +debug_mode 是否需要调试,0、1、2分别表示不调试、简单调试、详细调试 + + #视频流推理:(virtual_keyboard.sh) +./virtual_keyboard.elf hand_det.kmodel 0.25 0.4 handkp_det.kmodel 0 +``` + +## 2.2 效果展示 +![demo示例](https://kendryte-download.canaan-creative.com/k230/downloads/doc_images/ai_demo/virtual_keyboard/virtual_keyboard.gif){:height="50%" width="50%"} + +其中 ```Space```空格键,```clr```清空键,```<--``` +退格键。 + +**注意:** 手部不宜离屏幕太近,确保手掌在摄像头可见区域内。大拇指指尖选择字符,食指指尖触碰大拇指指尖输出当前选择的字符。推荐使用方式请参考上图。本应用仅提供一个示例实现,如需更高精度或更优体验,可通过调整阈值或自行替换相应的模型文件。 + + diff --git a/src/reference/ai_poc/virtual_keyboard/ai_base.cc b/src/reference/ai_poc/virtual_keyboard/ai_base.cc new file mode 100644 index 000000000..44674d4a1 --- /dev/null +++ b/src/reference/ai_poc/virtual_keyboard/ai_base.cc @@ -0,0 +1,187 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "ai_base.h" + +#include +#include + +#include "utils.h" + +using std::cout; +using std::endl; +using namespace nncase; +using namespace nncase::runtime::detail; + +AIBase::AIBase(const char *kmodel_file,const string model_name, const int debug_mode) : debug_mode_(debug_mode),model_name_(model_name) +{ + if (debug_mode > 1) + cout << "kmodel_file:" << kmodel_file << endl; + std::ifstream ifs(kmodel_file, std::ios::binary); + kmodel_interp_.load_model(ifs).expect("Invalid kmodel"); + set_input_init(); + set_output_init(); +} + +AIBase::~AIBase() +{ +} + +void AIBase::set_input_init() +{ + ScopedTiming st(model_name_ + " set_input init", debug_mode_); + int input_total_size = 0; + each_input_size_by_byte_.push_back(0); // 先补0,为之后做准备 + for (int i = 0; i < kmodel_interp_.inputs_size(); ++i) + { + auto desc = kmodel_interp_.input_desc(i); + auto shape = kmodel_interp_.input_shape(i); + auto tensor = host_runtime_tensor::create(desc.datatype, shape, hrt::pool_shared).expect("cannot create input tensor"); + kmodel_interp_.input_tensor(i, tensor).expect("cannot set input tensor"); + vector in_shape = {shape[0], shape[1], shape[2], shape[3]}; + input_shapes_.push_back(in_shape); + int dsize = shape[0] * shape[1] * shape[2] * shape[3]; + if (debug_mode_ > 1) + cout << "input shape:" << shape[0] << " " << shape[1] << " " << shape[2] << " " << shape[3] << endl; + // DEFINE_TYPECODE(uint8, u8, 0x06) + // DEFINE_TYPECODE(float32, f32, 0x0B) + if (desc.datatype == 0x06) + { + input_total_size += dsize; + each_input_size_by_byte_.push_back(input_total_size); + } + else if (desc.datatype == 0x0B) + { + input_total_size += (dsize * 4); + each_input_size_by_byte_.push_back(input_total_size); + } + else + assert(("kmodel input data type supports only uint8, float32", 0)); + } + each_input_size_by_byte_.push_back(input_total_size); // 最后一个保存总大小 +} + +void AIBase::set_input(const unsigned char *buf, size_t size) +{ + if (*each_input_size_by_byte_.rbegin() != size) + cout << "set_input:the actual input size{" + std::to_string(size) + "} is different from the model's required input size{" + std::to_string(*each_input_size_by_byte_.rbegin()) + "}" << endl; + assert((*each_input_size_by_byte_.rbegin() == size)); + + ScopedTiming st(model_name_ + " set_input", debug_mode_); + for (size_t i = 0; i < kmodel_interp_.inputs_size(); ++i) + { + auto desc = kmodel_interp_.input_desc(i); + auto shape = kmodel_interp_.input_shape(i); + auto tensor = host_runtime_tensor::create(desc.datatype, shape, hrt::pool_shared).expect("cannot create input tensor"); + auto mapped_buf = std::move(hrt::map(tensor, map_access_::map_write).unwrap()); // mapped_buf实际是有缓存数据的 + memcpy(reinterpret_cast(mapped_buf.buffer().data()), buf, each_input_size_by_byte_[i + 1] - each_input_size_by_byte_[i]); + auto ret = mapped_buf.unmap(); + ret = hrt::sync(tensor, sync_op_t::sync_write_back, true); + if (!ret.is_ok()) + { + std::cerr << "hrt::sync failed" << std::endl; + std::abort(); + } + kmodel_interp_.input_tensor(i, tensor).expect("cannot set input tensor"); + } +} + +runtime_tensor AIBase::get_input_tensor(size_t idx) +{ + return kmodel_interp_.input_tensor(idx).expect("cannot get input tensor"); +} + +void AIBase::set_input_tensor(size_t idx, runtime_tensor &tensor) +{ + ScopedTiming st(model_name_ + " set_input_tensor", debug_mode_); + kmodel_interp_.input_tensor(idx, tensor).expect("cannot set input tensor"); +} + +void AIBase::set_output_init() +{ + ScopedTiming st(model_name_ + " set_output_init", debug_mode_); + each_output_size_by_byte_.clear(); + int output_total_size = 0; + each_output_size_by_byte_.push_back(0); + for (size_t i = 0; i < kmodel_interp_.outputs_size(); i++) + { + auto desc = kmodel_interp_.output_desc(i); + auto shape = kmodel_interp_.output_shape(i); + vector out_shape; + int dsize = 1; + for (int j = 0; j < shape.size(); ++j) + { + out_shape.push_back(shape[j]); + dsize *= shape[j]; + if (debug_mode_ > 1) + cout << shape[j] << ","; + } + if (debug_mode_ > 1) + cout << endl; + output_shapes_.push_back(out_shape); + // DEFINE_TYPECODE(float32, f32, 0x0B) + if (desc.datatype == 0x0B) + { + output_total_size += (dsize * 4); + each_output_size_by_byte_.push_back(output_total_size); + } + else + assert(("kmodel output data type supports only float32", 0)); + auto tensor = host_runtime_tensor::create(desc.datatype, shape, hrt::pool_shared).expect("cannot create output tensor"); + kmodel_interp_.output_tensor(i, tensor).expect("cannot set output tensor"); + } +} + +void AIBase::set_output() +{ + ScopedTiming st(model_name_ + " set_output", debug_mode_); + for (size_t i = 0; i < kmodel_interp_.outputs_size(); i++) + { + auto desc = kmodel_interp_.output_desc(i); + auto shape = kmodel_interp_.output_shape(i); + auto tensor = host_runtime_tensor::create(desc.datatype, shape, hrt::pool_shared).expect("cannot create output tensor"); + kmodel_interp_.output_tensor(i, tensor).expect("cannot set output tensor"); + } +} + +void AIBase::run() +{ + ScopedTiming st(model_name_ + " run", debug_mode_); + kmodel_interp_.run().expect("error occurred in running model"); +} + +void AIBase::get_output() +{ + ScopedTiming st(model_name_ + " get_output", debug_mode_); + p_outputs_.clear(); + for (int i = 0; i < kmodel_interp_.outputs_size(); i++) + { + auto out = kmodel_interp_.output_tensor(i).expect("cannot get output tensor"); + // auto mapped_buf = std::move(hrt::map(out, map_access_::map_read).unwrap()); + // float *p_out = reinterpret_cast(mapped_buf.buffer().data()); + auto buf = out.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_read).unwrap().buffer(); + float *p_out = reinterpret_cast(buf.data()); + p_outputs_.push_back(p_out); + } +} diff --git a/src/reference/ai_poc/virtual_keyboard/ai_base.h b/src/reference/ai_poc/virtual_keyboard/ai_base.h new file mode 100644 index 000000000..9fd4470cc --- /dev/null +++ b/src/reference/ai_poc/virtual_keyboard/ai_base.h @@ -0,0 +1,120 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +// ai_base.h +#ifndef AI_BASE_H +#define AI_BASE_H + +#include +#include +#include + +#include +#include "scoped_timing.hpp" + +using std::string; +using std::vector; +using namespace nncase::runtime; + +/** + * @brief AI基类,封装nncase相关操作 + * 主要封装了nncase的加载、设置输入、运行、获取输出操作,后续开发demo只需要关注模型的前处理、后处理即可 + */ +class AIBase +{ +public: + /** + * @brief AI基类构造函数,加载kmodel,并初始化kmodel输入、输出 + * @param kmodel_file kmodel文件路径 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + AIBase(const char *kmodel_file,const string model_name, const int debug_mode = 1); + + /** + * @brief AI基类析构函数 + * @return None + */ + ~AIBase(); + + /** + * @brief 设置kmodel输入 + * @param buf 输入数据指针 + * @param size 输入数据大小 + * @return None + */ + void set_input(const unsigned char *buf, size_t size); + + /** + * @brief 根据索引获取kmodel输入tensor + * @param idx 输入数据指针 + * @return None + */ + runtime_tensor get_input_tensor(size_t idx); + + void set_input_tensor(size_t idx, runtime_tensor &tensor); + + /** + * @brief 初始化kmodel输出 + * @return None + */ + void set_output(); + + /** + * @brief 推理kmodel + * @return None + */ + void run(); + + /** + * @brief 获取kmodel输出,结果保存在对应的类属性中 + * @return None + */ + void get_output(); + +protected: + string model_name_; // 模型名字 + int debug_mode_; // 调试模型,0(不打印),1(打印时间),2(打印所有) + vector p_outputs_; // kmodel输出对应的指针列表 + vector> input_shapes_; //{{N,C,H,W},{N,C,H,W}...} + vector> output_shapes_; //{{N,C,H,W},{N,C,H,W}...}} 或 {{N,C},{N,C}...}}等 + vector each_input_size_by_byte_; //{0,layer1_length,layer1_length+layer2_length,...} + vector each_output_size_by_byte_; //{0,layer1_length,layer1_length+layer2_length,...} +private: + /** + * @brief 首次初始化kmodel输入,并获取输入shape + * @return None + */ + void set_input_init(); + + /** + * @brief 首次初始化kmodel输出,并获取输出shape + * @return None + */ + void set_output_init(); + + interpreter kmodel_interp_; // kmodel解释器,从kmodel文件构建,负责模型的加载、输入输出设置和推理 + vector kmodel_vec_; // 通过读取kmodel文件得到整个kmodel数据,用于传给kmodel解释器加载kmodel +}; +#endif \ No newline at end of file diff --git a/src/reference/ai_poc/virtual_keyboard/hand_detection.cc b/src/reference/ai_poc/virtual_keyboard/hand_detection.cc new file mode 100644 index 000000000..2fe01f28f --- /dev/null +++ b/src/reference/ai_poc/virtual_keyboard/hand_detection.cc @@ -0,0 +1,190 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "hand_detection.h" +#include + +HandDetection::HandDetection(const char *kmodel_file, float obj_thresh, float nms_thresh, FrameSize frame_size,const int debug_mode) +:obj_thresh_(obj_thresh), nms_thresh_(nms_thresh),frame_size_(frame_size),AIBase(kmodel_file, "HandDetection", debug_mode) +{ + model_name_ = "HandDetection"; + classes_num_ = 1; + int net_len = input_shapes_[0][2]; + ai2d_out_tensor_ = get_input_tensor(0); +} + +HandDetection::HandDetection(const char *kmodel_file, float obj_thresh, float nms_thresh, FrameSize frame_size, FrameCHWSize isp_shape, uintptr_t vaddr, uintptr_t paddr, const int debug_mode) +: obj_thresh_(obj_thresh), nms_thresh_(nms_thresh),frame_size_(frame_size), AIBase(kmodel_file,"HandDetection", debug_mode) +{ + model_name_ = "HandDetection"; + classes_num_ = 1; + vaddr_ = vaddr; + isp_shape_ = isp_shape; + dims_t in_shape{1, isp_shape.channel, isp_shape.height, isp_shape.width}; + int isp_size = isp_shape.channel * isp_shape.height * isp_shape.width; +#if 0 + int in_size = isp_shape.channel * isp_shape.height * isp_shape.width; + ai2d_in_tensor_ = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, { (gsl::byte *)vaddr, in_size }, + true, hrt::pool_shared).expect("cannot create input tensor"); +#else + ai2d_in_tensor_ = hrt::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("create ai2d input tensor failed"); +#endif + ai2d_out_tensor_ = get_input_tensor(0); + Utils::padding_resize(isp_shape, {input_shapes_[0][3], input_shapes_[0][2]}, ai2d_builder_, ai2d_in_tensor_, ai2d_out_tensor_, cv::Scalar(114, 114, 114)); +} + + +HandDetection::~HandDetection() +{ +} + +// ai2d for image +void HandDetection::pre_process(cv::Mat ori_img) +{ + ScopedTiming st(model_name_ + " pre_process image", debug_mode_); + std::vector rgb_chw_vec; + Utils::bgr2rgb_and_hwc2chw(ori_img, rgb_chw_vec); + Utils::padding_resize({ori_img.channels(), ori_img.rows, ori_img.cols}, rgb_chw_vec, {input_shapes_[0][3], input_shapes_[0][2]}, ai2d_out_tensor_, cv::Scalar(114, 114, 114)); +} + +// ai2d for video +void HandDetection::pre_process() +{ + ScopedTiming st(model_name_ + " pre_process_video", debug_mode_); +#if 0 + ai2d_builder_->invoke(ai2d_in_tensor_,ai2d_out_tensor_).expect("error occurred in ai2d running"); +#else + size_t isp_size = isp_shape_.channel * isp_shape_.height * isp_shape_.width; + auto buf = ai2d_in_tensor_.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(buf.data()), (void *)vaddr_, isp_size); + hrt::sync(ai2d_in_tensor_, sync_op_t::sync_write_back, true).expect("sync write_back failed"); + ai2d_builder_->invoke(ai2d_in_tensor_,ai2d_out_tensor_).expect("error occurred in ai2d running"); +#endif +} + +void HandDetection::inference() +{ + this->run(); + this->get_output(); +} + +void HandDetection::post_process(std::vector &result) +{ + auto boxes0 = decode_infer(p_outputs_[0], 8, frame_size_, anchors_0); + result.insert(result.begin(), boxes0.begin(), boxes0.end()); + auto boxes1 = decode_infer(p_outputs_[1], 16, frame_size_, anchors_1); + result.insert(result.begin(), boxes1.begin(), boxes1.end()); + auto boxes2 = decode_infer(p_outputs_[2], 32, frame_size_, anchors_2); + result.insert(result.begin(), boxes2.begin(), boxes2.end()); + nms(result); +} + +void HandDetection::nms(std::vector &input_boxes) +{ + std::sort(input_boxes.begin(), input_boxes.end(), [](BoxInfo a, BoxInfo b) { return a.score > b.score; }); + std::vector vArea(input_boxes.size()); + for (int i = 0; i < int(input_boxes.size()); ++i) + { + vArea[i] = (input_boxes.at(i).x2 - input_boxes.at(i).x1 + 1) + * (input_boxes.at(i).y2 - input_boxes.at(i).y1 + 1); + } + for (int i = 0; i < int(input_boxes.size()); ++i) + { + for (int j = i + 1; j < int(input_boxes.size());) + { + float xx1 = std::max(input_boxes[i].x1, input_boxes[j].x1); + float yy1 = std::max(input_boxes[i].y1, input_boxes[j].y1); + float xx2 = std::min(input_boxes[i].x2, input_boxes[j].x2); + float yy2 = std::min(input_boxes[i].y2, input_boxes[j].y2); + float w = std::max(float(0), xx2 - xx1 + 1); + float h = std::max(float(0), yy2 - yy1 + 1); + float inter = w * h; + float ovr = inter / (vArea[i] + vArea[j] - inter); + if (ovr >= nms_thresh_) + { + input_boxes.erase(input_boxes.begin() + j); + vArea.erase(vArea.begin() + j); + } + else + { + j++; + } + } + } +} + +std::vector HandDetection::decode_infer(float *data, int stride, FrameSize frame_size, float anchors[][2]) +{ +//std::cout << "decode_infer!\n"; + float ratiow = (float)input_shapes_[0][3] / frame_size.width; + float ratioh = (float)input_shapes_[0][2] / frame_size.height; + float gain = ratiow < ratioh ? ratiow : ratioh; + std::vector result; + int grid_size = input_shapes_[0][2] / stride; + int one_rsize = classes_num_ + 5; + float cx, cy, w, h; + for (int shift_y = 0; shift_y < grid_size; shift_y++) + { + for (int shift_x = 0; shift_x < grid_size; shift_x++) + { + int loc = shift_x + shift_y * grid_size; + for (int i = 0; i < 3; i++) + { + float *record = data + (loc * 3 + i) * one_rsize; + float *cls_ptr = record + 5; + for (int cls = 0; cls < classes_num_; cls++) + { + // float score = sigmoid(cls_ptr[cls]) * sigmoid(record[4]); + float score = cls_ptr[cls] * record[4]; + if (score > obj_thresh_) + { + cx = (record[0] * 2.f - 0.5f + (float)shift_x) * (float)stride; + cy = (record[1] * 2.f - 0.5f + (float)shift_y) * (float)stride; + w = pow(record[2] * 2.f, 2) * anchors[i][0]; + h = pow(record[3] * 2.f, 2) * anchors[i][1]; + + cx -= ((input_shapes_[0][3] - frame_size.width * gain) / 2); + cy -= ((input_shapes_[0][2] - frame_size.height * gain) / 2); + cx /= gain; + cy /= gain; + w /= gain; + h /= gain; + BoxInfo box; + box.x1 = std::max(0, std::min(int(frame_size.width), int(cx - w / 2.f))); + box.y1 = std::max(0, std::min(int(frame_size.height), int(cy - h / 2.f))); + box.x2 = std::max(0, std::min(int(frame_size.width), int(cx + w / 2.f))); + box.y2 = std::max(0, std::min(int(frame_size.height), int(cy + h / 2.f))); + + if (abs(box.x1-box.x2)< 0.1*frame_size.width) + continue; + box.score = score; + box.label = cls; + result.push_back(box); + } + } + } + } + } + return result; +} diff --git a/src/reference/ai_poc/virtual_keyboard/hand_detection.h b/src/reference/ai_poc/virtual_keyboard/hand_detection.h new file mode 100644 index 000000000..2ebd414bf --- /dev/null +++ b/src/reference/ai_poc/virtual_keyboard/hand_detection.h @@ -0,0 +1,157 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _HAND_DETECTION_H +#define _HAND_DETECTION_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#include +#include +#include + +#include "utils.h" +#include "ai_base.h" + +using namespace nncase; +using namespace nncase::runtime; +using namespace nncase::runtime::detail; +using namespace std; + +/** + * @brief 手掌检测 + * 主要封装了对于每一帧图片,从预处理、运行到后处理给出结果的过程 + */ +class HandDetection:public AIBase +{ +public: + /** + * @brief HandDetection构造函数,加载kmodel,并初始化kmodel输入、输出 + * @param kmodel_file kmodel文件路径 + * @param obj_thresh 手掌检测阈值,用于过滤roi + * @param nms_thresh 手掌检测框阈值,用于过滤重复roi + * @param frame_size 手掌检测输入图片尺寸 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + + // for image + HandDetection(const char *kmodel_file, float obj_thresh, float nms_thresh, FrameSize frame_size,const int debug_mode); + + /** + * @brief HandDetection构造函数,加载kmodel,并初始化kmodel输入、输出和手掌检测阈值 + * @param kmodel_file kmodel文件路径 + * @param obj_thresh 手掌检测阈值,用于过滤roi + * @param nms_thresh 手掌检测框阈值,用于过滤重复roi + * @param frame_size 手掌检测输入图片尺寸 + * @param isp_shape isp输入大小(chw) + * @param vaddr isp对应虚拟地址 + * @param paddr isp对应物理地址 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + + // for_video + HandDetection(const char *kmodel_file, float obj_thresh, float nms_thresh, FrameSize frame_size, FrameCHWSize isp_shape, uintptr_t vaddr, uintptr_t paddr, const int debug_mode); + + /** + * @brief HandDetection析构函数 + * @return None + */ + ~HandDetection(); + + /** + * @brief 图片预处理 + * @param ori_img 原始图片 + * @return None + */ + void pre_process(cv::Mat ori_img); + + /** + * @brief 视频流预处理(ai2d for isp) + * @return None + */ + void pre_process(); + + /** + * @brief kmodel推理 + * @return None + */ + void inference(); + + /** + * @brief kmodel推理结果后处理 + * @param results 后处理之后的基于原始图像的{检测框坐标点、得分和标签}集合 + * @return None + */ + void post_process(std::vector &result); + + std::vector labels_ = {"hand"}; //模型输出类别名称 + + +private: + + std::unique_ptr ai2d_builder_; // ai2d构建器 + runtime_tensor ai2d_in_tensor_; // ai2d输入tensor + runtime_tensor ai2d_out_tensor_; // ai2d输出tensor + uintptr_t vaddr_; // isp的虚拟地址 + FrameCHWSize isp_shape_; // isp对应的地址大小 + + float obj_thresh_; // 手掌检测阈值 + float nms_thresh_; // 手掌检测框nms阈值 + FrameSize frame_size_; // 输入图片尺寸 + int classes_num_; // 模型输出类别数 + + float anchors_0[3][2] = { { 26,27 }, { 53,52 }, { 75,71 } }; + float anchors_1[3][2] = { { 80,99 }, { 106,82 }, { 99,134 } }; + float anchors_2[3][2] = { { 140,113 }, { 161,172 }, { 245,276 } }; + + /** + * @brief 非极大值抑制 + * @param input_boxes 后处理之后的基于原始图像的{检测框坐标点、得分和标签}集合 + * @return None + */ + void nms(std::vector &input_boxes); + + /** + * @brief 预处理模型输出结果 + * @param data 指向模型推理得到的首个roi置信度的指针 + * @param stride 模型推理得到的feature相比模型输入的下采样倍数 + * @param frame_size 原始图像/帧宽高,用于将结果放到原始图像大小 + * @param anchors 模型推理得到的feature对应的anchor + * @return 每个feature对应的结果映射回原始图像的{检测框坐标点、得分和标签}集合 + */ + std::vector decode_infer(float *data, int stride, FrameSize frame_size, float anchors[][2]); +}; +#endif diff --git a/src/reference/ai_poc/virtual_keyboard/hand_keypoint.cc b/src/reference/ai_poc/virtual_keyboard/hand_keypoint.cc new file mode 100644 index 000000000..b51e1b843 --- /dev/null +++ b/src/reference/ai_poc/virtual_keyboard/hand_keypoint.cc @@ -0,0 +1,198 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "hand_keypoint.h" + +HandKeypoint::HandKeypoint(const char *kmodel_file, const int debug_mode) +:AIBase(kmodel_file, "HandKeypoint", debug_mode) +{ + model_name_ = "HandKeypoint"; + ai2d_out_tensor_ = get_input_tensor(0); +} + +HandKeypoint::HandKeypoint(const char *kmodel_file, FrameCHWSize isp_shape, uintptr_t vaddr, uintptr_t paddr, const int debug_mode) +: AIBase(kmodel_file,"HandKeypoint", debug_mode) +{ + model_name_ = "HandKeypoint"; + vaddr_ = vaddr; + isp_shape_ = isp_shape; + dims_t in_shape{1, isp_shape.channel, isp_shape.height, isp_shape.width}; + int isp_size = isp_shape.channel * isp_shape.height * isp_shape.width; +#if 0 + int in_size = isp_shape.channel * isp_shape.height * isp_shape.width; + ai2d_in_tensor_ = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, { (gsl::byte *)vaddr, in_size }, + true, hrt::pool_shared).expect("cannot create input tensor"); +#else + ai2d_in_tensor_ = hrt::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("create ai2d input tensor failed"); +#endif + ai2d_out_tensor_ = get_input_tensor(0); +} + +HandKeypoint::~HandKeypoint() +{ +} + +void HandKeypoint::pre_process(cv::Mat ori_img, Bbox &bbox) +{ + ScopedTiming st(model_name_ + " pre_process image", debug_mode_); + std::vector chw_vec; + Utils::hwc_to_chw(ori_img, chw_vec); + Utils::crop_resize({ori_img.channels(), ori_img.rows, ori_img.cols}, chw_vec, bbox, ai2d_out_tensor_); +} + +// for video +void HandKeypoint::pre_process(Bbox &bbox) +{ + ScopedTiming st(model_name_ + " pre_process_video", debug_mode_); +#if 1 + size_t isp_size = isp_shape_.channel * isp_shape_.height * isp_shape_.width; + auto buf = ai2d_in_tensor_.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(buf.data()), (void *)vaddr_, isp_size); + hrt::sync(ai2d_in_tensor_, sync_op_t::sync_write_back, true).expect("sync write_back failed"); +#endif + Utils::crop_resize(bbox, ai2d_builder_, ai2d_in_tensor_, ai2d_out_tensor_); +} + +void HandKeypoint::inference() +{ + this->run(); + this->get_output(); +} + +void HandKeypoint::post_process(Bbox &bbox) +{ + ScopedTiming st(model_name_ + " post_process", debug_mode_); + float *pred = p_outputs_[0]; + // 绘制关键点像素坐标 + int64_t output_tensor_size = output_shapes_[0][1];// 关键点输出 (x,y)*21= 42 + results.clear(); + minX = 1088; + maxX = 0; + minY = 1088; + maxY = 0; + + for (unsigned i = 0; i < output_tensor_size / 2; i++) + { + float x_kp; + float y_kp; + x_kp = static_cast(pred[i * 2] * bbox.w + bbox.x); + if (x_kpmaxX) + { + maxX = x_kp; + } + y_kp = static_cast(pred[i * 2 + 1] * bbox.h + bbox.y); + if (y_kpmaxY) + { + maxY = y_kp; + } + + results.push_back(x_kp); + results.push_back(y_kp); + + } +} + +void HandKeypoint::draw_keypoints(cv::Mat &img, Bbox &bbox, bool pic_mode) +{ + ScopedTiming st(model_name_ + " draw_keypoints", debug_mode_); + // 绘制关键点像素坐标 + if(pic_mode) + { + for (unsigned i = 0; i < results.size() / 2; i++) + { + cv::circle(img, cv::Point(results[i * 2], results[i * 2 + 1]), 2, cv::Scalar(255, 155, 0), 3); + } + + for (unsigned k = 0; k < 5; k++) + { + int i = k*8; + unsigned char R = 255, G = 0, B = 0; + + switch(k) + { + case 0:R = 255; G = 0; B = 0;break; + case 1:R = 255; G = 0; B = 255;break; + case 2:R = 255; G = 255; B = 0;break; + case 3:R = 0; G = 255; B = 0;break; + case 4:R = 0; G = 0; B = 255;break; + default: std::cout << "error" << std::endl; + } + + cv::line(img, cv::Point(results[0], results[1]), cv::Point(results[i + 2], results[i + 3]), cv::Scalar(B,G,R), 2, cv::LINE_AA); + cv::line(img, cv::Point(results[i + 2], results[i + 3]), cv::Point(results[i + 4], results[i + 5]), cv::Scalar(B, G, R), 2, cv::LINE_AA); + cv::line(img, cv::Point(results[i + 4], results[i + 5]), cv::Point(results[i + 6], results[i + 7]), cv::Scalar(B, G, R), 2, cv::LINE_AA); + cv::line(img, cv::Point(results[i + 6], results[i + 7]), cv::Point(results[i + 8], results[i + 9]), cv::Scalar(B, G, R), 2, cv::LINE_AA); + } + } + else + { + int osd_width = img.cols; + int osd_height = img.rows; + int SENSOR_HEIGHT = isp_shape_.height; + int SENSOR_WIDTH = isp_shape_.width; + int64_t output_tensor_size = output_shapes_[0][1];// 关键点输出 (x,y)*21= 42 + std::vectorresults_vd(output_tensor_size); + for (unsigned i = 0; i < output_tensor_size / 2; i++) + { + results_vd[i * 2] = static_cast(results[i*2]) / SENSOR_WIDTH * osd_width; + results_vd[i * 2 + 1] = static_cast(results[i*2+1]) / SENSOR_HEIGHT * osd_height; + cv::circle(img, cv::Point(results_vd[i * 2], results_vd[i * 2 + 1]), 4, cv::Scalar(255, 255, 155, 0), 4); + } + + for (unsigned k = 0; k < 5; k++) + { + int i = k*8; + unsigned char R = 255, G = 0, B = 0; + + switch(k) + { + case 0:R = 255; G = 0; B = 0;break; + case 1:R = 255; G = 0; B = 255;break; + case 2:R = 255; G = 255; B = 0;break; + case 3:R = 0; G = 255; B = 0;break; + case 4:R = 0; G = 0; B = 255;break; + default: std::cout << "error" << std::endl; + } + + cv::line(img, cv::Point(results_vd[0], results_vd[1]), cv::Point(results_vd[i + 2], results_vd[i + 3]), cv::Scalar(255, B,G,R), 2, cv::LINE_AA); + cv::line(img, cv::Point(results_vd[i + 2], results_vd[i + 3]), cv::Point(results_vd[i + 4], results_vd[i + 5]), cv::Scalar(255, B, G, R), 2, cv::LINE_AA); + cv::line(img, cv::Point(results_vd[i + 4], results_vd[i + 5]), cv::Point(results_vd[i + 6], results_vd[i + 7]), cv::Scalar(255, B, G, R), 2, cv::LINE_AA); + cv::line(img, cv::Point(results_vd[i + 6], results_vd[i + 7]), cv::Point(results_vd[i + 8], results_vd[i + 9]), cv::Scalar(255, B, G, R), 2, cv::LINE_AA); + } + } +} + +vector HandKeypoint::get_out() +{ + return p_outputs_; +} + diff --git a/src/reference/ai_poc/virtual_keyboard/hand_keypoint.h b/src/reference/ai_poc/virtual_keyboard/hand_keypoint.h new file mode 100644 index 000000000..0252cb8b1 --- /dev/null +++ b/src/reference/ai_poc/virtual_keyboard/hand_keypoint.h @@ -0,0 +1,141 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _HAND_KEYPOINT_H +#define _HAND_KEYPOINT_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "utils.h" +#include "ai_base.h" + + +using namespace nncase; +using namespace nncase::runtime; +using namespace nncase::runtime::detail; +using namespace std; + +/** + * @brief 手部关键点检测 + * 主要封装了对于每一帧图片,从预处理、运行到后处理给出结果的过程 + */ +class HandKeypoint: public AIBase +{ +public: + /** + * @brief HandKeypoint构造函数,加载kmodel,并初始化kmodel输入、输出 + * @param kmodel_file kmodel文件路径 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + HandKeypoint(const char *kmodel_file,const int debug_mode=0); + + /** + * @brief HandKeypoint构造函数,加载kmodel,并初始化kmodel输入、输出 + * @param kmodel_file kmodel文件路径 + * @param isp_shape isp输入大小(chw) + * @param vaddr isp对应虚拟地址 + * @param paddr isp对应物理地址 + * @param debug_mode 0(不调试)、 1(只显示时间)、2(显示所有打印信息) + * @return None + */ + // for video + HandKeypoint(const char *kmodel_file, FrameCHWSize isp_shape, uintptr_t vaddr, uintptr_t paddr, const int debug_mode); + + /** + * @brief HandKeypoint析构函数 + * @return None + */ + ~HandKeypoint(); + + /** + * @brief 图片预处理 + * @param ori_img 原始图片 + * @param bbox 原始手掌检测框位置 + * @return None + */ + void pre_process(cv::Mat ori_img, Bbox &bbox); + + /** + * @brief 视频流预处理(ai2d for isp) + * @param bbox 原始手掌检测框位置 + * @return None + */ + void pre_process(Bbox &bbox); + + /** + * @brief kmodel推理 + * @return None + */ + void inference(); + + /** + * @brief 将kmodel推理结果映射回原图上 + * @param bbox 原始手掌检测框位置 + * @return None + */ + void post_process(Bbox &bbox); + + /** + * @brief 将手部关键点画到原图 + * @param img 原图 + * @param bbox 手部关键点输入框在原图的显示 + * @param pic_mode ture(原图片),false(osd) + * @return None + */ + void draw_keypoints(cv::Mat &img, Bbox &bbox, bool pic_mode); + + /** + * @brief 返回kmodel的输出 + * @return kmodel的输出 + */ + vector get_out(); + + std::vector results; //手部关键点在原图上的坐标 + int minX; //手部关键点x方向的最小值 + int maxX; //手部关键点x方向的最大值 + int minY; //手部关键点y方向的最小值 + int maxY; //手部关键点y方向的最小值 + +private: + std::unique_ptr ai2d_builder_; // ai2d构建器 + runtime_tensor ai2d_in_tensor_; // ai2d输入tensor + runtime_tensor ai2d_out_tensor_; // ai2d输出tensor + uintptr_t vaddr_; // isp的虚拟地址 + FrameCHWSize isp_shape_; // isp对应的地址大小 +}; +#endif diff --git a/src/reference/ai_poc/virtual_keyboard/key.cc b/src/reference/ai_poc/virtual_keyboard/key.cc new file mode 100644 index 000000000..a869bf972 --- /dev/null +++ b/src/reference/ai_poc/virtual_keyboard/key.cc @@ -0,0 +1,59 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "key.h" + +Key::Key(int x, int y, int w, int h, std::string text) +: x_(x), y_(y), w_(w), h_(h), text_(text) +{ +} + +Key::~Key() +{ +} + +void Key::drawKey(cv::Mat& img, float alpha = 0.5) +{ + int fontFace = cv::FONT_HERSHEY_SIMPLEX; + double fontScale = 2; + int thickness = 2; + cv::Scalar text_color = cv::Scalar(255, 255, 255, 255); + cv::Scalar bg_color = cv::Scalar(255, 0, 0, 0); + cv::Mat bg_rec = img(cv::Rect(x_, y_, w_, h_)); + cv::Mat white_rect(bg_rec.size(), bg_rec.type(), bg_color); + cv::addWeighted(bg_rec, alpha, white_rect, 1 - alpha, 1.0, bg_rec); + + cv::Size text_size = cv::getTextSize(text_, fontFace, fontScale, thickness, nullptr); + cv::Point text_pos(x_ + w_/2 - text_size.width/2, y_ + h_/2 + text_size.height/2); + + cv::putText(img, text_, text_pos, fontFace, fontScale, text_color, thickness); +} + +bool Key::isOver(int x, int y) +{ + if ((x_ + w_ > x) && (x > x_) && (y_ + h_ > y) && (y > y_)) { + return true; + } + return false; +} diff --git a/src/reference/ai_poc/virtual_keyboard/key.h b/src/reference/ai_poc/virtual_keyboard/key.h new file mode 100644 index 000000000..04a98a71f --- /dev/null +++ b/src/reference/ai_poc/virtual_keyboard/key.h @@ -0,0 +1,87 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _KEY_H +#define _KEY_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +/** + * @brief 键盘按钮 + * 主要封装了对于每一个键盘按钮的处理 + */ +class Key +{ +public: + int x_, y_, w_, h_; //键盘按钮的位置 + std::string text_; //键盘按钮的字母 + + /** + * @brief Key构造函数 + * @param x //键盘按钮的左上角位置x方向坐标 + * @param y //键盘按钮的左上角位置y方向坐标 + * @param w //键盘按钮的x方向宽度 + * @param h //键盘按钮的y方向高度 + * @param text //键盘按钮的值 + * @return None + */ + Key(int x, int y, int w, int h, std::string text); + + /** + * @brief Key析构函数 + * @return None + */ + ~Key(); + + /** + * @brief 将键盘画到原图 + * @param img 原始图片 + * @param alpha 键盘按钮的透明度 + * @return None + */ + void drawKey(cv::Mat& img, float alpha); + + /** + * @brief 判断一个点是否在键盘按钮内 + * @param x 手指点的x坐标 + * @param y 手指点的y坐标 + * @return None + */ + bool isOver(int x, int y); + +}; +#endif diff --git a/src/reference/ai_poc/virtual_keyboard/main.cc b/src/reference/ai_poc/virtual_keyboard/main.cc new file mode 100644 index 000000000..9d6072ee1 --- /dev/null +++ b/src/reference/ai_poc/virtual_keyboard/main.cc @@ -0,0 +1,330 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include + +#include "utils.h" +#include "vi_vo.h" +#include "hand_detection.h" +#include "hand_keypoint.h" +#include "key.h" + + +std::atomic isp_stop(false); + +void print_usage(const char *name) +{ + cout << "Usage: " << name << " " << endl + << "Options:" << endl + << " kmodel_det 手掌检测kmodel路径\n" + << " obj_thresh 手掌检测阈值\n" + << " nms_thresh 手掌检测非极大值抑制阈值\n" + << " kmodel_kp 手势关键点检测kmodel路径\n" + << " debug_mode 是否需要调试, 0、1、2分别表示不调试、简单调试、详细调试\n" + << "\n" + << endl; +} + +float calculateIntDidtance(cv::Point pt1, cv::Point pt2) { + return cv::sqrt((pt1.x - pt2.x) * (pt1.x - pt2.x) + (pt1.y - pt2.y) * (pt1.y - pt2.y)); +} + +void video_proc(char *argv[]) +{ + vivcap_start(); + // 设置osd参数 + k_video_frame_info vf_info; + void *pic_vaddr = NULL; // osd + memset(&vf_info, 0, sizeof(vf_info)); + vf_info.v_frame.width = osd_width; + vf_info.v_frame.height = osd_height; + vf_info.v_frame.stride[0] = osd_width; + vf_info.v_frame.pixel_format = PIXEL_FORMAT_ARGB_8888; + block = vo_insert_frame(&vf_info, &pic_vaddr); + + // alloc memory,get isp memory + size_t paddr = 0; + void *vaddr = nullptr; + size_t size = SENSOR_CHANNEL * SENSOR_HEIGHT * SENSOR_WIDTH; + int ret = kd_mpi_sys_mmz_alloc_cached(&paddr, &vaddr, "allocate", "anonymous", size); + if (ret) + { + std::cerr << "physical_memory_block::allocate failed: ret = " << ret << ", errno = " << strerror(errno) << std::endl; + std::abort(); + } + + HandDetection hd(argv[1], atof(argv[2]), atof(argv[3]), {SENSOR_WIDTH, SENSOR_HEIGHT}, {SENSOR_CHANNEL, SENSOR_HEIGHT, SENSOR_WIDTH}, reinterpret_cast(vaddr), reinterpret_cast(paddr), atoi(argv[5])); + HandKeypoint hk(argv[4], {SENSOR_CHANNEL, SENSOR_HEIGHT, SENSOR_WIDTH}, reinterpret_cast(vaddr), reinterpret_cast(paddr), atoi(argv[5])); + + + std::vector results; + + std::vector keys; + std::string letters = "QWERTYUIOPASDFGHJKLZXCVBNM"; + + #if defined(CONFIG_BOARD_K230_CANMV) + int character_len = 39; + int box_w = 140; + int box_h = 100; + int startX = 215; + int startY = 360; + int margin = 10; + for (int i = 0; i < letters.size(); i++) { + if (i < 10) + { + keys.push_back(Key(startX + i * box_w + i * margin, startY, box_w, box_h, std::string(1, letters[i]))); + } + else if (i<19) + { + keys.push_back(Key(startX + (i-10) * box_w + (i-10) * margin + 75, startY+box_h+margin, box_w, box_h, std::string(1, letters[i]))); + } + else + { + keys.push_back(Key(startX + (i-19) * box_w + (i-19) * margin + 150, startY+2*box_h+2*margin, box_w, box_h, std::string(1, letters[i]))); + } + } + + keys.push_back(Key(startX + (26-19) * box_w + (26-19) * margin + 150, startY+2*box_h+2*margin, box_w, box_h, "clr")); + keys.push_back(Key(startX + 90, startY+3*box_h+3*margin, 650, box_h, "Space")); + keys.push_back(Key(startX + 100 + 650, startY+3*box_h+3*margin, 650, box_h, "<--")); + + Key textBox(startX, startY-box_h-margin, 10*box_w+9*margin, box_h, " "); + #else + int character_len = 18; + int box_w = 140; + int box_h = 180; + int startX = 174; + int startY = 270; + int margin = 10; + for (int i = 0; i < letters.size(); i++) { + if (i < 5) + { + keys.push_back(Key(startX + i * box_w + i * margin, startY, box_w, box_h, std::string(1, letters[i]))); + } + else if (i<10) + { + keys.push_back(Key(startX + (i-5) * box_w + (i-5) * margin, startY+box_h+margin, box_w, box_h, std::string(1, letters[i]))); + } + else if (i<15) + { + keys.push_back(Key(startX + (i-10) * box_w + (i-10) * margin, startY+2*box_h+2*margin, box_w, box_h, std::string(1, letters[i]))); + } + else if (i<20) + { + keys.push_back(Key(startX + (i-15) * box_w + (i-15) * margin, startY+3*box_h+3*margin, box_w, box_h, std::string(1, letters[i]))); + } + else if (i<25) + { + keys.push_back(Key(startX + (i-20) * box_w + (i-20) * margin, startY+4*box_h+4*margin, box_w, box_h, std::string(1, letters[i]))); + } + else + { + keys.push_back(Key(startX + (i-25) * box_w + (i-25) * margin, startY+5*box_h+5*margin, box_w, box_h, std::string(1, letters[i]))); + } + } + + keys.push_back(Key(startX + (26-25) * box_w + (26-25) * margin, startY+5*box_h+5*margin, 215, box_h, "Space")); + keys.push_back(Key(startX + (26-25) * box_w + 215 + (27-25) * margin, startY+5*box_h+5*margin, box_w, box_h, "clr")); + keys.push_back(Key(startX + (27-25) * box_w + 215 + (28-25) * margin, startY+5*box_h+5*margin, 215, box_h, "<--")); + + Key textBox(startX, startY-box_h-margin, 5*box_w+4*margin, box_h, " "); + #endif + + float previousClick = 0.0; + + while (!isp_stop) + { + ScopedTiming st("total time", 1); + { + ScopedTiming st("read capture", atoi(argv[5])); + // 从vivcap中读取一帧图像到dump_info + memset(&dump_info, 0, sizeof(k_video_frame_info)); + ret = kd_mpi_vicap_dump_frame(vicap_dev, VICAP_CHN_ID_1, VICAP_DUMP_YUV, &dump_info, 1000); + if (ret) + { + printf("sample_vicap...kd_mpi_vicap_dump_frame failed.\n"); + continue; + } + } + { + ScopedTiming st("isp copy", atoi(argv[5])); + auto vbvaddr = kd_mpi_sys_mmap_cached(dump_info.v_frame.phys_addr[0], size); + memcpy(vaddr, (void *)vbvaddr, SENSOR_HEIGHT * SENSOR_WIDTH * 3); + kd_mpi_sys_munmap(vbvaddr, size); + } + + results.clear(); + + hd.pre_process(); + hd.inference(); + hd.post_process(results); + + int signTipX = 0, signTipY = 0; + int thumbTipX = 0, thumbTipY = 0; + + cv::Mat osd_frame(osd_height, osd_width, CV_8UC4, cv::Scalar(0, 0, 0, 0)); + + cv::Point2f index_top; + cv::Point2f thumb_top; + float ratio; + + for (auto r: results) + { + int w = r.x2 - r.x1 + 1; + int h = r.y2 - r.y1 + 1; + + int length = std::max(w,h)/2; + int cx = (r.x1+r.x2)/2; + int cy = (r.y1+r.y2)/2; + int ratio_num = 1.26*length; + + int x1_1 = std::max(0,cx-ratio_num); + int y1_1 = std::max(0,cy-ratio_num); + int x2_1 = std::min(SENSOR_WIDTH-1, cx+ratio_num); + int y2_1 = std::min(SENSOR_HEIGHT-1, cy+ratio_num); + int w_1 = x2_1 - x1_1 + 1; + int h_1 = y2_1 - y1_1 + 1; + + struct Bbox bbox = {x:x1_1,y:y1_1,w:w_1,h:h_1}; + hk.pre_process(bbox); + hk.inference(); + hk.post_process(bbox); + + { + ScopedTiming st("osd draw keypoints", atoi(argv[5])); + hk.draw_keypoints(osd_frame, bbox, false); + } + + float *pred = hk.get_out()[0]; + int draw_x,draw_y; + + index_top.x = pred[8*2] * w_1 + x1_1; + index_top.y = pred[8*2+1] * h_1 + y1_1; + signTipX = static_cast(index_top.x / SENSOR_WIDTH * osd_width); + signTipY = static_cast(index_top.y / SENSOR_HEIGHT * osd_height); + + thumb_top.x = pred[4*2] * w_1 + x1_1; + thumb_top.y = pred[4*2+1] * h_1 + y1_1; + thumbTipX = static_cast(thumb_top.x / SENSOR_WIDTH * osd_width); + thumbTipY = static_cast(thumb_top.y / SENSOR_HEIGHT * osd_height); + + float dis = calculateIntDidtance(cv::Point(signTipX, signTipY), cv::Point(thumbTipX, thumbTipY)); + float dis_hand = calculateIntDidtance(cv::Point(hk.minX, hk.minY), cv::Point(hk.maxX, hk.maxY)); + ratio = dis/dis_hand; + if (ratio < 0.25) + { + int centerX = (signTipX + thumbTipX) / 2; + int centerY = (signTipY + thumbTipY) / 2; + cv::circle(osd_frame, cv::Point(centerX, centerY), 5, cv::Scalar(255, 0, 255, 0), cv::FILLED); + } + } + { + ScopedTiming st("osd draw keyboard", atoi(argv[5])); + float alpha = 0.5; + textBox.drawKey(osd_frame, (float)0.3); + for (auto& k : keys) + { + if (k.isOver(thumbTipX, thumbTipY)) + { + alpha = 0.2; + if ((k.isOver(signTipX, signTipY)) && (ratio < 0.25)) + { + float clickTime = cv::getTickCount(); + if ((clickTime - previousClick) / cv::getTickFrequency() > 0.6) + { + if (k.text_ == "<--") + { + textBox.text_ = textBox.text_.substr(0, textBox.text_.size() - 1); + } + else if (k.text_ == "clr") + { + textBox.text_ = ""; + } + else if (textBox.text_.size() < character_len) + { + if (k.text_ == "Space") { + textBox.text_ += " "; + } + else { + textBox.text_ += k.text_; + } + } + previousClick = clickTime; + } + } + } + k.drawKey(osd_frame, alpha); + alpha = 0.5; + } + } + { + ScopedTiming st("osd copy", atoi(argv[5])); + memcpy(pic_vaddr, osd_frame.data, osd_width * osd_height * 4); + // 显示通道插入帧 + kd_mpi_vo_chn_insert_frame(osd_id + 3, &vf_info); // K_VO_OSD0 + + ret = kd_mpi_vicap_dump_release(vicap_dev, VICAP_CHN_ID_1, &dump_info); + if (ret) + { + printf("sample_vicap...kd_mpi_vicap_dump_release failed.\n"); + } + } + } + + vo_osd_release_block(); + vivcap_stop(); + + // free memory + ret = kd_mpi_sys_mmz_free(paddr, vaddr); + if (ret) + { + std::cerr << "free failed: ret = " << ret << ", errno = " << strerror(errno) << std::endl; + std::abort(); + } +} + + +int main(int argc, char *argv[]) +{ + std::cout << "case " << argv[0] << " built at " << __DATE__ << " " << __TIME__ << std::endl; + if (argc != 6) + { + print_usage(argv[0]); + return -1; + } + { + std::thread thread_isp(video_proc, argv); + while (getchar() != 'q') + { + usleep(10000); + } + + isp_stop = true; + thread_isp.join(); + } + return 0; +} diff --git a/src/reference/ai_poc/virtual_keyboard/scoped_timing.hpp b/src/reference/ai_poc/virtual_keyboard/scoped_timing.hpp new file mode 100644 index 000000000..874ff1b17 --- /dev/null +++ b/src/reference/ai_poc/virtual_keyboard/scoped_timing.hpp @@ -0,0 +1,70 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include + +/** + * @brief 计时类 + * 统计在该类实例生命周期内的耗时 + */ +class ScopedTiming +{ +public: + /** + * @brief ScopedTiming构造函数,初始化计时对象名称并开始计时 + * @param info 计时对象名称 + * @param enable_profile 是否开始计时 + * @return None + */ + ScopedTiming(std::string info = "ScopedTiming", int enable_profile = 1) + : m_info(info), enable_profile(enable_profile) + { + if (enable_profile) + { + m_start = std::chrono::steady_clock::now(); + } + } + + /** + * @brief ScopedTiming析构,结束计时,并打印耗时 + * @return None + */ + ~ScopedTiming() + { + if (enable_profile) + { + m_stop = std::chrono::steady_clock::now(); + double elapsed_ms = std::chrono::duration(m_stop - m_start).count(); + std::cout << m_info << " took " << elapsed_ms << " ms" << std::endl; + } + } + +private: + int enable_profile; // 是否统计时间 + std::string m_info; // 计时对象名称 + std::chrono::steady_clock::time_point m_start; // 计时开始时间 + std::chrono::steady_clock::time_point m_stop; // 计时结束时间 +}; \ No newline at end of file diff --git a/src/reference/ai_poc/virtual_keyboard/utils.cc b/src/reference/ai_poc/virtual_keyboard/utils.cc new file mode 100644 index 000000000..7a60f9cdc --- /dev/null +++ b/src/reference/ai_poc/virtual_keyboard/utils.cc @@ -0,0 +1,395 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +// utils.cpp +#include +#include "utils.h" + +using std::ofstream; +using std::vector; +auto cache = cv::Mat::zeros(1, 1, CV_32FC1); +void Utils::dump_binary_file(const char *file_name, char *data, const size_t size) +{ + // eg:Utils::dump_binary_file(out_name.c_str(),reinterpret_cast(p_outputs_[i]),each_output_size_by_byte_[i+1]-each_output_size_by_byte_[i]); + std::ofstream outf; + outf.open(file_name, std::ofstream::binary); + outf.write(data, size); + outf.close(); +} + +void Utils::dump_gray_image(const char *file_name, const FrameSize &frame_size, unsigned char *data) +{ + cv::Mat gray_image = cv::Mat(frame_size.height, frame_size.width, CV_8UC1, data); + cv::imwrite(file_name, gray_image); +} + +void Utils::dump_color_image(const char *file_name, const FrameSize &frame_size, unsigned char *data) +{ + cv::Mat image_r = cv::Mat(frame_size.height, frame_size.width, CV_8UC1, data); + cv::Mat image_g = cv::Mat(frame_size.height, frame_size.width, CV_8UC1, data+frame_size.height*frame_size.width); + cv::Mat image_b = cv::Mat(frame_size.height, frame_size.width, CV_8UC1, data+2*frame_size.height*frame_size.width); + + std::vector color_vec(3); + color_vec.clear(); + color_vec.push_back(image_b); + color_vec.push_back(image_g); + color_vec.push_back(image_r); + + cv::Mat color_img; + cv::merge(color_vec, color_img); + cv::imwrite(file_name, color_img); +} + +cv::Mat Utils::padding_resize(const cv::Mat img, const FrameSize &frame_size, const cv::Scalar &padding) +{ + int ori_w = img.cols; + int ori_h = img.rows; + float ratiow = (float)frame_size.width / ori_w; + float ratioh = (float)frame_size.height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(frame_size.width - new_w) / 2; + float dh = (float)(frame_size.height - new_h) / 2; + int top = (int)(roundf(0 - 0.1)); + int bottom = (int)(roundf(dh * 2 + 0.1)); + int left = (int)(roundf(0 - 0.1)); + int right = (int)(roundf(dw * 2 - 0.1)); + cv::Mat cropped_img; + + cv::resize(img, cropped_img, cv::Size(new_w, new_h), cv::INTER_AREA); + cv::copyMakeBorder(cropped_img, cropped_img, top, bottom, left, right, cv::BORDER_CONSTANT, padding); + + return cropped_img; +} + +cv::Mat Utils::resize(const cv::Mat img, const FrameSize &frame_size) +{ + cv::Mat cropped_img; + cv::resize(img, cropped_img, cv::Size(frame_size.width, frame_size.height), cv::INTER_LINEAR); + return cropped_img; +} + +cv::Mat Utils::bgr_to_rgb(cv::Mat ori_img) +{ + cv::Mat rgb_img; + cv::cvtColor(ori_img, rgb_img, cv::COLOR_BGR2RGB); + return rgb_img; +} + +void Utils::hwc_to_chw(cv::Mat &ori_img, std::vector &chw_vec) +{ + // for rgb format + std::vector rgbChannels(3); + cv::split(ori_img, rgbChannels); + for (auto i = 0; i < rgbChannels.size(); i++) + { + std::vector data = std::vector(rgbChannels[i].reshape(1, 1)); + chw_vec.insert(chw_vec.end(), data.begin(), data.end()); + } +} + +void Utils::bgr2rgb_and_hwc2chw(cv::Mat &ori_img, std::vector &chw_vec) +{ + // for bgr format + std::vector bgrChannels(3); + cv::split(ori_img, bgrChannels); + for (auto i = 2; i > -1; i--) + { + std::vector data = std::vector(bgrChannels[i].reshape(1, 1)); + chw_vec.insert(chw_vec.end(), data.begin(), data.end()); + } +} + +void Utils::resize(FrameCHWSize ori_shape, std::vector &chw_vec, runtime_tensor &ai2d_out_tensor) +{ + // build ai2d_in_tensor + dims_t in_shape{1, ori_shape.channel, ori_shape.height, ori_shape.width}; + runtime_tensor ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), chw_vec.data(), chw_vec.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + // ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, typecode_t::dt_uint8, typecode_t::dt_uint8}; + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param { false, 30, 20, 400, 600 }; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, ai2d_pad_mode::constant, {114, 114, 114}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::resize(std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor) +{ + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param { false, 30, 20, 400, 600 }; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, ai2d_pad_mode::constant, {114, 114, 114}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::crop_resize(FrameCHWSize ori_shape, std::vector &chw_vec, Bbox &crop_info, runtime_tensor &ai2d_out_tensor) +{ + // build ai2d_in_tensor + dims_t in_shape{1, ori_shape.channel, ori_shape.height, ori_shape.width}; + runtime_tensor ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), chw_vec.data(), chw_vec.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{true, crop_info.x, crop_info.y, crop_info.w, crop_info.h}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, ai2d_pad_mode::constant, {114, 114, 114}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::crop_resize(Bbox &crop_info, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor) +{ + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, typecode_t::dt_uint8, typecode_t::dt_uint8}; + ai2d_crop_param_t crop_param{true, crop_info.x, crop_info.y, crop_info.w, crop_info.h}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, ai2d_pad_mode::constant, {114, 114, 114}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::padding_resize(FrameCHWSize ori_shape, std::vector &chw_vec, FrameSize resize_shape, runtime_tensor &ai2d_out_tensor, cv::Scalar padding) +{ + int ori_w = ori_shape.width; + int ori_h = ori_shape.height; + int width = resize_shape.width; + int height = resize_shape.height; + float ratiow = (float)width / ori_w; + float ratioh = (float)height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(width - new_w) / 2; + float dh = (float)(height - new_h) / 2; + int top = (int)(roundf(dh - 0.1)); + int bottom = (int)(roundf(dh + 0.1)); + int left = (int)(roundf(dw - 0.1)); + int right = (int)(roundf(dw - 0.1)); + + // create input + dims_t in_shape{1, ori_shape.channel, ori_h, ori_w}; + auto ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), chw_vec.data(), chw_vec.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{true, {{0, 0}, {0, 0}, {top, bottom}, {left, right}}, ai2d_pad_mode::constant, {padding[0], padding[1], padding[2]}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::padding_resize_one_side(FrameCHWSize ori_shape, std::vector &chw_vec, FrameSize resize_shape, runtime_tensor &ai2d_out_tensor, cv::Scalar padding) +{ + int ori_w = ori_shape.width; + int ori_h = ori_shape.height; + int width = resize_shape.width; + int height = resize_shape.height; + float ratiow = (float)width / ori_w; + float ratioh = (float)height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(width - new_w) / 2; + float dh = (float)(height - new_h) / 2; + int top = (int)(roundf(0)); + int bottom = (int)(roundf(dh * 2 + 0.1)); + int left = (int)(roundf(0)); + int right = (int)(roundf(dw * 2 - 0.1)); + + // create input + dims_t in_shape{1, ori_shape.channel, ori_h, ori_w}; + auto ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), chw_vec.data(), chw_vec.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{true, {{0, 0}, {0, 0}, {top, bottom}, {left, right}}, ai2d_pad_mode::constant, {padding[0], padding[1], padding[2]}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::padding_resize(FrameCHWSize ori_shape, FrameSize resize_shape, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor, const cv::Scalar padding) +{ + int ori_w = ori_shape.width; + int ori_h = ori_shape.height; + int width = resize_shape.width; + int height = resize_shape.height; + float ratiow = (float)width / ori_w; + float ratioh = (float)height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(width - new_w) / 2; + float dh = (float)(height - new_h) / 2; + int top = (int)(roundf(dh - 0.1)); + int bottom = (int)(roundf(dh + 0.1)); + int left = (int)(roundf(dw - 0.1)); + int right = (int)(roundf(dw - 0.1)); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{true, {{0, 0}, {0, 0}, {top, bottom}, {left, right}}, ai2d_pad_mode::constant, {padding[0], padding[1], padding[2]}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::padding_resize_one_side(FrameCHWSize ori_shape, FrameSize resize_shape, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor, const cv::Scalar padding) +{ + int ori_w = ori_shape.width; + int ori_h = ori_shape.height; + int width = resize_shape.width; + int height = resize_shape.height; + float ratiow = (float)width / ori_w; + float ratioh = (float)height / ori_h; + float ratio = ratiow < ratioh ? ratiow : ratioh; + int new_w = (int)(ratio * ori_w); + int new_h = (int)(ratio * ori_h); + float dw = (float)(width - new_w) / 2; + float dh = (float)(height - new_h) / 2; + int top = (int)(roundf(0)); + int bottom = (int)(roundf(dh * 2 + 0.1)); + int left = (int)(roundf(0)); + int right = (int)(roundf(dw * 2 - 0.1)); + + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{true, {{0, 0}, {0, 0}, {top, bottom}, {left, right}}, ai2d_pad_mode::constant, {padding[0], padding[1], padding[2]}}; + ai2d_resize_param_t resize_param{true, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{false, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {0.5, 0.1, 0.0, 0.1, 0.5, 0.0}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +void Utils::affine(FrameCHWSize ori_shape, std::vector &ori_data, float *affine_matrix, runtime_tensor &ai2d_out_tensor) +{ + runtime_tensor ai2d_in_tensor; + // init ai2d in/out + dims_t in_shape{1, ori_shape.channel, ori_shape.height, ori_shape.width}; + ai2d_in_tensor = host_runtime_tensor::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("cannot create input tensor"); + + // ai2d input + auto input_buf = ai2d_in_tensor.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); + memcpy(reinterpret_cast(input_buf.data()), ori_data.data(), ori_data.size()); + hrt::sync(ai2d_in_tensor, sync_op_t::sync_write_back, true).expect("write back input failed"); + + // run ai2d + + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {10, 0}}, ai2d_pad_mode::constant, {255, 10, 5}}; + ai2d_resize_param_t resize_param{false, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{true, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {affine_matrix[0], affine_matrix[1], affine_matrix[2], affine_matrix[3], affine_matrix[4], affine_matrix[5]}}; + + dims_t out_shape = ai2d_out_tensor.shape(); + ai2d_builder builder { in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param }; + builder.build_schedule(); + builder.invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} + +// for video(只算一次即可) +void Utils::affine(float *affine_matrix, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor) +{ + // run ai2d + ai2d_datatype_t ai2d_dtype{ai2d_format::NCHW_FMT, ai2d_format::NCHW_FMT, ai2d_in_tensor.datatype(), ai2d_out_tensor.datatype()}; + ai2d_crop_param_t crop_param{false, 0, 0, 0, 0}; + ai2d_shift_param_t shift_param{false, 0}; + ai2d_pad_param_t pad_param{false, {{0, 0}, {0, 0}, {0, 0}, {10, 0}}, ai2d_pad_mode::constant, {255, 10, 5}}; + ai2d_resize_param_t resize_param{false, ai2d_interp_method::tf_bilinear, ai2d_interp_mode::half_pixel}; + ai2d_affine_param_t affine_param{true, ai2d_interp_method::cv2_bilinear, 0, 0, 127, 1, {affine_matrix[0], affine_matrix[1], affine_matrix[2], affine_matrix[3], affine_matrix[4], affine_matrix[5]}}; + + dims_t in_shape = ai2d_in_tensor.shape(); + dims_t out_shape = ai2d_out_tensor.shape(); + builder.reset(new ai2d_builder(in_shape, out_shape, ai2d_dtype, crop_param, shift_param, pad_param, resize_param, affine_param)); + builder->build_schedule(); + builder->invoke(ai2d_in_tensor,ai2d_out_tensor).expect("error occurred in ai2d running"); +} diff --git a/src/reference/ai_poc/virtual_keyboard/utils.h b/src/reference/ai_poc/virtual_keyboard/utils.h new file mode 100644 index 000000000..1a4c32d18 --- /dev/null +++ b/src/reference/ai_poc/virtual_keyboard/utils.h @@ -0,0 +1,320 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +// utils.h +#ifndef UTILS_H +#define UTILS_H + +#include +#include +#include +#include +#include +#include +#include + +using namespace nncase; +using namespace nncase::runtime; +using namespace nncase::runtime::k230; +using namespace nncase::F::k230; + +using cv::Mat; +using std::cout; +using std::endl; +using std::ifstream; +using std::vector; + +/** + * @brief 手掌检测框 + */ +typedef struct BoxInfo +{ + float x1; // 手掌检测框的左上顶点x坐标 + float y1; // 手掌检测框的左上顶点y坐标 + float x2; // 手掌检测框的右下顶点x坐标 + float y2; // 手掌检测框的右下顶点y坐标 + float score; // 手掌检测框的得分 + int label; // 手掌检测框的类别 +} BoxInfo; + +/** + * @brief 人脸检测框 + */ +typedef struct Bbox +{ + float x; // 人脸检测框的左顶点x坐标 + float y; // 人脸检测框的左顶点x坐标 + float w; + float h; +} Bbox; + +/** + * @brief 人脸五官点 + */ +typedef struct SparseLandmarks +{ + float points[10]; // 人脸五官点,依次是图片的左眼(x,y)、右眼(x,y),鼻子(x,y),左嘴角(x,y),右嘴角 +} SparseLandmarks; + +/** + * @brief 单张/帧图片大小 + */ +typedef struct FrameSize +{ + size_t width; // 宽 + size_t height; // 高 +} FrameSize; + +/** + * @brief 单张/帧图片大小 + */ +typedef struct FrameCHWSize +{ + size_t channel; // 通道 + size_t height; // 高 + size_t width; // 宽 +} FrameCHWSize; + +/** + * @brief AI Demo工具类 + * 封装了AI Demo常用的函数,包括二进制文件读取、文件保存、图片预处理等操作 + */ +class Utils +{ +public: + /** + * @brief 读取2进制文件 + * @param file_name 文件路径 + * @return 文件对应类型的数据 + */ + template + static vector read_binary_file(const char *file_name) + { + ifstream ifs(file_name, std::ios::binary); + ifs.seekg(0, ifs.end); + size_t len = ifs.tellg(); + vector vec(len / sizeof(T), 0); + ifs.seekg(0, ifs.beg); + ifs.read(reinterpret_cast(vec.data()), len); + ifs.close(); + return vec; + } + + /** + * @brief 打印数据 + * @param data 需打印数据对应指针 + * @param size 需打印数据大小 + * @return None + */ + template + static void dump(const T *data, size_t size) + { + for (size_t i = 0; i < size; i++) + { + cout << data[i] << " "; + } + cout << endl; + } + + // 静态成员函数不依赖于类的实例,可以直接通过类名调用 + /** + * @brief 将数据以2进制方式保存为文件 + * @param file_name 保存文件路径+文件名 + * @param data 需要保存的数据 + * @param size 需要保存的长度 + * @return None + */ + static void dump_binary_file(const char *file_name, char *data, const size_t size); + + /** + * @brief 将数据保存为灰度图片 + * @param file_name 保存图片路径+文件名 + * @param frame_size 保存图片的宽、高 + * @param data 需要保存的数据 + * @return None + */ + static void dump_gray_image(const char *file_name, const FrameSize &frame_size, unsigned char *data); + + /** + * @brief 将数据保存为彩色图片 + * @param file_name 保存图片路径+文件名 + * @param frame_size 保存图片的宽、高 + * @param data 需要保存的数据 + * @return None + */ + static void dump_color_image(const char *file_name, const FrameSize &frame_size, unsigned char *data); + + + /*************************for img process********************/ + /** + * @brief 对图片进行先padding后resize的处理 + * @param ori_img 原始图片 + * @param frame_size 需要resize图像的宽高 + * @param padding 需要padding的像素,默认是cv::Scalar(104, 117, 123),BGR + * @return 处理后图像 + */ + static cv::Mat padding_resize(const cv::Mat img, const FrameSize &frame_size, const cv::Scalar &padding = cv::Scalar(104, 117, 123)); + + /** + * @brief 对图片resize + * @param ori_img 原始图片 + * @param frame_size 需要resize图像的宽高 + * @param padding 需要padding的像素,默认是cv::Scalar(104, 117, 123),BGR + * @return 处理后图像 + */ + static cv::Mat resize(const cv::Mat ori_img, const FrameSize &frame_size); + + /** + * @brief 将图片从bgr转为rgb + * @param ori_img 原始图片 + * @return 处理后图像 + */ + static cv::Mat bgr_to_rgb(cv::Mat ori_img); + + /** + * @brief 将RGB或RGB图片从hwc转为chw + * @param ori_img 原始图片 + * @param chw_vec 转为chw后的数据 + * @return None + */ + static void hwc_to_chw(cv::Mat &ori_img, std::vector &chw_vec); // for rgb data + + /** + * @brief 将BGR图片从hwc转为chw + * @param ori_img 原始图片 + * @param chw_vec 转为chw后的数据 + * @return None + */ + static void bgr2rgb_and_hwc2chw(cv::Mat &ori_img, std::vector &chw_vec); + + /*************************for ai2d ori_img process********************/ + // resize + /** + * @brief resize函数,对chw数据进行resize + * @param ori_shape 原始数据chw + * @param chw_vec 原始数据 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + static void resize(FrameCHWSize ori_shape, std::vector &chw_vec, runtime_tensor &ai2d_out_tensor); + + /** + * @brief resize函数 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + static void resize(std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor); + + // crop resize + /** + * @brief resize函数,对chw数据进行crop & resize + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + static void crop_resize(FrameCHWSize ori_shape, std::vector &chw_vec, Bbox &crop_info, runtime_tensor &ai2d_out_tensor); + + /** + * @brief crop_resize函数,对chw数据进行crop & resize + * @param crop_info 需要crop的位置,x,y,w,h + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + static void crop_resize(Bbox &crop_info, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor); + + // padding resize + /** + * @brief padding_resize函数(上下左右padding),对chw数据进行padding & resize + * @param ori_shape 原始数据chw + * @param chw_vec 原始数据 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + static void padding_resize(FrameCHWSize ori_shape, std::vector &chw_vec, FrameSize resize_shape, runtime_tensor &ai2d_out_tensor, cv::Scalar padding); + + /** + * @brief padding_resize函数(右或下padding),对chw数据进行padding & resize + * @param ori_shape 原始数据chw + * @param chw_vec 原始数据 + * @param resize_shape resize之后的大小 + * @param ai2d_out_tensor ai2d输出 + * @param padding 填充值,用于resize时的等比例变换 + * @return None + */ + static void padding_resize_one_side(FrameCHWSize ori_shape, std::vector &chw_vec, FrameSize resize_shape, runtime_tensor &ai2d_out_tensor, cv::Scalar padding); + + /** + * @brief padding_resize函数(上下左右padding),对chw数据进行padding & resize + * @param ori_shape 原始数据chw + * @param resize_shape resize之后的大小 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @param padding 填充值,用于resize时的等比例变换 + * @return None + */ + static void padding_resize(FrameCHWSize ori_shape, FrameSize resize_shape, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor, cv::Scalar padding); + + /** + * @brief padding_resize函数(右或下padding),对chw数据进行padding & resize + * @param ori_shape 原始数据chw + * @param resize_shape resize之后的大小 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @param padding 填充值,用于resize时的等比例变换 + * @return None + */ + static void padding_resize_one_side(FrameCHWSize ori_shape, FrameSize resize_shape, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor, const cv::Scalar padding); + + // affine + /** + * @brief 仿射变换函数,对chw数据进行仿射变换(for imgae) + * @param ori_shape 原始数据chw大小 + * @param ori_data 原始数据 + * @param affine_matrix 仿射变换矩阵 + * @param ai2d_out_tensor 仿射变换后的数据 + * @return None + */ + static void affine(FrameCHWSize ori_shape, std::vector &ori_data, float *affine_matrix, runtime_tensor &ai2d_out_tensor); + + /** + * @brief 仿射变换函数,对chw数据进行仿射变换(for video) + * @param affine_matrix 仿射变换矩阵 + * @param builder ai2d构建器,用于运行ai2d + * @param ai2d_in_tensor ai2d输入 + * @param ai2d_out_tensor ai2d输出 + * @return None + */ + static void affine(float *affine_matrix, std::unique_ptr &builder, runtime_tensor &ai2d_in_tensor, runtime_tensor &ai2d_out_tensor); +}; + +#endif diff --git a/src/reference/ai_poc/virtual_keyboard/vi_vo.h b/src/reference/ai_poc/virtual_keyboard/vi_vo.h new file mode 100644 index 000000000..e3d8bdba4 --- /dev/null +++ b/src/reference/ai_poc/virtual_keyboard/vi_vo.h @@ -0,0 +1,627 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include "mpi_sys_api.h" + +/* vicap */ +#include +#include +#include +#include +#include + +#include "k_module.h" +#include "k_type.h" +#include "k_vb_comm.h" +#include "k_video_comm.h" +#include "k_sys_comm.h" +#include "mpi_vb_api.h" +#include "mpi_vicap_api.h" +#include "mpi_isp_api.h" +#include "mpi_sys_api.h" +#include "k_vo_comm.h" +#include "mpi_vo_api.h" + +#include "vo_test_case.h" + +#include "k_connector_comm.h" +#include "mpi_connector_api.h" +#include "k_autoconf_comm.h" + + +#if defined(CONFIG_BOARD_K230_CANMV) +#define SENSOR_CHANNEL (3) // isp通道数 +#define SENSOR_HEIGHT (720) // isp高度,ai输入,竖屏 +#define SENSOR_WIDTH (1280) // isp宽度,ai输入,竖屏 +#define ISP_CHN0_WIDTH (1920)//(1920) +#define ISP_CHN0_HEIGHT (1080)//(1080) +#define vicap_install_osd (1) +#define osd_id K_VO_OSD3 +#define osd_width (1920) +#define osd_height (1080) +#else +#define SENSOR_CHANNEL (3) // isp通道数 +#define SENSOR_HEIGHT (1280) // isp高度,ai输入,竖屏 +#define SENSOR_WIDTH (720) // isp宽度,ai输入,竖屏 +#define ISP_CHN0_WIDTH (1088)//(1920) +#define ISP_CHN0_HEIGHT (1920)//(1080) +#define vicap_install_osd (1) +#define osd_id K_VO_OSD3 +#define osd_width (1080) +#define osd_height (1920) +#endif + + +k_vb_config config; +k_vicap_dev vicap_dev; +k_vicap_chn vicap_chn; +k_vicap_dev_attr dev_attr; +k_vicap_chn_attr chn_attr; +k_vicap_sensor_info sensor_info; +k_vicap_sensor_type sensor_type; +k_mpp_chn vicap_mpp_chn; +k_mpp_chn vo_mpp_chn; + +k_video_frame_info dump_info; + +k_vo_draw_frame vo_frame = (k_vo_draw_frame) { + 1, + 16, + 16, + 128, + 128, + 1 +}; + +static k_vb_blk_handle block; +k_u32 g_pool_id; + +int vo_creat_layer_test(k_vo_layer chn_id, layer_info *info) +{ + k_vo_video_layer_attr attr; + + // check layer + if ((chn_id >= K_MAX_VO_LAYER_NUM) || ((info->func & K_VO_SCALER_ENABLE) && (chn_id != K_VO_LAYER0)) + || ((info->func != 0) && (chn_id == K_VO_LAYER2))) + { + printf("input layer num failed \n"); + return -1 ; + } + + // check scaler + + // set offset + attr.display_rect = info->offset; + // set act + attr.img_size = info->act_size; + // sget size + info->size = info->act_size.height * info->act_size.width * 3 / 2; + //set pixel format + attr.pixel_format = info->format; + if (info->format != PIXEL_FORMAT_YVU_PLANAR_420) + { + printf("input pix format failed \n"); + return -1; + } + // set stride + attr.stride = (info->act_size.width / 8 - 1) + ((info->act_size.height - 1) << 16); + // set function + attr.func = info->func; + // set scaler attr + attr.scaler_attr = info->attr; + + // set video layer atrr + kd_mpi_vo_set_video_layer_attr(chn_id, &attr); + + // enable layer + kd_mpi_vo_enable_video_layer(chn_id); + + return 0; +} + +k_vb_blk_handle vo_insert_frame(k_video_frame_info *vf_info, void **pic_vaddr) +{ + k_u64 phys_addr = 0; + k_u32 *virt_addr; + k_vb_blk_handle handle; + k_s32 size; + + if (vf_info == NULL) + return K_FALSE; + + if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_ABGR_8888 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_ARGB_8888) + size = vf_info->v_frame.height * vf_info->v_frame.width * 4; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_RGB_565 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_BGR_565) + size = vf_info->v_frame.height * vf_info->v_frame.width * 2; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_ABGR_4444 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_ARGB_4444) + size = vf_info->v_frame.height * vf_info->v_frame.width * 2; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_RGB_888 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_BGR_888) + size = vf_info->v_frame.height * vf_info->v_frame.width * 3; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_ARGB_1555 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_ABGR_1555) + size = vf_info->v_frame.height * vf_info->v_frame.width * 2; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_YVU_PLANAR_420) + size = vf_info->v_frame.height * vf_info->v_frame.width * 3 / 2; + + size = size + 4096; // 强制4K ,后边得删了 + + printf("vb block size is %x \n", size); + + handle = kd_mpi_vb_get_block(g_pool_id, size, NULL); + if (handle == VB_INVALID_HANDLE) + { + printf("%s get vb block error\n", __func__); + return K_FAILED; + } + + phys_addr = kd_mpi_vb_handle_to_phyaddr(handle); + if (phys_addr == 0) + { + printf("%s get phys addr error\n", __func__); + return K_FAILED; + } + + virt_addr = (k_u32 *)kd_mpi_sys_mmap(phys_addr, size); + // virt_addr = (k_u32 *)kd_mpi_sys_mmap_cached(phys_addr, size); + + if (virt_addr == NULL) + { + printf("%s mmap error\n", __func__); + return K_FAILED; + } + + vf_info->mod_id = K_ID_VO; + vf_info->pool_id = g_pool_id; + vf_info->v_frame.phys_addr[0] = phys_addr; + if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_YVU_PLANAR_420) + vf_info->v_frame.phys_addr[1] = phys_addr + (vf_info->v_frame.height * vf_info->v_frame.stride[0]); + *pic_vaddr = virt_addr; + + printf("phys_addr is %lx g_pool_id is %d \n", phys_addr, g_pool_id); + + return handle; +} + +k_u32 vo_creat_osd_test(k_vo_osd osd, osd_info *info) +{ + k_vo_video_osd_attr attr; + + // set attr + attr.global_alptha = info->global_alptha; + + if (info->format == PIXEL_FORMAT_ABGR_8888 || info->format == PIXEL_FORMAT_ARGB_8888) + { + info->size = info->act_size.width * info->act_size.height * 4; + info->stride = info->act_size.width * 4 / 8; + } + else if (info->format == PIXEL_FORMAT_RGB_565 || info->format == PIXEL_FORMAT_BGR_565) + { + info->size = info->act_size.width * info->act_size.height * 2; + info->stride = info->act_size.width * 2 / 8; + } + else if (info->format == PIXEL_FORMAT_RGB_888 || info->format == PIXEL_FORMAT_BGR_888) + { + info->size = info->act_size.width * info->act_size.height * 3; + info->stride = info->act_size.width * 3 / 8; + } + else if(info->format == PIXEL_FORMAT_ARGB_4444 || info->format == PIXEL_FORMAT_ABGR_4444) + { + info->size = info->act_size.width * info->act_size.height * 2; + info->stride = info->act_size.width * 2 / 8; + } + else if(info->format == PIXEL_FORMAT_ARGB_1555 || info->format == PIXEL_FORMAT_ABGR_1555) + { + info->size = info->act_size.width * info->act_size.height * 2; + info->stride = info->act_size.width * 2 / 8; + } + else + { + printf("set osd pixel format failed \n"); + } + + attr.stride = info->stride; + attr.pixel_format = info->format; + attr.display_rect = info->offset; + attr.img_size = info->act_size; + kd_mpi_vo_set_video_osd_attr(osd, &attr); + + kd_mpi_vo_osd_enable(osd); + + return 0; +} + +void sample_vicap_install_osd(void) +{ + osd_info osd; + + osd.act_size.width = osd_width ; + osd.act_size.height = osd_height; + osd.offset.x = 0; + osd.offset.y = 0; + osd.global_alptha = 0xff; + // osd.global_alptha = 0x32; + osd.format = PIXEL_FORMAT_ARGB_8888;//PIXEL_FORMAT_ARGB_4444; //PIXEL_FORMAT_ARGB_1555;//PIXEL_FORMAT_ARGB_8888; + + vo_creat_osd_test(osd_id, &osd); +} + +void vo_osd_release_block(void) +{ + if(vicap_install_osd == 1) + { + kd_mpi_vo_osd_disable(osd_id); + kd_mpi_vb_release_block(block); + } + +} + +static k_s32 sample_connector_init(void) +{ + k_u32 ret = 0; + k_s32 connector_fd; +#if defined(CONFIG_BOARD_K230_CANMV) + k_connector_type connector_type = LT9611_MIPI_4LAN_1920X1080_30FPS;// HX8377_V2_MIPI_4LAN_1080X1920_30FPS; +#else + k_connector_type connector_type = HX8377_V2_MIPI_4LAN_1080X1920_30FPS; +#endif + k_connector_info connector_info; + + memset(&connector_info, 0, sizeof(k_connector_info)); + + //connector get sensor info + ret = kd_mpi_get_connector_info(connector_type, &connector_info); + if (ret) { + printf("sample_vicap, the sensor type not supported!\n"); + return ret; + } + + connector_fd = kd_mpi_connector_open(connector_info.connector_name); + if (connector_fd < 0) { + printf("%s, connector open failed.\n", __func__); + return K_ERR_VO_NOTREADY; + } + + // set connect power + kd_mpi_connector_power_set(connector_fd, K_TRUE); + // connector init + kd_mpi_connector_init(connector_fd, connector_info); + + return 0; +} + +static k_s32 vo_layer_vdss_bind_vo_config(void) +{ + layer_info info; + + k_vo_layer chn_id = K_VO_LAYER1; + + memset(&info, 0, sizeof(info)); + + sample_connector_init(); + + // config lyaer + info.act_size.width = ISP_CHN0_WIDTH;//ISP_CHN0_HEIGHT;//1080;//640;//1080; + info.act_size.height = ISP_CHN0_HEIGHT;//ISP_CHN0_WIDTH;//1920;//480;//1920; + info.format = PIXEL_FORMAT_YVU_PLANAR_420; + info.func = 0;//K_ROTATION_180;////K_ROTATION_90; + info.global_alptha = 0xff; + info.offset.x = 0;//(1080-w)/2, + info.offset.y = 0;//(1920-h)/2; + vo_creat_layer_test(chn_id, &info); + + if(vicap_install_osd == 1) + sample_vicap_install_osd(); + + //exit ; + return 0; +} + +static void sample_vicap_bind_vo(k_mpp_chn vicap_mpp_chn, k_mpp_chn vo_mpp_chn) +{ + k_s32 ret; + + ret = kd_mpi_sys_bind(&vicap_mpp_chn, &vo_mpp_chn); + if (ret) { + printf("kd_mpi_sys_unbind failed:0x%x\n", ret); + } + + return; +} + +static void sample_vicap_unbind_vo(k_mpp_chn vicap_mpp_chn, k_mpp_chn vo_mpp_chn) +{ + k_s32 ret; + + ret = kd_mpi_sys_unbind(&vicap_mpp_chn, &vo_mpp_chn); + if (ret) { + printf("kd_mpi_sys_unbind failed:0x%x\n", ret); + } + + return; +} + +int vivcap_start() +{ + k_s32 ret = 0; + + k_u32 pool_id; + k_vb_pool_config pool_config; + + printf("sample_vicap ...\n"); + +#if defined(CONFIG_BOARD_K230_CANMV) + sensor_type = OV_OV5647_MIPI_CSI0_1920X1080_30FPS_10BIT_LINEAR; + kd_mpi_vicap_set_mclk(VICAP_MCLK0, VICAP_PLL0_CLK_DIV4, 16, 1); +#else + sensor_type = IMX335_MIPI_2LANE_RAW12_2592X1944_30FPS_LINEAR; +#endif + vicap_dev = VICAP_DEV_ID_0; + + memset(&config, 0, sizeof(config)); + config.max_pool_cnt = 64; + //VB for YUV420SP output + config.comm_pool[0].blk_cnt = 5; + config.comm_pool[0].mode = VB_REMAP_MODE_NOCACHE; + config.comm_pool[0].blk_size = VICAP_ALIGN_UP((ISP_CHN0_WIDTH * ISP_CHN0_HEIGHT * 3 / 2), VICAP_ALIGN_1K); + + //VB for RGB888 output + config.comm_pool[1].blk_cnt = 5; + config.comm_pool[1].mode = VB_REMAP_MODE_NOCACHE; + config.comm_pool[1].blk_size = VICAP_ALIGN_UP((SENSOR_HEIGHT * SENSOR_WIDTH * 3 ), VICAP_ALIGN_1K); + + ret = kd_mpi_vb_set_config(&config); + if (ret) { + printf("vb_set_config failed ret:%d\n", ret); + return ret; + } + + k_vb_supplement_config supplement_config; + memset(&supplement_config, 0, sizeof(supplement_config)); + supplement_config.supplement_config |= VB_SUPPLEMENT_JPEG_MASK; + + ret = kd_mpi_vb_set_supplement_config(&supplement_config); + if (ret) { + printf("vb_set_supplement_config failed ret:%d\n", ret); + return ret; + } + + ret = kd_mpi_vb_init(); + if (ret) { + printf("vb_init failed ret:%d\n", ret); + return ret; + } + printf("sample_vicap ...kd_mpi_vicap_get_sensor_info\n"); + + // dwc_dsi_init(); + vo_layer_vdss_bind_vo_config(); + + if(vicap_install_osd == 1) + { + memset(&pool_config, 0, sizeof(pool_config)); + pool_config.blk_size = VICAP_ALIGN_UP((osd_width * osd_height * 4 * 2), VICAP_ALIGN_1K); + pool_config.blk_cnt = 4; + pool_config.mode = VB_REMAP_MODE_NOCACHE; + pool_id = kd_mpi_vb_create_pool(&pool_config); // osd0 - 3 argb 320 x 240 + g_pool_id = pool_id; + + printf("--------aa--------------g_pool_id is %d pool_id is %d \n",g_pool_id, pool_id); + } + + memset(&sensor_info, 0, sizeof(k_vicap_sensor_info)); + ret = kd_mpi_vicap_get_sensor_info(sensor_type, &sensor_info); + if (ret) { + printf("sample_vicap, the sensor type not supported!\n"); + return ret; + } + + memset(&dev_attr, 0, sizeof(k_vicap_dev_attr)); + dev_attr.acq_win.h_start = 0; + dev_attr.acq_win.v_start = 0; +#if defined (CONFIG_BOARD_K230_CANMV) + dev_attr.acq_win.width = ISP_CHN0_WIDTH; + dev_attr.acq_win.height = ISP_CHN0_HEIGHT; +#else + dev_attr.acq_win.width = 2592;//SENSOR_HEIGHT; + dev_attr.acq_win.height = 1944;//SENSOR_WIDTH; +#endif + dev_attr.mode = VICAP_WORK_ONLINE_MODE; + + dev_attr.pipe_ctrl.data = 0xFFFFFFFF; + dev_attr.pipe_ctrl.bits.af_enable = 0; + dev_attr.pipe_ctrl.bits.ahdr_enable = 0; + + + dev_attr.cpature_frame = 0; + memcpy(&dev_attr.sensor_info, &sensor_info, sizeof(k_vicap_sensor_info)); + + ret = kd_mpi_vicap_set_dev_attr(vicap_dev, dev_attr); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_set_dev_attr failed.\n"); + return ret; + } + + memset(&chn_attr, 0, sizeof(k_vicap_chn_attr)); + + //set chn0 output yuv420sp + chn_attr.out_win.h_start = 0; + chn_attr.out_win.v_start = 0; + chn_attr.out_win.width = ISP_CHN0_WIDTH; + chn_attr.out_win.height = ISP_CHN0_HEIGHT; + + +#if defined(CONFIG_BOARD_K230_CANMV) + chn_attr.crop_win = dev_attr.acq_win; +#else + // chn_attr.crop_win = dev_attr.acq_win; + chn_attr.crop_win.h_start = 768; + chn_attr.crop_win.v_start = 16; + chn_attr.crop_win.width = ISP_CHN0_WIDTH; + chn_attr.crop_win.height = ISP_CHN0_HEIGHT; +#endif + + chn_attr.scale_win = chn_attr.out_win; + chn_attr.crop_enable = K_FALSE; + chn_attr.scale_enable = K_FALSE; + // chn_attr.dw_enable = K_FALSE; + chn_attr.chn_enable = K_TRUE; + chn_attr.pix_format = PIXEL_FORMAT_YVU_PLANAR_420; + chn_attr.buffer_num = VICAP_MAX_FRAME_COUNT;//at least 3 buffers for isp + chn_attr.buffer_size = config.comm_pool[0].blk_size; + vicap_chn = VICAP_CHN_ID_0; + + printf("sample_vicap ...kd_mpi_vicap_set_chn_attr, buffer_size[%d]\n", chn_attr.buffer_size); + ret = kd_mpi_vicap_set_chn_attr(vicap_dev, vicap_chn, chn_attr); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_set_chn_attr failed.\n"); + return ret; + } + + //bind vicap chn 0 to vo + vicap_mpp_chn.mod_id = K_ID_VI; + vicap_mpp_chn.dev_id = vicap_dev; + vicap_mpp_chn.chn_id = vicap_chn; + + vo_mpp_chn.mod_id = K_ID_VO; + vo_mpp_chn.dev_id = K_VO_DISPLAY_DEV_ID; + vo_mpp_chn.chn_id = K_VO_DISPLAY_CHN_ID1; + + sample_vicap_bind_vo(vicap_mpp_chn, vo_mpp_chn); + printf("sample_vicap ...dwc_dsi_init\n"); + + //set chn1 output rgb888p + chn_attr.out_win.h_start = 0; + chn_attr.out_win.v_start = 0; + chn_attr.out_win.width = SENSOR_WIDTH ; + chn_attr.out_win.height = SENSOR_HEIGHT; + // chn_attr.crop_win = dev_attr.acq_win; + +#if defined(CONFIG_BOARD_K230_CANMV) + chn_attr.crop_win = dev_attr.acq_win; +#else + chn_attr.crop_win.h_start = 768; + chn_attr.crop_win.v_start = 16; + chn_attr.crop_win.width = ISP_CHN0_WIDTH; + chn_attr.crop_win.height = ISP_CHN0_HEIGHT; +#endif + + chn_attr.scale_win = chn_attr.out_win; + chn_attr.crop_enable = K_FALSE; + chn_attr.scale_enable = K_FALSE; + // chn_attr.dw_enable = K_FALSE; + chn_attr.chn_enable = K_TRUE; + chn_attr.pix_format = PIXEL_FORMAT_BGR_888_PLANAR; + chn_attr.buffer_num = VICAP_MAX_FRAME_COUNT;//at least 3 buffers for isp + chn_attr.buffer_size = config.comm_pool[1].blk_size; + + printf("sample_vicap ...kd_mpi_vicap_set_chn_attr, buffer_size[%d]\n", chn_attr.buffer_size); + ret = kd_mpi_vicap_set_chn_attr(vicap_dev, VICAP_CHN_ID_1, chn_attr); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_set_chn_attr failed.\n"); + return ret; + } + + printf("sample_vicap ...kd_mpi_vicap_init\n"); + ret = kd_mpi_vicap_init(vicap_dev); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_init failed.\n"); + // goto err_exit; + } + + printf("sample_vicap ...kd_mpi_vicap_start_stream\n"); + ret = kd_mpi_vicap_start_stream(vicap_dev); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_init failed.\n"); + // goto err_exit; + } + + return ret; +} + +int vivcap_stop() +{ + printf("sample_vicap ...kd_mpi_vicap_stop_stream\n"); + int ret = kd_mpi_vicap_stop_stream(vicap_dev); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_init failed.\n"); + return ret; + } + + ret = kd_mpi_vicap_deinit(vicap_dev); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_deinit failed.\n"); + return ret; + } + + kd_mpi_vo_disable_video_layer(K_VO_LAYER1); + + vicap_mpp_chn.mod_id = K_ID_VI; + vicap_mpp_chn.dev_id = vicap_dev; + vicap_mpp_chn.chn_id = vicap_chn; + + vo_mpp_chn.mod_id = K_ID_VO; + vo_mpp_chn.dev_id = K_VO_DISPLAY_DEV_ID; + vo_mpp_chn.chn_id = K_VO_DISPLAY_CHN_ID1; + + sample_vicap_unbind_vo(vicap_mpp_chn, vo_mpp_chn); + + /*Allow one frame time for the VO to release the VB block*/ + k_u32 display_ms = 1000 / 33; + usleep(1000 * display_ms); + + ret = kd_mpi_vb_exit(); + if (ret) { + printf("sample_vicap, kd_mpi_vb_exit failed.\n"); + return ret; + } + + return 0; +} + +void yuv_rotate_90(char *des, char *src,int width,int height) +{ + int n = 0; + int hw = width>>1; + int hh = height>>1; + int size = width * height; + int hsize = size>>2; + + int pos = 0; + + for(int i = width-1;i >= 0;i--) + { + pos = 0; + for(int j= 0;j < height;j++) + { + des[n++]= src[pos+i]; + pos += width; + } + } + +} \ No newline at end of file diff --git a/src/reference/business_poc/dictionary_pen_poc/CMakeLists.txt b/src/reference/business_poc/dictionary_pen_poc/CMakeLists.txt new file mode 100644 index 000000000..7290eabd2 --- /dev/null +++ b/src/reference/business_poc/dictionary_pen_poc/CMakeLists.txt @@ -0,0 +1,96 @@ +cmake_minimum_required(VERSION 3.2) +set(SRC main.cpp vo/vo.cc audio/audio_buf_play.cc) + +set(CMAKE_CXX_STANDARD 17) +set(bin dictionary_pen.elf) + +set(nncase_sdk_root "${PROJECT_SOURCE_DIR}/../../../big/nncase") +set(k230_sdk ${nncase_sdk_root}/../../../) + +set(CMAKE_EXE_LINKER_FLAGS "-T ${nncase_sdk_root}/examples/cmake/link.lds --static") + + +#riscv64交叉编译 +include_directories(${k230_sdk}/src/big/utils/lib/opencv/include/opencv4) +include_directories(${k230_sdk}/src/big/utils/lib/freetype/include/freetype2) +#include_directories(${k230_sdk}/src/big/nncase/riscv64/sentencepiece/include/) +include_directories(${k230_sdk}/src/big/nncase/riscv64/) +include_directories(${k230_sdk}/src/big/nncase/riscv64/nncase/include/) + +#sentencepiece +include_directories(${k230_sdk}/src/big/utils/lib/sentencepiece/include/) + + +link_directories(${k230_sdk}/src/big/utils/lib/opencv/lib) +link_directories(${k230_sdk}/src/big/utils/lib/opencv/lib/opencv4/3rdparty) +link_directories(${k230_sdk}/src/big/utils/lib/freetype/lib) +#link_directories(${k230_sdk}/src/big/nncase/riscv64/sentencepiece/lib/) +include_directories(${k230_sdk}/src/big/nncase/riscv64/nncase/include/nncase/runtime) +link_directories(${k230_sdk}/src/big/nncase/riscv64/nncase/lib/) + +#sentencepiece +link_directories(${k230_sdk}/src/big/utils/lib/sentencepiece/lib) + + +#add vo audio mapi and include +include_directories(${k230_sdk}/src/big/mpp/userapps/api/) +include_directories(${k230_sdk}/src/big/mpp/include) +include_directories(${k230_sdk}/src/big/mpp/include/comm) +include_directories(./) +include_directories(./audio) +include_directories(./vo) +include_directories(./vicap) + +## set mmz +link_directories(${k230_sdk}/src/big/mpp/userapps/lib) + +#添加openblas库 +link_directories(${k230_sdk}/src/big/utils/lib/openblas/lib/) +include_directories(${k230_sdk}/src/big/utils/lib/openblas/include/) + + + #imagestitch +include_directories(./include/stitch/include) + +add_library(stitch STATIC ./include/stitch/src/stitch.cpp) +target_link_libraries(stitch opencv_imgcodecs opencv_imgproc opencv_core libjpeg-turbo libopenjp2 libpng libtiff libwebp zlib csi_cv) + +# ocr +include_directories(./include/det_ocr/include) +#link_directories(./det_ocr/lib/) +add_library(detocr STATIC ./include/det_ocr/src/clipper.cpp ./include/det_ocr/src/det_util.cpp ./include/det_ocr/src/det_ocr.cpp) +target_link_libraries(detocr nncase.rt_modules.k230 Nncase.Runtime.Native opencv_imgcodecs opencv_imgproc opencv_core libjpeg-turbo libopenjp2 libpng libtiff libwebp zlib csi_cv) + + +include_directories(./include/) +#tts +include_directories(./include/tts/src) +include_directories(./include/tts/paddlespeech_zhfrontend) +include_directories(./include/tts/paddlespeech_zhfrontend/pypinyin) +include_directories(./include/tts/paddlespeech_zhfrontend/zh_normalization) +INCLUDE_DIRECTORIES(./include/tts/paddlespeech_zhfrontend/cppjieba/include +./include/tts/paddlespeech_zhfrontend/cppjieba/deps/limonp/include) +INCLUDE_DIRECTORIES(./include/tts/g2p_en) +INCLUDE_DIRECTORIES(./include/tts/g2p_en/nltk) +# +# +ADD_SUBDIRECTORY(./include/tts/paddlespeech_zhfrontend) +ADD_SUBDIRECTORY(./include/tts/g2p_en) + +include_directories(./include/API) +aux_source_directory(./include/tts/src DIR_SRCS) +aux_source_directory(./include/API DIR_APIS) +add_executable(${bin} ${SRC} ${DIR_SRCS} ${DIR_APIS}) + +# +target_link_libraries(${bin} -Wl,--start-group stitch detocr zh_frontend_lib g2p_en_lib openblas nncase.rt_modules.k230 Nncase.Runtime.Native functional_k230 pthread m sys sentencepiece vo connector ai ao aenc adec vb freetype vicap cam_device cam_engine hal oslayer ebase fpga isp_drv binder auto_ctrol common cam_caldb isi 3a buffer_management cameric_drv video_in virtual_hal start_engine cmd_buffer switch cameric_reg_drv t_database_c t_mxml_c t_json_c t_common_c sensor -Wl,--end-group ) + +#install(TARGETS ${bin} DESTINATION out) + + + + + + + + diff --git a/src/reference/business_poc/dictionary_pen_poc/README.md b/src/reference/business_poc/dictionary_pen_poc/README.md new file mode 100644 index 000000000..169c290f3 --- /dev/null +++ b/src/reference/business_poc/dictionary_pen_poc/README.md @@ -0,0 +1,58 @@ +## 简介 + +词典笔项目接口,具体接口见文档:https://cf.b-bug.org/pages/viewpage.action?pageId=108174084 + +## 运行 +根据不同操作可修改main.cpp +根据sdk路径修改CMakeList.txt中的DEMO_ROOT + +``` +bash build.sh +``` + +### 拼接 + +``` +#include "stitch_api.hpp" +stitch_api("./testdata/Fri_Mar_24_00_47_10_2023_","./result_stitch.jpg"); +``` + +### OCR + +``` +#include "ocr_api.h" +ocr_api ocr_api; +ocr_api.ocr("./result_stitch.jpg","./result_ocr.txt"); +``` + +### TTS + +``` +#include "tts_api.h" +string audio_name = "audio.wav"; +tts_api tts_api; +tts_api.tts("good morning !", audio_name); +``` + +### NMT + +``` +#include "nmt_api.h" +nmt_api nmt_api; +//英翻中为false,中翻英为true +nmt_api.nmt("good morning !","result_nmt.txt",false); +``` + +### pipeline + +``` +#include "stitch_api.hpp" +#include "ocr_api.h" +#include "tts_api.h" +#include "nmt_api.h" + +cidianbi_pipeline("./testdata/Fri_Mar_24_00_47_10_2023_","audio.wav"); +``` + +git lfs fetch +git lfs pull \ No newline at end of file diff --git a/src/reference/business_poc/dictionary_pen_poc/audio/audio_buf_play.cc b/src/reference/business_poc/dictionary_pen_poc/audio/audio_buf_play.cc new file mode 100755 index 000000000..d4bc01dc1 --- /dev/null +++ b/src/reference/business_poc/dictionary_pen_poc/audio/audio_buf_play.cc @@ -0,0 +1,194 @@ +#include "audio_buf_play.h" +#include +#include +#include +#include +#include "k_vb_comm.h" +#include "k_sys_comm.h" +#include "mpi_vb_api.h" +#include "mpi_sys_api.h" +#include "mpi_ao_api.h" + +/* According to earlier standards */ +#include +#include +#include +#include +#include + +#define AUDIO_PERSEC_DIV_NUM 25 + +static k_vb_blk_handle g_audio_handle; +static k_s32 _get_audio_frame(k_audio_frame *audio_frame, int nSize) +{ + g_audio_handle = kd_mpi_vb_get_block(VB_INVALID_POOLID, nSize, NULL); + if (g_audio_handle == VB_INVALID_HANDLE) + { + printf("%s get vb block error\n", __func__); + return K_FAILED; + } + audio_frame->len = nSize; + audio_frame->pool_id = kd_mpi_vb_handle_to_pool_id(g_audio_handle); + audio_frame->phys_addr = kd_mpi_vb_handle_to_phyaddr(g_audio_handle); + audio_frame->virt_addr = kd_mpi_sys_mmap(audio_frame->phys_addr, nSize); + printf("=======_get_audio_frame virt_addr:%p\n", audio_frame->virt_addr); + + return K_SUCCESS; +} + +static k_s32 _release_audio_frame() +{ + kd_mpi_vb_release_block(g_audio_handle); + return K_SUCCESS; +} + +// static k_bool g_vb_init = K_FALSE; +// k_s32 audio_buffer_sample_vb_init(k_bool enable_cache, k_u32 sample_rate) +// { +// if (g_vb_init) +// { +// return K_SUCCESS; +// } +// k_s32 ret; +// k_vb_config config; + +// memset(&config, 0, sizeof(config)); +// config.max_pool_cnt = 64; + +// config.comm_pool[0].blk_cnt = 50; +// config.comm_pool[0].blk_size = sample_rate * 2 * 4 / AUDIO_PERSEC_DIV_NUM; +// config.comm_pool[0].mode = enable_cache ? VB_REMAP_MODE_CACHED : VB_REMAP_MODE_NOCACHE; + +// config.comm_pool[1].blk_cnt = 2; +// config.comm_pool[1].blk_size = sample_rate * 2 * 4 / AUDIO_PERSEC_DIV_NUM * 2; // ao use +// config.comm_pool[1].mode = enable_cache ? VB_REMAP_MODE_CACHED : VB_REMAP_MODE_NOCACHE; + +// int blk_total_size = 0; +// for (int i = 0; i < 2; i++) +// { +// blk_total_size += config.comm_pool[i].blk_cnt * config.comm_pool[i].blk_size; +// } +// printf("mmz blk total size:%.2f MB\n", blk_total_size / 1024 / 1024.0); + +// ret = kd_mpi_vb_set_config(&config); +// if (ret) +// { +// printf("vb_set_config failed ret:%d\n", ret); +// return ret; +// } +// else +// { +// printf("vb_set_config ok\n"); +// } + +// ret = kd_mpi_vb_init(); + +// if (ret) +// printf("vb_init failed ret:%d\n", ret); +// else +// g_vb_init = K_TRUE; + +// return ret; +// } + +k_s32 audio_buffer_sample_vb_destroy() +{ + // if (!g_vb_init) + // { + // return K_FAILED; + // } + // g_vb_init = K_FALSE; + + k_s32 ret; + ret = kd_mpi_vb_exit(); + if (ret) + printf("vb_exit failed ret:%d\n", ret); + return ret; +} + +static k_audio_frame g_play_audio_frame; +static k_u32 g_channel_count; +static k_u32 g_sample_rate; + +k_s32 audio_buffer_play_init(k_u32 sample_rate,k_u32 channel_count) +{ + + _get_audio_frame(&g_play_audio_frame, sample_rate * 2 * 2 / AUDIO_PERSEC_DIV_NUM); + g_channel_count = channel_count; + g_sample_rate = sample_rate; + + k_aio_dev_attr ao_dev_attr; + ao_dev_attr.audio_type = KD_AUDIO_OUTPUT_TYPE_I2S; + ao_dev_attr.kd_audio_attr.i2s_attr.sample_rate = sample_rate; + ao_dev_attr.kd_audio_attr.i2s_attr.bit_width = KD_AUDIO_BIT_WIDTH_16; + ao_dev_attr.kd_audio_attr.i2s_attr.chn_cnt = 2; + ao_dev_attr.kd_audio_attr.i2s_attr.i2s_mode = K_STANDARD_MODE; + ao_dev_attr.kd_audio_attr.i2s_attr.snd_mode = (1 == channel_count) ? KD_AUDIO_SOUND_MODE_MONO : KD_AUDIO_SOUND_MODE_STEREO; + ao_dev_attr.kd_audio_attr.i2s_attr.frame_num = AUDIO_PERSEC_DIV_NUM; + ao_dev_attr.kd_audio_attr.i2s_attr.point_num_per_frame = ao_dev_attr.kd_audio_attr.i2s_attr.sample_rate / ao_dev_attr.kd_audio_attr.i2s_attr.frame_num; + ao_dev_attr.kd_audio_attr.i2s_attr.i2s_type = K_AIO_I2STYPE_INNERCODEC; + + kd_mpi_ao_set_pub_attr(0, &ao_dev_attr); + + kd_mpi_ao_enable(0); + kd_mpi_ao_enable_chn(0, 0); + + return 0; +} + +k_s32 audio_buffer_play(k_u8 *pdata, k_u32 data_len) +{ + k_u8 *pDataBuf = (k_u8 *)g_play_audio_frame.virt_addr; + int frame_size = g_sample_rate*g_channel_count*2/AUDIO_PERSEC_DIV_NUM;//16 bit + g_play_audio_frame.len = frame_size; + int frame_count = data_len / frame_size; + for (int i=0;i < frame_count; i ++) + { + memcpy(pDataBuf,pdata+i*frame_size,frame_size); + if (0 != kd_mpi_ao_send_frame(0, 0, &g_play_audio_frame, 1000)) + { + printf("kd_mpi_ao_send_frame failed\n"); + return -1; + } + } + + return 0; +} + +k_s32 audio_buffer_play_deinit() +{ + kd_mpi_ao_disable_chn(0, 0); + kd_mpi_ao_disable(0); + _release_audio_frame(); + return 0; +} + + + +#define WAV_HEAD_SIZE 44 +void audio_test_file(void) +{ + unsigned char *pcm_file_data = NULL; + FILE *fp = fopen("audio_test.wav", "rb"); + if (NULL == fp) + { + printf("open file:%s failed\n", "audio.wav"); + return ; + } + + fseek(fp, 0, SEEK_END); + int size = ftell(fp); + pcm_file_data = (unsigned char *)malloc(size); + if (pcm_file_data == NULL) + { + printf("malloc size %d failed\n", size); + return ; + } + + fseek(fp, 0, SEEK_SET); + fread(pcm_file_data, size, 1, fp); + fclose(fp); + + + audio_buffer_play(pcm_file_data+WAV_HEAD_SIZE,size-WAV_HEAD_SIZE); +} \ No newline at end of file diff --git a/src/reference/business_poc/dictionary_pen_poc/audio/audio_buf_play.h b/src/reference/business_poc/dictionary_pen_poc/audio/audio_buf_play.h new file mode 100755 index 000000000..0467e29b5 --- /dev/null +++ b/src/reference/business_poc/dictionary_pen_poc/audio/audio_buf_play.h @@ -0,0 +1,46 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __AUDIO_PLAY_BUFFER_H__ +#define __AUDIO_PLAY_BUFFER_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* end of #ifdef __cplusplus */ + +#include "k_type.h" + +// k_s32 audio_buffer_sample_vb_init(k_bool enable_cache, k_u32 sample_rate); //初始化vb +k_s32 audio_buffer_sample_vb_destroy(); //销毁vb + +k_s32 audio_buffer_play_init(k_u32 sample_rate,k_u32 channel_count); +k_s32 audio_buffer_play(k_u8 *pdata, k_u32 data_len); +k_s32 audio_buffer_play_deinit(); +void audio_test_file(void); + +#ifdef __cplusplus +} +#endif /* end of #ifdef __cplusplus */ + +#endif \ No newline at end of file diff --git a/src/reference/business_poc/dictionary_pen_poc/audio/sample_audio.c b/src/reference/business_poc/dictionary_pen_poc/audio/sample_audio.c new file mode 100755 index 000000000..11ba0c208 --- /dev/null +++ b/src/reference/business_poc/dictionary_pen_poc/audio/sample_audio.c @@ -0,0 +1,55 @@ +#include "audio_buf_play.h" +#include +#include +#include +#include + +#define WAV_HEAD_SIZE 44 +static void test_play_audio_buffer() +{ + unsigned char *pcm_file_data = NULL; + FILE *fp = fopen("audio.wav", "rb"); + if (NULL == fp) + { + printf("open file:%s failed\n", "audio.wav"); + return ; + } + + fseek(fp, 0, SEEK_END); + int size = ftell(fp); + pcm_file_data = (unsigned char *)malloc(size); + if (pcm_file_data == NULL) + { + printf("malloc size %d failed\n", size); + return ; + } + + fseek(fp, 0, SEEK_SET); + fread(pcm_file_data, size, 1, fp); + fclose(fp); + + + audio_buffer_play(pcm_file_data+WAV_HEAD_SIZE,size-WAV_HEAD_SIZE); +} + +int main(int argc, char *argv[]) +{ + //init + audio_buffer_sample_vb_init(K_TRUE,48000); + audio_buffer_play_init(16000,1); + + //play + for (int i =0;i < 3;i ++) + { + test_play_audio_buffer(); + } + + //deinit + printf("deinit ...\n"); + sleep(1); + audio_buffer_play_deinit(); + audio_buffer_sample_vb_destroy(); + + + return 0; +} \ No newline at end of file diff --git a/src/reference/business_poc/dictionary_pen_poc/build.sh b/src/reference/business_poc/dictionary_pen_poc/build.sh new file mode 100755 index 000000000..216f32857 --- /dev/null +++ b/src/reference/business_poc/dictionary_pen_poc/build.sh @@ -0,0 +1,20 @@ +#!/bin/bash +### 7.4.0 +#export PATH=$PATH:/data/zhanglimin/code_kmodel_export_build_inference/AndeSight_STD_v323/toolchains/nds64le-linux-glibc-v5d/bin +### 7.3.0 +export PATH=$PATH:../../../../toolchain/riscv64-linux-musleabi_for_x86_64-pc-linux-gnu/bin/ +rm -rf build +mkdir build +pushd build +cmake -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=`pwd` \ + -DCMAKE_TOOLCHAIN_FILE=../../../../src/big/nncase/examples/cmake/Riscv64.cmake \ + .. + +#make -j && make install +make -j + + + +popd + diff --git a/src/reference/business_poc/dictionary_pen_poc/main.cpp b/src/reference/business_poc/dictionary_pen_poc/main.cpp new file mode 100644 index 000000000..942e876f2 --- /dev/null +++ b/src/reference/business_poc/dictionary_pen_poc/main.cpp @@ -0,0 +1,517 @@ +#include "tts_api.h" +#include "stitch_api.hpp" +#include "ocr_api.h" + +#include "nmt_api.h" +#include "CvxText.h" +#include "stitch.h" + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "sys/ioctl.h" +#include +#include "stdio.h" +#include "k_autoconf_comm.h" + +#include "vo.h" +#include "audio_buf_play.h" + +#include + + +using namespace std; + +// .ocr_api ./image_path ./det_kmodel ./ocr_kmodel ./dict_path ./result_path +// ./stitch ./test_data_dir ./result_path + +// osd_cidianbi.plane cidianbi.plane; + +cidianbi_attr cidianbi; +Mat stich_picture; +k_video_frame_info dump_info; +k_video_frame_info release_info; + +queue video_frame; + + +bool app_run = true; + +ocr_api ocr_api; +tts_api tts_api; +nmt_api nmt_api; + +static k_s32 sample_vb_init(k_bool enable_cache, k_u32 sample_rate) +{ + + k_s32 ret; + k_vb_config config; + k_vb_pool_config pool_config; + k_u32 pool_id; + + memset(&config, 0, sizeof(config)); + config.max_pool_cnt = 64; + + config.comm_pool[1].blk_cnt = 150; + config.comm_pool[1].blk_size = sample_rate * 2 * 4 ;// AUDIO_PERSEC_DIV_NUM; + config.comm_pool[1].mode = enable_cache ? VB_REMAP_MODE_CACHED : VB_REMAP_MODE_NOCACHE; + + config.comm_pool[2].blk_cnt = 2; + config.comm_pool[2].blk_size = sample_rate * 2 * 4 ;//AUDIO_PERSEC_DIV_NUM * 2; // ao use + config.comm_pool[2].mode = enable_cache ? VB_REMAP_MODE_CACHED : VB_REMAP_MODE_NOCACHE; + + //VB for YUV420SP output + config.comm_pool[3].blk_cnt = VICAP_MAX_FRAME_COUNT; + config.comm_pool[3].mode = VB_REMAP_MODE_NOCACHE; + config.comm_pool[3].blk_size = VICAP_ALIGN_UP((ISP_CHN0_WIDTH * ISP_CHN0_HEIGHT * 3 / 2), VICAP_ALIGN_1K); + + config.comm_pool[0].blk_cnt = PRIVATE_POLL_NUM; + config.comm_pool[0].blk_size = PRIVATE_POLL_SZE; + config.comm_pool[0].mode = VB_REMAP_MODE_NOCACHE; + + int blk_total_size = 0; + for (int i = 0; i < 3; i++) + { + blk_total_size += config.comm_pool[i].blk_cnt * config.comm_pool[i].blk_size; + } + printf("mmz blk total size:%.2f MB\n", blk_total_size / 1024 / 1024.0); + + ret = kd_mpi_vb_set_config(&config); + if (ret) + { + printf("vb_set_config failed ret:%d\n", ret); + return ret; + } + else + { + printf("vb_set_config ok\n"); + } + + ret = kd_mpi_vb_init(); + + if (ret) + printf("vb_init failed ret:%d\n", ret); + + memset(&pool_config, 0, sizeof(pool_config)); + pool_config.blk_cnt = PRIVATE_POLL_NUM; + pool_config.blk_size = PRIVATE_POLL_SZE; + pool_config.mode = VB_REMAP_MODE_NONE; + pool_id = kd_mpi_vb_create_pool(&pool_config); // osd0 - 3 argb 320 x 240 + cidianbi.plane.g_pool_id = pool_id; + + printf("cidianbi.plane.g_pool_id is %d \n", cidianbi.plane.g_pool_id); + + return ret; +} + +static void sample_display_init(k_vo_osd chn) +{ + osd_info osd; + k_vo_osd osd_id = chn; + + osd.act_size.width = 1080 ; + osd.act_size.height = 480; + osd.offset.x = 0; + osd.offset.y = 800; + osd.global_alptha = 0xff; + osd.format = PIXEL_FORMAT_ARGB_8888;//PIXEL_FORMAT_ARGB_4444; //PIXEL_FORMAT_ARGB_1555;//PIXEL_FORMAT_ARGB_8888; + + memcpy(&cidianbi.plane.osd, &osd, sizeof(osd)); + + sample_connector_init(HX8377_V2_MIPI_4LAN_1080X1920_30FPS); + + // sample_vo_creat_private_poll(); + // config osd + sample_vo_creat_osd(osd_id, &osd); + +#if VICAP_VO_TESET + sample_vo_layer_config(); +#endif + +} + +static void *exit_app(void *arg) +{ + printf("press 'q' to exit application!!\n"); + while(getchar() != 'q') + { + usleep(10000); + if(app_run == false) + break; + } + app_run = false; + printf("exit_app start exit \n"); + return NULL; +} + +static bool key_status = 0; +static void *gpio_app(void *arg) +{ + pin_mode_t key0; + pin_mode_t key1; + pin_mode_t led0; + pin_mode_t led1; + int val0, val1; + int gpio_fd = -1; + key0.pin = KEY_PIN_NUM1; + key1.pin = KEY_PIN_NUM2; + + led0.pin = LED_PIN_NUM1; + led1.pin = LED_PIN_NUM2; + + cidianbi.key_val = 0; + + gpio_fd = sample_gpio_init(); + ioctl(gpio_fd, GPIO_WRITE_LOW, &led0); + ioctl(gpio_fd, GPIO_WRITE_LOW, &led1); + + while(app_run) + { + + ioctl(gpio_fd, GPIO_READ_VALUE, &key0); + ioctl(gpio_fd, GPIO_READ_VALUE, &key1); + val0 = key0.mode; + val1 = key1.mode; + if(!key_status) + { + if (!val0 || !val1) //任意键按下皆可开灯 + { + ioctl(gpio_fd, GPIO_WRITE_HIGH, &led0); + ioctl(gpio_fd, GPIO_WRITE_HIGH, &led1); + key_status = 1; + pthread_mutex_lock(&cidianbi.mutex_key); + cidianbi.key_val = 1; + pthread_mutex_unlock(&cidianbi.mutex_key); + } + } + else + { + if (val0 && val1) //两键同时松开才关灯 + { + ioctl(gpio_fd, GPIO_WRITE_LOW, &led0); + ioctl(gpio_fd, GPIO_WRITE_LOW, &led1); + key_status = 0; + pthread_mutex_lock(&cidianbi.mutex_key); + cidianbi.key_val = 0; + pthread_mutex_unlock(&cidianbi.mutex_key); + } + } + usleep(10 * 1000); //delay 10ms + } + + cidianbi.exit_flag = cidianbi.exit_flag | (1 << 0); + + printf("gpio thread exit success cidianbi.exit_flag is %x \n", cidianbi.exit_flag); + + return NULL; +} + +static bool is_vicap_open(void) +{ + int ret = 0; + + ret = kd_mpi_vicap_dump_frame(cidianbi.vicap_dev, VICAP_CHN_ID_0, VICAP_DUMP_YUV, &dump_info, 1000); + if (ret) { + printf("sample_vicap...kd_mpi_vicap_dump_frame failed.\n"); + sample_vivcap_deinit(); + return 0; + } + + ret = kd_mpi_vicap_dump_release(cidianbi.vicap_dev, VICAP_CHN_ID_0, &dump_info); + if (ret) { + printf("sample_vicap...kd_mpi_vicap_dump_release failed.\n"); + } + + return 1; +} + +static void *sample_vicap_dump_picture(void *arg) +{ + int ret; + int save_picture_flag = 0; + size_t size = ISP_CHN0_WIDTH * ISP_CHN0_HEIGHT * 3 / 2; + int is_switch = 0; + bool is_open = 0; + + // stith picture + Mat current_image_grey;//读当前图片 + Mat left_image_history;//初始化,用于中间结果 + + /// 定义变量 // 当前帧的图像路 // 累计拼接图像 + int last_right_start_x = 0; // 记录上一次拼接时,右图在累计拼接图像中的起始坐标(左上角的x坐标) 参数3 + int last_right_start_y = 0; // 记录上一次拼接时,右图在累计拼接图像中的起始坐标(左上角的y坐标) 参数4 + int round = 0; // 处理的第几帧图像 + int flag_start = 0; // 是否开始进行拼接 + int flag_stop = 0; // 是否停止拼接 // 历史待匹配的左图 + string debug_save_prefix; + /// 定长输出相关的变量 + int interval_length = 0;//默认为0 + //int interval_length = 0; // 当拼接图像的长度大于该值,则输出拼接图像,并重新开始拼接。设为<0时,为非定长输出。 + // int interval_length = 200; // 当拼接图像的长度大于该值,则输出拼接图像,并重新开始拼接。设为<0时,为非定长输出。 + int interval_flag_save = 0; + Mat image_stitch;//初始化,用于最终结果 + + sample_vivcap_init(); + + int i = 0; + for(i = 0; i < 3; i++) + { + is_open = is_vicap_open(); + if(is_open == 0) + sample_vivcap_init(); + else + break; + } + + while(app_run) + { + pthread_mutex_lock(&cidianbi.mutex_key); + int curt_val = cidianbi.key_val; + if((save_picture_flag == 1) && (curt_val == 0)) + { + is_switch = 1; + } + save_picture_flag = cidianbi.key_val; + pthread_mutex_unlock(&cidianbi.mutex_key); + if(save_picture_flag == 1) + { + memset(&dump_info, 0 , sizeof(k_video_frame_info)); + ret = kd_mpi_vicap_dump_frame(cidianbi.vicap_dev, VICAP_CHN_ID_0, VICAP_DUMP_YUV, &dump_info, 1000); + if (ret) { + printf("sample_vicap...kd_mpi_vicap_dump_frame failed.\n"); + break; + } + // save picture + // video_frame.push(dump_info); +// printf("sample_vicap...kd_mpi_vicap_dump_frame success. video_frame deep is %d %x \n", video_frame.size(), dump_info.v_frame.phys_addr[0]); + + auto vbvaddr = kd_mpi_sys_mmap(dump_info.v_frame.phys_addr[0], size); + + current_image_grey = cv::Mat(ISP_CHN0_HEIGHT, ISP_CHN0_WIDTH, CV_8UC(1), vbvaddr); + if(current_image_grey.empty()){ + cout << "error: stitch input image is empty: " << endl; + continue; + } + stitch(current_image_grey, left_image_history, image_stitch, last_right_start_x, last_right_start_y, round, flag_start, flag_stop, debug_save_prefix, + interval_length, interval_flag_save); + + // imwrite("vicap_stitch.png", image_stitch); + + ret = kd_mpi_vicap_dump_release(cidianbi.vicap_dev, VICAP_CHN_ID_0, &dump_info); + if (ret) { + printf("sample_vicap...kd_mpi_vicap_dump_release failed.\n"); + } + kd_mpi_sys_munmap(vbvaddr, size); + + // release_info = video_frame.front(); + // memcpy(&release_info, &video_frame.front(), sizeof(release_info)); + // video_frame.pop(); + // auto vbvaddr = kd_mpi_sys_mmap(release_info.v_frame.phys_addr[0], size); + // kd_mpi_sys_munmap(vbvaddr, size); + + // printf("sample_vicap...kd_mpi_vicap_dump_release success. video_frame deep is %d release_info addr i %x \n", video_frame.size(), release_info.v_frame.phys_addr[0]); + // ret = kd_mpi_vicap_dump_release(cidianbi.vicap_dev, VICAP_CHN_ID_0, &release_info); + // if (ret) { + // printf("sample_vicap...kd_mpi_vicap_dump_release failed.\n"); + // } + } + else + { + if(is_switch == 1) + { + is_switch = 0; + // imwrite("over_vicap_stitch.png", image_stitch); // save picture + // printf("save picture success --------------------- \n"); + + pthread_mutex_lock(&cidianbi.stitch); + cidianbi.stitch_val = 1; + stich_picture = image_stitch.clone(); + pthread_mutex_unlock(&cidianbi.stitch); + + // imwrite("over2_vicap_stitch.png", image_stitch); // save picture S + + current_image_grey.release(); + left_image_history.release(); + image_stitch.release(); + debug_save_prefix.clear(); + last_right_start_x = 0; + last_right_start_y = 0; + round = 0; + flag_start = 0; + flag_stop = 0; + interval_length = 0; + interval_flag_save = 0; + } + usleep(10000); // delay 10ms + } + + } + + sample_vivcap_deinit(); +#if VICAP_VO_TESET + kd_mpi_vo_disable_video_layer(K_VO_LAYER1); +#endif + cidianbi.exit_flag = cidianbi.exit_flag | (1 << 1); + + printf("vicap_dump_picture thread exit success cidianbi.exit_flag is %x \n", cidianbi.exit_flag); + return NULL; +} + + +#define PICTURE_DIR "./testdata/Fri_Mar_24_00_47_10_2023_" + +static void *cidianbi_programming(void *arg) +{ + k_video_frame_info vf_info; + void *pic_vaddr = NULL; + k_vb_blk_handle block; + k_u8 *audio_pdata; + k_u32 audio_len; + string input_text; + string nmt_string; + Mat current_image_grey; + + //audio init + audio_buffer_play_init(16000, 1); + + // set frame + memset(&vf_info, 0, sizeof(vf_info)); + vf_info.v_frame.width = cidianbi.plane.osd.act_size.width; + vf_info.v_frame.height = cidianbi.plane.osd.act_size.height; + vf_info.v_frame.stride[0] = cidianbi.plane.osd.act_size.width; + vf_info.v_frame.pixel_format = cidianbi.plane.osd.format; + block = sample_vo_insert_frame(&vf_info, &pic_vaddr); + + printf("cidianbi_programming------------------inin success ----------- \n"); + while(app_run) + { + if(cidianbi.stitch_val == 1) + { + printf("cidianbi_programming----------------------------- \n"); + pthread_mutex_lock(&cidianbi.stitch); + cidianbi.stitch_val = 0; + pthread_mutex_unlock(&cidianbi.stitch); + + input_text.clear(); + nmt_string.clear(); + + // stitch_api(PICTURE_DIR,"./result_stitch.jpg"); + // current_image_grey = imread("./result_stitch.jpg", 0); + input_text = ocr_api.ocr_run(stich_picture); + + imwrite("ocr_stitch.png", stich_picture); // save picture + + std::vector audio_data; + bool flag = tts_api.tts_run(input_text, audio_data); + nmt_string = nmt_api.nmt_run(input_text,flag); + + sample_vo_filling_color(pic_vaddr, input_text, nmt_string, flag); + kd_mpi_vo_chn_insert_frame(cidianbi.chn + 3, &vf_info); //K_VO_OSD0 + + audio_pdata = (k_u8*)&audio_data[0]; + k_u32 audio_len = audio_data.size(); + audio_buffer_play(audio_pdata, audio_len); + sleep(1); + } + else + { + usleep(10000); + } + + } + + // close cidianbi.plane + kd_mpi_vo_osd_disable(cidianbi.chn); + audio_buffer_play_deinit(); + kd_mpi_vb_release_block(block); + kd_mpi_vb_destory_pool(cidianbi.plane.g_pool_id); + cidianbi.exit_flag = cidianbi.exit_flag | (2 << 1); + + printf("cidianbi_programming thread exit success cidianbi.exit_flag is %x \n", cidianbi.exit_flag); + + return NULL; +} + +void fun_sig(int sig) +{ + if(sig == SIGINT) + { + printf("recive ctrl+c\n"); + app_run = false; + // quit.store(false); + } +} + +int main(void) +{ + int ret = 0; + k_u32 g_max_sample_rate = 48000; + + printf("start add model \n"); + + memset(&cidianbi, 0, sizeof(cidianbi)); + memset(&cidianbi.plane, 0, sizeof(cidianbi.plane)); + + /****fixed operation for ctrl+c****/ + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = fun_sig; + sigfillset(&sa.sa_mask); + sigaction(SIGINT, &sa, NULL); + + //加载kmodel + ocr_api.load_model(); + tts_api.load_model(); + nmt_api.load_model(); + + cidianbi.chn = K_VO_OSD3; + cidianbi.exit_flag = 0; + //vb init + sample_vb_init(K_TRUE, g_max_sample_rate); + + pthread_t vo_thread_handle; + pthread_t exit_thread_handle; + pthread_t gpio_thread_handle; + pthread_t dump_picture_thread_handle; + pthread_t cidianbi_thread_handle; + pthread_t stitch_thread_handle; + + // init thread + pthread_mutex_init(&cidianbi.mutex_key, NULL); + pthread_mutex_init(&cidianbi.stitch, NULL); + + // display init + sample_display_init(cidianbi.chn); + + pthread_create(&exit_thread_handle, NULL, exit_app, NULL); + pthread_create(&gpio_thread_handle, NULL, gpio_app, NULL); // ext_flag = bit[0] = 1 0x1 + pthread_create(&dump_picture_thread_handle, NULL, sample_vicap_dump_picture, NULL); // ext_flag = bit[1] = 1 0x2 + pthread_create(&cidianbi_thread_handle, NULL, cidianbi_programming, NULL); // ext_flag = bit[2] = 1 0x4 + // pthread_create(&stitch_thread_handle, NULL, stitch_programming, NULL); // ext_flag = bit[3] = 1 0x8 + + while(cidianbi.exit_flag != 0x7) // 0x1 , 0x2, 0x4 + { + sleep(1); + } + + pthread_join(exit_thread_handle, NULL); + pthread_join(gpio_thread_handle, NULL); + pthread_join(dump_picture_thread_handle, NULL); + pthread_join(cidianbi_thread_handle, NULL); + // pthread_join(stitch_thread_handle, NULL); + + kd_mpi_vb_exit(); + + printf("exit success \n"); + + return 0; +} diff --git a/src/reference/business_poc/dictionary_pen_poc/vo/vo.cc b/src/reference/business_poc/dictionary_pen_poc/vo/vo.cc new file mode 100644 index 000000000..627261c77 --- /dev/null +++ b/src/reference/business_poc/dictionary_pen_poc/vo/vo.cc @@ -0,0 +1,525 @@ +#include "k_module.h" +#include "k_type.h" +#include "k_vb_comm.h" +#include "k_video_comm.h" +#include "k_sys_comm.h" +#include "mpi_vb_api.h" +#include "mpi_sys_api.h" +#include "mpi_vo_api.h" +#include "k_vo_comm.h" + +#include "stdio.h" +#include "string.h" +#include "stdlib.h" + + +#include "k_connector_comm.h" +#include "mpi_connector_api.h" +#include "vo.h" + +#include "opencv2/opencv.hpp" +#include "opencv2/core.hpp" +#include "opencv2/highgui.hpp" +#include "opencv2/imgcodecs.hpp" +#include "opencv2/imgproc.hpp" + +#include "CvxText.h" + + + +k_vicap_dev_attr dev_attr; +k_vicap_chn_attr chn_attr; +k_vicap_sensor_info sensor_info; +k_vicap_sensor_type sensor_type; + + +k_s32 sample_connector_init(k_connector_type type) +{ + k_u32 ret = 0; + k_s32 connector_fd; + k_u32 chip_id = 0x00; + k_connector_type connector_type = type; + k_connector_info connector_info; + + memset(&connector_info, 0, sizeof(k_connector_info)); + + //connector get sensor info + ret = kd_mpi_get_connector_info(connector_type, &connector_info); + if (ret) { + printf("sample_vicap, the sensor type not supported!\n"); + return ret; + } + + connector_fd = kd_mpi_connector_open(connector_info.connector_name); + if (connector_fd < 0) { + printf("%s, connector open failed.\n", __func__); + return K_ERR_VO_NOTREADY; + } + + // set connect power + kd_mpi_connector_power_set(connector_fd, K_TRUE); + // set connect get id + kd_mpi_connector_id_get(connector_fd, &chip_id); + // connector init + kd_mpi_connector_init(connector_fd, connector_info); + + return 0; +} + +k_u32 sample_vo_creat_osd(k_vo_osd osd, osd_info *info) +{ + k_vo_video_osd_attr attr; + + // set attr + attr.global_alptha = info->global_alptha; + + if (info->format == PIXEL_FORMAT_ABGR_8888 || info->format == PIXEL_FORMAT_ARGB_8888) + { + info->size = info->act_size.width * info->act_size.height * 4; + info->stride = info->act_size.width * 4 / 8; + } + else if (info->format == PIXEL_FORMAT_RGB_565 || info->format == PIXEL_FORMAT_BGR_565) + { + info->size = info->act_size.width * info->act_size.height * 2; + info->stride = info->act_size.width * 2 / 8; + } + else if (info->format == PIXEL_FORMAT_RGB_888 || info->format == PIXEL_FORMAT_BGR_888) + { + info->size = info->act_size.width * info->act_size.height * 3; + info->stride = info->act_size.width * 3 / 8; + } + else if(info->format == PIXEL_FORMAT_ARGB_4444 || info->format == PIXEL_FORMAT_ABGR_4444) + { + info->size = info->act_size.width * info->act_size.height * 2; + info->stride = info->act_size.width * 2 / 8; + } + else if(info->format == PIXEL_FORMAT_ARGB_1555 || info->format == PIXEL_FORMAT_ABGR_1555) + { + info->size = info->act_size.width * info->act_size.height * 2; + info->stride = info->act_size.width * 2 / 8; + } + else + { + printf("set osd pixel format failed \n"); + } + + attr.stride = info->stride; + attr.pixel_format = info->format; + attr.display_rect = info->offset; + attr.img_size = info->act_size; + kd_mpi_vo_set_video_osd_attr(osd, &attr); + + kd_mpi_vo_osd_enable(osd); + + return 0; +} + +int vo_creat_layer_test(k_vo_layer chn_id, layer_info *info) +{ + k_vo_video_layer_attr attr; + + // check layer + if ((chn_id >= K_MAX_VO_LAYER_NUM) || ((info->func & K_VO_SCALER_ENABLE) && (chn_id != K_VO_LAYER0)) + || ((info->func != 0) && (chn_id == K_VO_LAYER2))) + { + printf("input layer num failed \n"); + return -1 ; + } + + memset(&attr, 0, sizeof(attr)); + + // set offset + attr.display_rect = info->offset; + // set act + attr.img_size = info->act_size; + // sget size + info->size = info->act_size.height * info->act_size.width * 3 / 2; + //set pixel format + attr.pixel_format = info->format; + if (info->format != PIXEL_FORMAT_YVU_PLANAR_420) + { + printf("input pix format failed \n"); + return -1; + } + // set stride + attr.stride = (info->act_size.width / 8 - 1) + ((info->act_size.height - 1) << 16); + // set function + attr.func = info->func; + // set scaler attr + attr.scaler_attr = info->attr; + + // set video layer atrr + kd_mpi_vo_set_video_layer_attr(chn_id, &attr); + + // enable layer + kd_mpi_vo_enable_video_layer(chn_id); + + return 0; +} + + +k_vb_blk_handle sample_vo_insert_frame(k_video_frame_info *vf_info, void **pic_vaddr) +{ + k_u64 phys_addr = 0; + k_u32 *virt_addr; + k_vb_blk_handle handle; + k_s32 size = 0; + + if (vf_info == NULL) + return K_FALSE; + + if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_ABGR_8888 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_ARGB_8888) + size = vf_info->v_frame.height * vf_info->v_frame.width * 4; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_RGB_565 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_BGR_565) + size = vf_info->v_frame.height * vf_info->v_frame.width * 2; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_ABGR_4444 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_ARGB_4444) + size = vf_info->v_frame.height * vf_info->v_frame.width * 2; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_RGB_888 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_BGR_888) + size = vf_info->v_frame.height * vf_info->v_frame.width * 3; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_ARGB_1555 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_ABGR_1555) + size = vf_info->v_frame.height * vf_info->v_frame.width * 2; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_YVU_PLANAR_420) + size = vf_info->v_frame.height * vf_info->v_frame.width * 3 / 2; + + size = size + 4096; // 强制4K ,后边得删了 + + printf("vb block size is %x \n", size); + + handle = kd_mpi_vb_get_block(cidianbi.plane.g_pool_id, size, NULL); + if (handle == VB_INVALID_HANDLE) + { + printf("%s cidianbi.plane.g_pool_id is %d get vb block error\n", __func__, cidianbi.plane.g_pool_id); + return K_FAILED; + } + + phys_addr = kd_mpi_vb_handle_to_phyaddr(handle); + if (phys_addr == 0) + { + printf("%s get phys addr error\n", __func__); + return K_FAILED; + } + + virt_addr = (k_u32 *)kd_mpi_sys_mmap(phys_addr, size); + // virt_addr = (k_u32 *)kd_mpi_sys_mmap_cached(phys_addr, size); + + if (virt_addr == NULL) + { + printf("%s mmap error\n", __func__); + return K_FAILED; + } + + vf_info->mod_id = K_ID_VO; + vf_info->pool_id = cidianbi.plane.g_pool_id; + vf_info->v_frame.phys_addr[0] = phys_addr; + if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_YVU_PLANAR_420) + vf_info->v_frame.phys_addr[1] = phys_addr + (vf_info->v_frame.height * vf_info->v_frame.stride[0]); + *pic_vaddr = virt_addr; + + printf("phys_addr is %lx \n", phys_addr); + + return handle; +} + +inline wstring to_width_string(const string input) +{ + wstring_convert> converter; + + return converter.from_bytes(input); +} + +#define PICTURE "result_nmt.txt" +// test picture +void sample_vo_filling_color(void *pic_vaddr, string in, string out, bool is_en) +{ + int i = 0; + void *read_addr = NULL; + FILE *fd; + int ret = 0; + cv::Mat img; + + k_u32 *temp_addr = (k_u32 *)pic_vaddr; + k_u32 read_size = 64; + + CvxText cv_text_("./kmodel/simsun.ttc"); + + // cv::Scalar size(15, 1.0, 0.1, 0); + // float p = 1.f; + // cv_text_.setFont(NULL, &size, NULL, &p); + + cv_text_.restoreFont(); + + // memset(pic_vaddr, &data, cidianbi.plane.osd.act_size.width * cidianbi.plane.osd.act_size.height * 4); + memset(pic_vaddr, 0xffffffff, cidianbi.plane.osd.act_size.width * cidianbi.plane.osd.act_size.height * 4); + + img = cv::Mat(cidianbi.plane.osd.act_size.height, cidianbi.plane.osd.act_size.width, CV_8UC(4), pic_vaddr); + + wstring w_str_in = to_width_string(in); + wstring w_str_out = to_width_string(out); + + cv_text_.putText(img, w_str_in.c_str(),cv::Point(10, 80),cv::Scalar(0, 0, 255)); + cv_text_.putText(img, w_str_out.c_str(),cv::Point(10, 140),cv::Scalar(0, 0, 255)); + + cout << w_str_in.c_str() << "\n" << w_str_out.c_str() << endl; +} + + +k_s32 sample_vo_layer_config(void) +{ + layer_info info; + k_vo_layer chn_id = K_VO_LAYER1; + + memset(&info, 0, sizeof(info)); + + info.act_size.width = ISP_CHN1_WIDTH;//1080;//640;//1080; + info.act_size.height = ISP_CHN1_HEIGHT;//1920;//480;//1920; + info.format = PIXEL_FORMAT_YVU_PLANAR_420; + info.func = K_ROTATION_0;////K_ROTATION_90; + info.global_alptha = 0xff; + info.offset.x = 0;//(1080-w)/2, + info.offset.y = 0;//(1920-h)/2; + vo_creat_layer_test(chn_id, &info); + + return 0; +} + +int sample_sys_bind_init(void) +{ + k_s32 ret = 0; + k_mpp_chn vicap_mpp_chn; + k_mpp_chn vo_mpp_chn; + vicap_mpp_chn.mod_id = K_ID_VI; + vicap_mpp_chn.dev_id = cidianbi.vicap_dev; + vicap_mpp_chn.chn_id = VICAP_CHN_ID_1; + + vo_mpp_chn.mod_id = K_ID_VO; + vo_mpp_chn.dev_id = K_VO_DISPLAY_DEV_ID; + vo_mpp_chn.chn_id = K_VO_DISPLAY_CHN_ID1; + + ret = kd_mpi_sys_bind(&vicap_mpp_chn, &vo_mpp_chn); + if (ret) { + printf("kd_mpi_sys_unbind failed:0x%x\n", ret); + } + return ret; +} + +void sample_vicap_unbind_vo(void) +{ + k_s32 ret = 0; + k_mpp_chn vicap_mpp_chn; + k_mpp_chn vo_mpp_chn; + + vicap_mpp_chn.mod_id = K_ID_VI; + vicap_mpp_chn.dev_id = cidianbi.vicap_dev; + vicap_mpp_chn.chn_id = VICAP_CHN_ID_1; + + vo_mpp_chn.mod_id = K_ID_VO; + vo_mpp_chn.dev_id = K_VO_DISPLAY_DEV_ID; + vo_mpp_chn.chn_id = K_VO_DISPLAY_CHN_ID1; + + ret = kd_mpi_sys_unbind(&vicap_mpp_chn, &vo_mpp_chn); + if (ret) { + printf("kd_mpi_sys_unbind failed:0x%x\n", ret); + } + return; +} + + +int sample_vivcap_init(void) +{ + k_s32 ret = 0; + + sensor_type = SC_SC035HGS_MIPI_1LANE_RAW10_640X480_60FPS_LINEAR; + cidianbi.vicap_dev = VICAP_DEV_ID_0; + + memset(&sensor_info, 0, sizeof(k_vicap_sensor_info)); + ret = kd_mpi_vicap_get_sensor_info(sensor_type, &sensor_info); + if (ret) { + printf("sample_vicap, the sensor type not supported!\n"); + return ret; + } + + memset(&dev_attr, 0, sizeof(k_vicap_dev_attr)); + dev_attr.acq_win.h_start = 0; + dev_attr.acq_win.v_start = 0; + dev_attr.acq_win.width = ISP_INPUT_WIDTH; + dev_attr.acq_win.height = ISP_INPUT_HEIGHT; + dev_attr.mode = VICAP_WORK_ONLINE_MODE; + + dev_attr.pipe_ctrl.data = 0xFFFFFFFF; + dev_attr.pipe_ctrl.bits.af_enable = 0; + dev_attr.pipe_ctrl.bits.ahdr_enable = 0; + + + dev_attr.cpature_frame = 0; + memcpy(&dev_attr.sensor_info, &sensor_info, sizeof(k_vicap_sensor_info)); + + ret = kd_mpi_vicap_set_dev_attr(cidianbi.vicap_dev, dev_attr); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_set_dev_attr failed.\n"); + return ret; + } + + memset(&chn_attr, 0, sizeof(k_vicap_chn_attr)); + + //set chn0 output yuv420sp + // chn_attr.out_win = dev_attr.acq_win; + // chn_attr.crop_win = chn_attr.out_win; + chn_attr.out_win.h_start = 0; + chn_attr.out_win.v_start = 0; + chn_attr.out_win.width = ISP_CHN0_WIDTH; + chn_attr.out_win.height = ISP_CHN0_HEIGHT; + + // chn_attr.crop_win = dev_attr.acq_win; + chn_attr.crop_win.h_start = ISP_CROP_W_OFFSET; + chn_attr.crop_win.v_start = ISP_CROP_H_OFFSET; + chn_attr.crop_win.width = ISP_CHN0_WIDTH; + chn_attr.crop_win.height = ISP_CHN0_HEIGHT; + + chn_attr.scale_win = chn_attr.out_win; + chn_attr.crop_enable = K_FALSE; + chn_attr.scale_enable = K_FALSE; + // chn_attr.dw_enable = K_FALSE; + chn_attr.chn_enable = K_TRUE; + chn_attr.pix_format = PIXEL_FORMAT_YVU_PLANAR_420; + chn_attr.buffer_num = VICAP_MAX_FRAME_COUNT;//at least 3 buffers for isp + chn_attr.buffer_size = VICAP_ALIGN_UP((ISP_CHN0_WIDTH * ISP_CHN0_HEIGHT * 3 / 2), VICAP_ALIGN_1K);; + cidianbi.vicap_chn = VICAP_CHN_ID_0; + + // printf("sample_vicap ...kd_mpi_vicap_set_chn_attr, buffer_size[%d]\n", chn_attr.buffer_size); + ret = kd_mpi_vicap_set_chn_attr(cidianbi.vicap_dev, cidianbi.vicap_chn, chn_attr); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_set_chn_attr failed.\n"); + return ret; + } + +#if VICAP_VO_TESET + // config bind + sample_sys_bind_init(); + //set chn1 output rgb888p + chn_attr.out_win.h_start = 0; + chn_attr.out_win.v_start = 0; + chn_attr.out_win.width = ISP_CHN1_WIDTH ; + chn_attr.out_win.height = ISP_CHN1_HEIGHT; + + chn_attr.crop_win.h_start = ISP_CROP_W_OFFSET; + chn_attr.crop_win.v_start = ISP_CROP_H_OFFSET; + chn_attr.crop_win.width = ISP_CHN0_WIDTH; + chn_attr.crop_win.height = ISP_CHN0_HEIGHT; + + chn_attr.scale_win = chn_attr.out_win; + chn_attr.crop_enable = K_FALSE; + chn_attr.scale_enable = K_FALSE; + chn_attr.chn_enable = K_TRUE; + chn_attr.pix_format = PIXEL_FORMAT_YVU_PLANAR_420; + chn_attr.buffer_num = VICAP_MAX_FRAME_COUNT;//at least 3 buffers for isp + chn_attr.buffer_size = VICAP_ALIGN_UP((ISP_CHN1_HEIGHT * ISP_CHN1_WIDTH * 3 ), VICAP_ALIGN_1K); + chn_attr.fps = 30; + + // printf("sample_vicap ...kd_mpi_vicap_set_chn_attr, buffer_size[%d]\n", chn_attr.buffer_size); + ret = kd_mpi_vicap_set_chn_attr(cidianbi.vicap_dev, VICAP_CHN_ID_1, chn_attr); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_set_chn_attr failed.\n"); + return ret; + } +#endif + // set to header file database parse mode + ret = kd_mpi_vicap_set_database_parse_mode(cidianbi.vicap_dev, VICAP_DATABASE_PARSE_HEADER); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_set_database_parse_mode failed.\n"); + return ret; + } + + // printf("sample_vicap ...kd_mpi_vicap_init\n"); + ret = kd_mpi_vicap_init(cidianbi.vicap_dev); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_init failed.\n"); + return ret; + } + ret = kd_mpi_vicap_start_stream(cidianbi.vicap_dev); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_start_stream failed.\n"); + return ret; + } + + printf("vicap init success -------------------\n"); + + return ret; +} + + +int sample_vivcap_deinit(void) +{ + k_s32 ret; + + ret = kd_mpi_vicap_stop_stream(cidianbi.vicap_dev); + if (ret) { + printf("sample_vicap, stop stream failed.\n"); + } + ret = kd_mpi_vicap_deinit(cidianbi.vicap_dev); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_deinit failed.\n"); + return ret; + } + +#if VICAP_VO_TESET + sample_vicap_unbind_vo(); +#endif + + return 0; + +} + +int sample_gpio_init(void) +{ + int ret; + int gpio_fd = -1; + pin_mode_t key0; + pin_mode_t key1; + + pin_mode_t led0; + pin_mode_t led1; + + gpio_fd = open("/dev/gpio", O_RDWR); + if (gpio_fd < 0) + { + printf("open /dev/pin err\n"); + return -1; + } + + key0.pin = KEY_PIN_NUM1; + key1.pin = KEY_PIN_NUM2; + + led0.pin = LED_PIN_NUM1; + led1.pin = LED_PIN_NUM2; + + ret = ioctl(gpio_fd, GPIO_DM_INPUT, &key0); + if (ret) + { + printf("ioctl /dev/pin err\n"); + return -1; + } + + ret = ioctl(gpio_fd, GPIO_DM_INPUT, &key1); + if (ret) + { + printf("ioctl /dev/pin err\n"); + return -1; + } + + ret = ioctl(gpio_fd, GPIO_DM_OUTPUT, &led0); + if (ret) + { + printf("ioctl /dev/pin err\n"); + return -1; + } + + + ret = ioctl(gpio_fd, GPIO_DM_OUTPUT, &led1); + if (ret) + { + printf("ioctl /dev/pin err\n"); + return -1; + } + + return gpio_fd; +} diff --git a/src/reference/business_poc/dictionary_pen_poc/vo/vo.h b/src/reference/business_poc/dictionary_pen_poc/vo/vo.h new file mode 100644 index 000000000..28c821f76 --- /dev/null +++ b/src/reference/business_poc/dictionary_pen_poc/vo/vo.h @@ -0,0 +1,184 @@ +/** + * @file vo_test_case.h + * @author + * @brief + * @version 1.0 + * @date 2022-09-01 + * + * @copyright + * Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __VO_H__ +#define __VO_H__ + +#include +#include +#include +#include +#include +#include +#include "sys/ioctl.h" +#include + +#include "k_module.h" +#include "k_type.h" +#include "k_vb_comm.h" +#include "k_video_comm.h" +#include "k_sys_comm.h" +#include "mpi_vb_api.h" +#include "mpi_sys_api.h" +#include "mpi_vo_api.h" +#include "k_vo_comm.h" + +#include "k_connector_comm.h" +#include "mpi_connector_api.h" + +#include "k_vicap_comm.h" +#include "mpi_vb_api.h" +#include "mpi_vicap_api.h" +#include "mpi_isp_api.h" +#include "k_video_comm.h" + + +#include +#include +#include +#include + + +using namespace std; + +#define VICAP_VO_TESET 1 + +#define PRIVATE_POLL_SZE (1920 * 1080 * 3 / 2) + (4096 * 2) +#define PRIVATE_POLL_NUM (4) + +#define ISP_CHN1_WIDTH (320) +#define ISP_CHN1_HEIGHT (240) + +#define ISP_CHN0_WIDTH (320) +#define ISP_CHN0_HEIGHT (240) + +#define ISP_INPUT_WIDTH (640) +#define ISP_INPUT_HEIGHT (480) +#define ISP_CROP_W_OFFSET (0) +#define ISP_CROP_H_OFFSET (0) + +#define VICAP_MAX_FRAME_COUNT (30) + +#define VICAP_ALIGN_1K 0x400 +#define VICAP_ALIGN_UP(addr, size) (((addr)+((size)-1U))&(~((size)-1U))) + + +#define GPIO_DM_OUTPUT _IOW('G', 0, int) +#define GPIO_DM_INPUT _IOW('G', 1, int) +#define GPIO_DM_INPUT_PULL_UP _IOW('G', 2, int) +#define GPIO_DM_INPUT_PULL_DOWN _IOW('G', 3, int) +#define GPIO_WRITE_LOW _IOW('G', 4, int) +#define GPIO_WRITE_HIGH _IOW('G', 5, int) + +#define GPIO_PE_RISING _IOW('G', 7, int) +#define GPIO_PE_FALLING _IOW('G', 8, int) +#define GPIO_PE_BOTH _IOW('G', 9, int) +#define GPIO_PE_HIGH _IOW('G', 10, int) +#define GPIO_PE_LOW _IOW('G', 11, int) + +#define GPIO_READ_VALUE _IOW('G', 12, int) + +#define KEY_PIN_NUM1 46 //gpio46 +#define KEY_PIN_NUM2 27 //gpio27 + +#define LED_PIN_NUM1 42 //GPIO42 +#define LED_PIN_NUM2 42 // ??? + +typedef struct kd_pin_mode +{ + unsigned short pin; /* pin number, from 0 to 63 */ + unsigned short mode; /* pin level status, 0 low level, 1 high level */ +} pin_mode_t; + + +typedef struct +{ + k_u64 osd_phy_addr; + void *osd_virt_addr; + k_pixel_format format; + k_vo_point offset; + k_vo_size act_size; + k_u32 size; + k_u32 stride; + k_u8 global_alptha; +} osd_info; + +typedef struct +{ + k_u64 layer_phy_addr; + k_pixel_format format; + k_vo_point offset; + k_vo_size act_size; + k_u32 size; + k_u32 stride; + k_u8 global_alptha; + //only layer0、layer1 + k_u32 func; + // only layer0 + k_vo_scaler_attr attr; + +} layer_info; + +typedef struct { + osd_info osd; + k_u32 g_pool_id; +}osd_plane; + +typedef struct { + k_vicap_dev vicap_dev; + k_vicap_chn vicap_chn; + osd_plane plane; + k_vo_osd chn; + k_u32 exit_flag; + pthread_mutex_t mutex_key; + k_u32 key_val; + + pthread_mutex_t stitch; + k_u32 stitch_val; + +}cidianbi_attr; + +extern cidianbi_attr cidianbi; + +k_s32 sample_connector_init(k_connector_type type); +k_u32 sample_vo_creat_osd(k_vo_osd osd, osd_info *info); +k_vb_blk_handle sample_vo_insert_frame(k_video_frame_info *vf_info, void **pic_vaddr); +int sample_vo_creat_private_poll(void); +void sample_vo_filling_color(void *pic_vaddr, string in, string out, bool is_en); +k_s32 sample_vo_layer_config(void); + +int sample_vivcap_init(void); +int sample_vivcap_deinit(void); + +int sample_gpio_init(void); + +#endif \ No newline at end of file diff --git a/src/reference/business_poc/peephole/big/app/main.cpp b/src/reference/business_poc/peephole/big/app/main.cpp index cc5af8382..99005a746 100644 --- a/src/reference/business_poc/peephole/big/app/main.cpp +++ b/src/reference/business_poc/peephole/big/app/main.cpp @@ -26,8 +26,51 @@ #include "my_app.h" #include "media.h" -int main() { +static bool enable_pir_vo = false; +static bool disable_first_snap = false; +static int detect_stay_duration = 10; + +static void Usage() { + std::cout << "Usage: ./peehole_device [-v] [-d] [-t ]"<< std::endl; + std::cout << "-h: print usage" << std::endl; + std::cout << "-v: enable pir vo, default false" << std::endl; + std::cout << "-d: disable first snap, default false" << std::endl; + std::cout << "-t: person detect stay duration(s), default 10s " << std::endl; + exit(-1); +} + +static int parse_config(int argc, char *argv[]) { + int result; + opterr = 0; + while ((result = getopt(argc, argv, "vdt:")) != -1) { + switch (result) { + case 'v' : { + enable_pir_vo = true; + break; + } + case 'd' : { + disable_first_snap = true; + break; + } + case 't' : { + detect_stay_duration = atoi(optarg); + break; + } + case 'h' : + default: Usage(); break; + } + } +} + +int main(int argc, char *argv[]) { MyApp *app = new MyApp(16); + if (argc > 1) + parse_config(argc, argv); + + app->EnablePirVo(enable_pir_vo); + app->DisableFirstSnap(disable_first_snap); + app->SetDetectStayDura(detect_stay_duration); + TrigerMode triger_mode = app->GetCurrentMode(); // TrigerMode triger_mode = DOORBELL_MODE; printf("triger mode = %d...\n", triger_mode); diff --git a/src/reference/business_poc/peephole/big/app/my_app.cpp b/src/reference/business_poc/peephole/big/app/my_app.cpp index 82be68920..3ab7ea46f 100644 --- a/src/reference/business_poc/peephole/big/app/my_app.cpp +++ b/src/reference/business_poc/peephole/big/app/my_app.cpp @@ -106,13 +106,24 @@ int MyApp::EnterPlaybackMode() { TrigerMode MyApp::EnterPirMode() { current_mode_ = PIR_MODE; - kmodel_path_ = "person_detect_yolov5n.kmodel"; + kmodel_path_ = "/bin/person_detect_yolov5n.kmodel"; media_->VcapSetDevAttr(); + // for vo + if (enable_pir_vo_) { + VcapChnAttr vcap_chn_attr; + memset(&vcap_chn_attr, 0, sizeof(vcap_chn_attr)); + vcap_chn_attr.output_width = 1088; + vcap_chn_attr.output_height = 1920; + vcap_chn_attr.crop_width = 1088; + vcap_chn_attr.crop_height = 1920; + vcap_chn_attr.pixel_format = PIXEL_FORMAT_YUV_SEMIPLANAR_420; + media_->VcapSetChnAttr(VICAP_CHN_ID_0, vcap_chn_attr); + } // for ai { VcapChnAttr vcap_chn_attr; - k_vicap_chn vi_detect_chn = VICAP_CHN_ID_0; + k_vicap_chn vi_detect_chn = VICAP_CHN_ID_1; vcap_chn_attr.output_width = 720; vcap_chn_attr.output_height = 1280; vcap_chn_attr.crop_width = 1088; @@ -132,7 +143,8 @@ TrigerMode MyApp::EnterPirMode() { media_->VcapSetChnAttr(VICAP_CHN_ID_2, vcap_chn_attr); } media_->VcapInit(); - + if (enable_pir_vo_) + media_->VoInit(); int venc_snap_chn_ = 0; media_->VencSnapChnCreate(venc_snap_chn_, 1088, 1920); media_->VencSnapChnStart(); @@ -149,6 +161,8 @@ TrigerMode MyApp::EnterPirMode() { while (!ai_exit_flag_ && !venc_exit_flag_) { usleep(10000); } + if (enable_pir_vo_) + media_->VoDeInit(); media_->VcapStop(); media_->VencSnapChnStop(); if (person_detect_thread_.joinable()) @@ -170,6 +184,21 @@ void MyApp::StartPersonDetectThread() { person_detect_thread_ = std::thread([this]() { vector results; ScopedTiming st; + int osd_width = 1088; + int osd_height = 1920; + + void *pic_vaddr = NULL; + uint32_t insert_vo_handle; + k_video_frame_info vf_info; + if (enable_pir_vo_) { + memset(&vf_info, 0, sizeof(vf_info)); + vf_info.v_frame.width = osd_width; + vf_info.v_frame.height = osd_height; + vf_info.v_frame.stride[0] = osd_width; + vf_info.v_frame.pixel_format = PIXEL_FORMAT_ARGB_8888; + insert_vo_handle = media_->VoGetInserFrame(&vf_info, &pic_vaddr); + } + k_u64 paddr = 0; void *vaddr = nullptr; k_u32 size = 3 * detect_width_ * detect_height_; @@ -178,7 +207,7 @@ void MyApp::StartPersonDetectThread() { person_detect_ = new personDetect(kmodel_path_.c_str(), 0.5, 0.45, {3, detect_height_, detect_width_}, reinterpret_cast(vaddr), reinterpret_cast(paddr), 0); while (!ai_exit_flag_) { k_video_frame_info dump_frame; - k_s32 ret = media_->VcapGetDumpFrame(VICAP_CHN_ID_0, &dump_frame, vaddr); + k_s32 ret = media_->VcapGetDumpFrame(VICAP_CHN_ID_1, &dump_frame, vaddr); if (ret != K_SUCCESS) { continue; } @@ -193,7 +222,7 @@ void MyApp::StartPersonDetectThread() { start_detect_.store(true); } else { int elapsed = st.ElapsedSeconds(); - if (elapsed >= 10) { + if (elapsed >= detect_stay_dura_) { printf("stay aram...\n"); check_stay_.store(true); start_detect_.store(false); @@ -205,10 +234,30 @@ void MyApp::StartPersonDetectThread() { start_detect_.store(false); } - media_->VcapReleaseDumpFrame(VICAP_CHN_ID_0, &dump_frame); + if (enable_pir_vo_) { + cv::Mat osd_frame(osd_height, osd_width, CV_8UC4, cv::Scalar(0, 0, 0, 0)); + if (check_stay_) { + for (auto r : results) { + int x1 = r.x1 / 720 * osd_width; + int y1 = r.y1 / 1280 * osd_height; + + int w = (r.x2-r.x1) / 720 * osd_width; + int h = (r.y2-r.y1) / 1280 * osd_height; + cv::rectangle(osd_frame, cv::Rect( x1,y1,w,h ), cv::Scalar(255, 255,0, 0), 6, 2, 0); // ARGB + } + } + + memcpy(pic_vaddr, osd_frame.data, osd_width * osd_height * 4); + media_->VoInsertFrame(&vf_info); + } + + media_->VcapReleaseDumpFrame(VICAP_CHN_ID_1, &dump_frame); } delete person_detect_; media_->MediaSysFree(paddr, vaddr); + + if (enable_pir_vo_) + media_->VoReleaseInserFrame(insert_vo_handle); }); } @@ -379,6 +428,16 @@ TrigerMode MyApp::EnterDoorBellMode() { StartAencSendThread(); StartVencSendThread(); + if (enable_pir_vo_ && pir_to_doorbell_) { + uint8_t buf[128]; + UserMessage *msg = (UserMessage*)buf; + msg->type = static_cast(UserMsgType::CURRENT_MODE_TYPE); + msg->len = snprintf(msg->data, sizeof(buf) - 8,"%s", "doorbell_mode"); + msg->data[msg->len] = '\0'; + comm_server_->SendMessage(msg, sizeof(UserMessage) + msg->len + 1); + pir_to_doorbell_ = false; + } + while(!doorbell_venc_exit_flag_ &&!doorbell_aenc_exit_flag_ &&!doorbell_palyaudio_exit_flag_) { @@ -665,7 +724,7 @@ void MyApp::StartPlayAudioThread() { std::fstream audio_file; k_u32 music_data_size_ {0}; k_u8 *music_data_ {nullptr}; - audio_file.open("./doorbell.g711u", std::ios::in | std::ios::binary); + audio_file.open("/bin/doorbell.g711u", std::ios::in | std::ios::binary); if (audio_file.is_open()) { audio_file.seekg(0, std::ios::end); music_data_size_ = audio_file.tellg(); @@ -722,7 +781,8 @@ void MyApp::StartPlayAudioThread() { usleep(10000); } - delete []music_data_; + if (music_data_) + delete []music_data_; printf("StartPlayAudioThread stop...\n"); return; }); @@ -734,6 +794,18 @@ void MyApp::ReceiveMessageThread() { if (comm_server_->ClientReady()) { client_ready_.store(true); exit_msg_.store(false); + if (enable_pir_vo_) { + uint8_t buf[128]; + UserMessage *msg = (UserMessage*)buf; + msg->type = static_cast(UserMsgType::CURRENT_MODE_TYPE); + if (current_mode_ == DOORBELL_MODE) { + msg->len = snprintf(msg->data, sizeof(buf) - 8,"%s", "doorbell_mode"); + } else if (current_mode_ == PIR_MODE) { + msg->len = snprintf(msg->data, sizeof(buf) - 8,"%s", "pir_mode"); + } + msg->data[msg->len] = '\0'; + comm_server_->SendMessage(msg, sizeof(UserMessage) + msg->len + 1); + } } if (comm_server_->GetKeyPressed() && !key_pressed_) { @@ -777,6 +849,7 @@ void MyApp::ReceiveMessageThread() { venc_exit_flag_.store(true); send_event_exit_flag_.store(true); current_mode_ = DOORBELL_MODE; + pir_to_doorbell_ = true; } std::this_thread::sleep_for(std::chrono::milliseconds(20)); } diff --git a/src/reference/business_poc/peephole/big/app/my_app.h b/src/reference/business_poc/peephole/big/app/my_app.h index 75c43774e..b791df33e 100644 --- a/src/reference/business_poc/peephole/big/app/my_app.h +++ b/src/reference/business_poc/peephole/big/app/my_app.h @@ -95,6 +95,18 @@ class MyApp { void StartSendEventThread(); TrigerMode GetCurrentMode(); + void EnablePirVo(bool enable_pir_vo) { + enable_pir_vo_ = enable_pir_vo; + } + void DisableFirstSnap(bool disable_first_snap) { + doorbell_first_snap_ = !disable_first_snap; + first_snap_ = !disable_first_snap; + } + + void SetDetectStayDura(int detect_stay_duration) { + detect_stay_dura_ = detect_stay_duration; + } + private: void StartPirSnapThread(); void StartPersonDetectThread(); @@ -169,6 +181,9 @@ class MyApp { std::atomic doorbell_first_snap_ {true}; std::string kmodel_path_; std::atomic sys_init_ {false}; + bool enable_pir_vo_ {false}; + int detect_stay_dura_ {10}; + bool pir_to_doorbell_ {false}; }; #endif // _MY_APP_ \ No newline at end of file diff --git a/src/reference/business_poc/peephole/big/comm_server/include/comm_msg.h b/src/reference/business_poc/peephole/big/comm_server/include/comm_msg.h index 828c35061..f7e2cef48 100644 --- a/src/reference/business_poc/peephole/big/comm_server/include/comm_msg.h +++ b/src/reference/business_poc/peephole/big/comm_server/include/comm_msg.h @@ -51,6 +51,7 @@ enum class UserMsgType : int { // server->client SERVER_MSG_BASE = 100, PLAYBACK_ACK, + CURRENT_MODE_TYPE, // UserMsgMax = 1000 }; diff --git a/src/reference/business_poc/peephole/big/media/include/media.h b/src/reference/business_poc/peephole/big/media/include/media.h index 1433f95a2..ab1161ea8 100644 --- a/src/reference/business_poc/peephole/big/media/include/media.h +++ b/src/reference/business_poc/peephole/big/media/include/media.h @@ -77,6 +77,8 @@ struct AudioStream { k_vb_blk_handle blk_handle; }; + + class Media { public: ~Media() { } @@ -96,6 +98,9 @@ class Media { int VcapStop(); int VoInit(); + uint32_t VoGetInserFrame(k_video_frame_info *vf_info, void **pic_vaddr); + int VoInsertFrame(k_video_frame_info *vf_info); + int VoReleaseInserFrame(uint32_t inser_handle); int VoDeInit(); int VencChnCreate(int chn, int width, int height); @@ -147,6 +152,9 @@ class Media { AudioStream audio_innercom_stream_; k_u64 venc_width_ {1088}; k_u64 venc_height_ {1920}; + k_u32 osd_pool_id_ {0}; + k_u64 osd_width_ {1088}; + k_u64 osd_height_ {1920}; k_u8 venc_snap_chn_ {0}; k_u8 venc_chn_ {1}; k_u64 detect_width_ {720}; diff --git a/src/reference/business_poc/peephole/big/media/src/media.cpp b/src/reference/business_poc/peephole/big/media/src/media.cpp index 009a1bc13..679302a14 100644 --- a/src/reference/business_poc/peephole/big/media/src/media.cpp +++ b/src/reference/business_poc/peephole/big/media/src/media.cpp @@ -43,36 +43,36 @@ int Media::Init() { // vb for video k_u64 pic_size = venc_width_ * venc_height_ * 3 / 2; k_u64 stream_size = venc_width_ * venc_height_ / 2; - vb_config.comm_pool[2].blk_cnt = 6; + vb_config.comm_pool[2].blk_cnt = 3; vb_config.comm_pool[2].blk_size = ((pic_size + 0xfff) & ~0xfff); vb_config.comm_pool[2].mode = VB_REMAP_MODE_NOCACHE; - vb_config.comm_pool[3].blk_cnt = 30; + vb_config.comm_pool[3].blk_cnt = 3; vb_config.comm_pool[3].blk_size = ((stream_size + 0xfff) & ~0xfff); vb_config.comm_pool[3].mode = VB_REMAP_MODE_NOCACHE; // vb for YUV420SP output - vb_config.comm_pool[4].blk_cnt = 5; + vb_config.comm_pool[4].blk_cnt = 3; vb_config.comm_pool[4].mode = VB_REMAP_MODE_NOCACHE; vb_config.comm_pool[4].blk_size = VICAP_ALIGN_UP((venc_width_ * venc_height_ * 3 / 2), 0x1000); // vb for RGB888 output - vb_config.comm_pool[5].blk_cnt = 6; - vb_config.comm_pool[5].mode = VB_REMAP_MODE_NOCACHE; - vb_config.comm_pool[5].blk_size = VICAP_ALIGN_UP((detect_height_ * detect_width_ * 3 ), 0x1000); + // vb_config.comm_pool[5].blk_cnt = 0; + // vb_config.comm_pool[5].mode = VB_REMAP_MODE_NOCACHE; + // vb_config.comm_pool[5].blk_size = VICAP_ALIGN_UP((detect_height_ * detect_width_ * 3 ), 0x1000); memset(&sensor_info_, 0, sizeof(sensor_info_)); kd_mpi_vicap_get_sensor_info(sensor_type_, &sensor_info_); - vb_config.comm_pool[6].blk_cnt = 6; - vb_config.comm_pool[6].blk_size = VICAP_ALIGN_UP(sensor_info_.width * sensor_info_.height * 3 / 2, 0x1000); - vb_config.comm_pool[6].mode = VB_REMAP_MODE_NOCACHE; + vb_config.comm_pool[5].blk_cnt = 3; + vb_config.comm_pool[5].blk_size = VICAP_ALIGN_UP(sensor_info_.width * sensor_info_.height * 3 / 2, 0x1000); + vb_config.comm_pool[5].mode = VB_REMAP_MODE_NOCACHE; - vb_config.comm_pool[7].blk_cnt = 2; - vb_config.comm_pool[7].blk_size = ((pic_size + 0xfff) & ~0xfff); + vb_config.comm_pool[6].blk_cnt = 3; + vb_config.comm_pool[6].blk_size = ((pic_size + 0xfff) & ~0xfff); + vb_config.comm_pool[6].mode = VB_REMAP_MODE_NOCACHE; + vb_config.comm_pool[7].blk_cnt = 3; + vb_config.comm_pool[7].blk_size = ((stream_size + 0xfff) & ~0xfff); vb_config.comm_pool[7].mode = VB_REMAP_MODE_NOCACHE; - vb_config.comm_pool[8].blk_cnt = 10; - vb_config.comm_pool[8].blk_size = ((stream_size + 0xfff) & ~0xfff); - vb_config.comm_pool[8].mode = VB_REMAP_MODE_NOCACHE; k_vb_supplement_config vb_supp; memset(&vb_supp, 0, sizeof(vb_supp)); @@ -115,6 +115,7 @@ int Media::VcapSetDevAttr() { dev_attr.pipe_ctrl.data = 0xFFFFFFFF; dev_attr.pipe_ctrl.bits.af_enable = 0; dev_attr.pipe_ctrl.bits.ahdr_enable = 0; + dev_attr.pipe_ctrl.bits.dnr3_enable = 0; dev_attr.cpature_frame = 0; memcpy(&dev_attr.sensor_info, &sensor_info_, sizeof(k_vicap_sensor_info)); @@ -144,7 +145,7 @@ int Media::VcapSetChnAttr(k_vicap_chn vicap_chn, const VcapChnAttr &vcap_attr) { vicap_chn_attr.chn_enable = K_TRUE; vicap_chn_attr.alignment = 12; vicap_chn_attr.pix_format = vcap_attr.pixel_format; - vicap_chn_attr.buffer_num = 6; + vicap_chn_attr.buffer_num = 3; vicap_chn_attr.buffer_size = VICAP_ALIGN_UP(sensor_info_.width * sensor_info_.height * 3 / 2, 0x1000); k_s32 ret = kd_mpi_vicap_set_chn_attr(vicap_dev_, vicap_chn, vicap_chn_attr); @@ -157,7 +158,13 @@ int Media::VcapSetChnAttr(k_vicap_chn vicap_chn, const VcapChnAttr &vcap_attr) { } int Media::VcapInit() { - k_s32 ret = kd_mpi_vicap_init(vicap_dev_); + k_s32 ret; + ret = kd_mpi_vicap_set_database_parse_mode(vicap_dev_, VICAP_DATABASE_PARSE_HEADER); + if (ret) { + printf("sample_vicap, kd_mpi_vicap_set_database_parse_mode failed.\n"); + return ret; + } + ret = kd_mpi_vicap_init(vicap_dev_); if (ret) { std::cout << "sample_vicap, kd_mpi_vicap_init failed." << std::endl; return ret; @@ -287,6 +294,96 @@ int Media::VoConnectorInit() { return 0; } +int Media::VoInsertFrame(k_video_frame_info *vf_info) { + int ret = kd_mpi_vo_chn_insert_frame(K_VO_OSD3 + 3, vf_info); + if (ret) { + printf("VoInsertFrame failed.\n"); + return -1; + } + + return 0; +} + +uint32_t Media::VoGetInserFrame(k_video_frame_info *vf_info, void **pic_vaddr) { + k_u64 phys_addr = 0; + k_u32 *virt_addr; + k_vb_blk_handle handle; + k_s32 size; + + k_vo_video_osd_attr attr; + attr.global_alptha = 0xff; + attr.stride = osd_width_ * 4 / 8; + attr.pixel_format = PIXEL_FORMAT_ARGB_8888; + attr.display_rect.x = 0; + attr.display_rect.y = 0; + attr.img_size.width = osd_width_; + attr.img_size.height = osd_height_; + kd_mpi_vo_set_video_osd_attr(K_VO_OSD3, &attr); + kd_mpi_vo_osd_enable(K_VO_OSD3); + + k_vb_pool_config pool_config; + memset(&pool_config, 0, sizeof(pool_config)); + pool_config.blk_size = VICAP_ALIGN_UP((osd_width_ * osd_height_ * 4 * 2), 0x1000); + pool_config.blk_cnt = 1; + pool_config.mode = VB_REMAP_MODE_NOCACHE; + osd_pool_id_ = kd_mpi_vb_create_pool(&pool_config); + + if (vf_info == NULL) + return K_FALSE; + + if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_ABGR_8888 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_ARGB_8888) + size = vf_info->v_frame.height * vf_info->v_frame.width * 4; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_RGB_565 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_BGR_565) + size = vf_info->v_frame.height * vf_info->v_frame.width * 2; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_ABGR_4444 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_ARGB_4444) + size = vf_info->v_frame.height * vf_info->v_frame.width * 2; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_RGB_888 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_BGR_888) + size = vf_info->v_frame.height * vf_info->v_frame.width * 3; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_ARGB_1555 || vf_info->v_frame.pixel_format == PIXEL_FORMAT_ABGR_1555) + size = vf_info->v_frame.height * vf_info->v_frame.width * 2; + else if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_YVU_PLANAR_420) + size = vf_info->v_frame.height * vf_info->v_frame.width * 3 / 2; + + size = size + 4096; + + handle = kd_mpi_vb_get_block(osd_pool_id_, size, NULL); + if (handle == VB_INVALID_HANDLE) { + printf("%s get vb block error\n", __func__); + return K_FAILED; + } + + phys_addr = kd_mpi_vb_handle_to_phyaddr(handle); + if (phys_addr == 0) { + printf("%s get phys addr error\n", __func__); + return K_FAILED; + } + + virt_addr = (k_u32 *)kd_mpi_sys_mmap(phys_addr, size); + if (virt_addr == NULL) { + printf("%s mmap error\n", __func__); + return K_FAILED; + } + + vf_info->mod_id = K_ID_VO; + vf_info->pool_id = osd_pool_id_; + vf_info->v_frame.phys_addr[0] = phys_addr; + if (vf_info->v_frame.pixel_format == PIXEL_FORMAT_YVU_PLANAR_420) + vf_info->v_frame.phys_addr[1] = phys_addr + (vf_info->v_frame.height * vf_info->v_frame.stride[0]); + *pic_vaddr = virt_addr; + + return handle; +} + +int Media::VoReleaseInserFrame(uint32_t inser_handle) { + kd_mpi_vo_osd_disable(K_VO_OSD3); + kd_mpi_vb_release_block(k_vb_blk_handle(inser_handle)); + int ret = kd_mpi_vb_destory_pool(osd_pool_id_); + if (ret) + printf("vb destory pool ret = %d, osd_pool_id = %d...\n", ret, osd_pool_id_); + + return 0; +} + int Media::VoDeInit() { kd_mpi_vo_disable_video_layer(K_VO_LAYER1); @@ -316,7 +413,7 @@ int Media::VencSnapChnCreate(int chn, int width, int height) { attr.venc_attr.pic_height = height; k_u64 stream_size = width * height / 2; attr.venc_attr.stream_buf_size = VICAP_ALIGN_UP(stream_size, 0x1000); - attr.venc_attr.stream_buf_cnt = 10; + attr.venc_attr.stream_buf_cnt = 3; attr.rc_attr.rc_mode = K_VENC_RC_MODE_MJPEG_FIXQP; attr.rc_attr.mjpeg_fixqp.src_frame_rate = 30; attr.rc_attr.mjpeg_fixqp.dst_frame_rate = 30; @@ -398,7 +495,7 @@ int Media::VencChnCreate(int chn, int width, int height) { attr.venc_attr.pic_height = height; k_u64 stream_size = width * height / 2; attr.venc_attr.stream_buf_size = VICAP_ALIGN_UP(stream_size, 0x1000); - attr.venc_attr.stream_buf_cnt = 30; + attr.venc_attr.stream_buf_cnt = 3; attr.venc_attr.type = K_PT_H265; attr.venc_attr.profile = VENC_PROFILE_H265_MAIN; attr.rc_attr.rc_mode = K_VENC_RC_MODE_CBR; diff --git a/src/reference/fancy_poc/ai_scale/README.md b/src/reference/fancy_poc/ai_scale/README.md index 5ef729c22..a31d54669 100644 --- a/src/reference/fancy_poc/ai_scale/README.md +++ b/src/reference/fancy_poc/ai_scale/README.md @@ -1,17 +1,17 @@ # K230 模拟AI电子秤 ![Alt text](resource/image.png) -Document version: V1.0 Release date: 2023-10-7 +Document version: V1.0 Release date: 2023-10-26 ## 介绍 -该项目为K230 模拟AI电子秤开源工程。本工程基于K230应用了度量学习技术实现商品识别。本应用使用PC作为服务端控制上秤、下秤和展示商品;使用K230作为客户端建立对比向量库,然后捕捉图像进行向量相似度对比获得商品类别,将识别结果传给服务端展示给用户。得到商品类别后可以结合商品单价和商品重量得到价签。 +该项目为K230 模拟AI电子秤开源工程。本工程基于K230应用了度量学习技术实现商品识别。本应用使用PC作为服务端控制上秤、下秤、采集新商品和展示称重商品;使用K230作为客户端建立对比向量库,然后捕捉图像进行向量相似度对比获得商品类别,结合商品单价和商品重量得到应付钱数;最后将商品类别和应付钱数在PC端展示给用户。 frame -本项目主要侧重于K230端功能的实现,使用PC端的“上秤”,“下秤”两个按钮模拟传感器的逻辑。 +本项目主要侧重于K230端功能的实现,使用PC端的“上秤”,“下秤”两个按钮模拟传感器的逻辑。多次点击采集按钮获取开发板摄像头采集的新类别图片;点击添加按钮将新类别添加到底库中;点击清除按钮停止采集。本项目未连接重量传感器,设置默认重量为1kg。 ## 主要特点 -- 自学习:无需重新训练模型,在底库数据集中添加对应类别,推理时即可识别; +- 实时自学习:无需重新训练模型,使用采集功能在底库数据集中添加对应类别,推理时即可识别; - 小样本分类效果良好:每个类别只需要几张图片即可完成分类; @@ -24,14 +24,14 @@ Document version: V1.0 Release date: 2023-10-7 wget https://ai.b-bug.org/k230/downloads/fancy_poc/ai_scale/$file || wget https://kendryte-download.canaan-creative.com/k230/downloads/fancy_poc/ai_scale/$file; done - for file in onboard_v2.4.zip + for file in onboard_v2.5.zip do wget https://ai.b-bug.org/k230/downloads/fancy_poc/ai_scale/k230_board/$file || wget https://kendryte-download.canaan-creative.com/k230/downloads/fancy_poc/ai_scale/k230_board/$file; done ## 数据准备 -待分类的数据需要按照固定格式进行组织,数据组织形式如下: +待分类的数据必须要按照固定格式进行组织,数据组织形式如下: ``` |-gallery @@ -51,7 +51,27 @@ Document version: V1.0 Release date: 2023-10-7 |... ``` -数据集的根目录为gallery,gallery包含若干个子文件夹,每个文件夹以类别编号命名,从0开始;类别文件夹下包括若干张图片和一个label.txt文件;label.txt文件中存储类别名称。该数据集用于在商品识别之前创建底库。 +数据集的根目录为gallery,gallery包含若干个子文件夹,每个文件夹以类别编号命名,从0开始;类别文件夹下包括若干张图片(图片不要太大,不超过300kb)和一个label.txt文件,图片从0开始命名,label.txt文件中第一行存储类别名称,第二行存储类别单价,如gallery/0/label.txt: + +```shell +长茄子 +1.23 +``` + +该数据集用于在商品识别之前创建底库。 + +本项目提供了示例商品类别底库,请参照onboard_v2.5/gallery中的数据结构组织数据。 + +## 可执行文件编译 + +进入SDK目录下的reference/fancy_poc下,执行: + +```shell +chmod +x build_app.sh +./build_app.sh +``` + +在reference/fancy_poc/k230_bin目录下,获取ai_scale.elf和client拷贝到开发板onboard_v2.5内。 ## 服务端准备 @@ -78,7 +98,7 @@ Document version: V1.0 Release date: 2023-10-7 ### 1. 服务端: # 解压AIScale.zip - cd AIScale/AIScale_v1.0 + cd AIScale start AIScale.exe #或双击AIScale.exe启动 **注意:**服务端界面启动后点击**启动**按钮, 服务端服务IP为运行服务器的本机IP,连接端口默认为8080,连接端口可自定义。 @@ -90,12 +110,9 @@ Document version: V1.0 Release date: 2023-10-7 cd /sharefs/ai_scale #小核下执行(IP和端口由服务端设置) ./connect.sh 192.168.1.2 8080 - #小核下修改ai_scale_isp.sh文件的可执行文件名称 - vi ai_scale_isp.sh - #将main.elf换为ai_scale.elf #大核下执行(./ai_scale_isp.sh) ./ai_scale.elf recognition.kmodel None gallery 5 1 - #gallery是底库数据集的路径,根据您自定义的数据进行输入 + #gallery是底库数据集的路径 **注意:** 1、使用./connect.sh命令时需要使用服务端显示的相应IP地址及通信端口; @@ -111,7 +128,7 @@ Document version: V1.0 Release date: 2023-10-7 ![测试说明](./resource/state.jpg) -PC启动服务端,开发板摄像头对准识别商品,调整开发板使得摄像头拍摄到的图像尽可能清晰。然后建立PC和开发板之间的连接,开始上秤识别。 +PC启动服务端,开发板摄像头对准识别商品,调整开发板使得摄像头拍摄到的图像尽可能清晰且距离固定。然后建立PC和开发板之间的连接,开始上秤识别。 ### 服务端展示界面 @@ -122,7 +139,8 @@ PC启动服务端,开发板摄像头对准识别商品,调整开发板使得 ![show](./resource/show.gif) -- 称重重量由传感器获取,商品单价可以存储在PC端的数据库中,也可存储在开发板上,在构建底库时同时构建商品价格字典; +- 本项目依赖网络传输,图片的传输和处理较慢,不可频繁多次点击同一按钮,如有问题,可重新启动; + +- 本项目侧重实现K230端的商品识别称重计价; -- 通过识别获得商品类别后,后续可以根据称重重量和单价计算当前商品的价格; -- 本项目侧重实现K230端的商品识别; + diff --git a/src/reference/fancy_poc/ai_scale/resource/server.jpg b/src/reference/fancy_poc/ai_scale/resource/server.jpg index 781eb876e..1dce9579f 100644 Binary files a/src/reference/fancy_poc/ai_scale/resource/server.jpg and b/src/reference/fancy_poc/ai_scale/resource/server.jpg differ diff --git a/src/reference/fancy_poc/ai_scale/resource/show.gif b/src/reference/fancy_poc/ai_scale/resource/show.gif index 83015a20d..18552cbda 100644 Binary files a/src/reference/fancy_poc/ai_scale/resource/show.gif and b/src/reference/fancy_poc/ai_scale/resource/show.gif differ diff --git a/src/reference/fancy_poc/ai_scale/resource/state.jpg b/src/reference/fancy_poc/ai_scale/resource/state.jpg index 921cef24d..1846b84e7 100644 Binary files a/src/reference/fancy_poc/ai_scale/resource/state.jpg and b/src/reference/fancy_poc/ai_scale/resource/state.jpg differ diff --git a/src/reference/fancy_poc/ai_scale/src/ai_scale_ai_code/main.cc b/src/reference/fancy_poc/ai_scale/src/ai_scale_ai_code/main.cc index db1374fc4..3863a0ab9 100644 --- a/src/reference/fancy_poc/ai_scale/src/ai_scale_ai_code/main.cc +++ b/src/reference/fancy_poc/ai_scale/src/ai_scale_ai_code/main.cc @@ -26,7 +26,12 @@ #include #include #include +#include +#include #include +#include +#include +#include #include "utils.h" #include "vi_vo.h" #include "gen_embedding.h" @@ -38,6 +43,16 @@ using namespace std; std::atomic isp_stop(false); +std::vector> g_embeddings; //底库数据创建的向量对比库 +std::map g_label_dict; // 底库类别标签映射 +std::map g_price_dict; // 底库类别单价映射 +int g_img_idx=0; // 底库图片索引 +int g_max_classes_idx=0; // 底库类别索引 +string g_dataset_dir="gallery"; // 底库根目录 +string g_result=""; // 识别类别结果 +string g_price=""; // 识别类别单价 +string g_weight=""; // 识别类别重量,默认为1kg,实际应用中可以接入重量传感器 + void print_usage() { cout << "模型推理时传参说明:" @@ -61,17 +76,130 @@ void print_usage() << endl; } -bool fileExists(const std::string &filename) { +bool file_exists(const std::string &filename) { std::ifstream file(filename.c_str()); return file.good(); } -int save_result(string recog_res) +bool removeFile(const std::string& filePath) { + if (remove(filePath.c_str()) == 0) { + return true; + } + return false; +} + +bool clearDirectory(const std::string& path) { + if (mkdir(path.c_str(), 0777) != 0) { + return false; + } + + DIR* dp = opendir(path.c_str()); + if (!dp) { + return false; + } + + struct dirent* entry; + + while ((entry = readdir(dp))) { + if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) { + std::string entryPath = path + "/" + entry->d_name; + struct stat statbuf; + + if (stat(entryPath.c_str(), &statbuf) == -1) { + return false; + } + + if (S_ISDIR(statbuf.st_mode)) { + // 递归删除子文件夹 + if (!clearDirectory(entryPath)) { + return false; + } + } else { + // 删除文件 + if (!removeFile(entryPath)) { + return false; + } + } + } + } + closedir(dp); + + return true; +} + +bool directoryExists(const std::string& path) { + struct stat info; + if (stat(path.c_str(), &info) != 0) { + return false; // 文件夹不存在 + } + + return (info.st_mode & S_IFDIR) != 0; // 文件夹存在 +} + +bool createDirectory(const std::string& path) { + if (mkdir(path.c_str(), 0777) == 0) { + return true; // 文件夹创建成功 + } + + return false; // 文件夹创建失败 +} + + +bool copyFile(const std::string &sourceFilePath,const std::string &destinationFilePath){ + std::ifstream sourceFile(sourceFilePath, std::ios::binary); + if (!sourceFile) { + std::cerr << "无法打开源文件: " << sourceFilePath << std::endl; + return 1; + } + std::ofstream destinationFile(destinationFilePath, std::ios::binary); + if (!destinationFile) { + std::cerr << "无法创建或打开目标文件: " << destinationFilePath << std::endl; + return 1; + } + // 逐个字节复制文件内容 + char buffer; + while (sourceFile.get(buffer)) { + destinationFile.put(buffer); + } + // 关闭文件 + sourceFile.close(); + destinationFile.close(); + + std::cout << "文件拷贝成功!" << std::endl; +} + +bool copytxtFile(const std::string &sourceFilePath,const std::string &destinationFilePath){ + std::ifstream sourceFile(sourceFilePath); // 打开源文件 + if (!sourceFile.is_open()) { + std::cerr << "无法打开源文件" << std::endl; + return false; + } + + std::ofstream destinationFile(destinationFilePath); // 创建或打开目标文件 + if (!destinationFile.is_open()) { + std::cerr << "无法创建或打开目标文件" << std::endl; + sourceFile.close(); // 关闭源文件 + return false; + } + + std::string line; + while (std::getline(sourceFile, line)) { + destinationFile << line << std::endl; // 逐行复制内容 + } + + sourceFile.close(); // 关闭源文件 + destinationFile.close(); // 关闭目标文件 + + return true; + +} + +int save_result(string file_name,string recog_res) { - std::ofstream outfile("res/result.txt"); + std::ofstream outfile(file_name); if (!outfile) { - std::cout << "无法打开文件 res/result.txt" << std::endl; + std::cout << "无法打开文件"+file_name << std::endl; return 1; } outfile << recog_res; @@ -100,22 +228,22 @@ double calculate_cosine_similarity(const std::vector &embedding1, const s return dot_product / (std::sqrt(norm_embedding1) * std::sqrt(norm_embedding2)); } -std::vector> calculate_cosine_similarity_with_all_files(const std::vector &target_embedding, const std::vector> &vector) +std::vector> calculate_cosine_similarity_with_all_files(const std::vector &target_embedding) { ScopedTiming st("calculate cosine similarity with all files", 2); std::vector> similarities; - for (size_t i = 0; i < vector.size(); ++i) + for (size_t i = 0; i < g_embeddings.size(); ++i) { - double similarity = calculate_cosine_similarity(target_embedding, vector[i]); + double similarity = calculate_cosine_similarity(target_embedding, g_embeddings[i]); similarities.push_back(std::make_pair(i, similarity)); } return similarities; } -std::pair, std::string> get_top_n_similar_files(const std::vector &target_embedding, const std::vector> &vector, const std::map &label_dict, size_t n, int debug_mode) +std::pair, std::string> get_top_n_similar_files(const std::vector &target_embedding, size_t n, int debug_mode) { ScopedTiming st("get top_k idx", debug_mode); - std::vector> similarities = calculate_cosine_similarity_with_all_files(target_embedding, vector); + std::vector> similarities = calculate_cosine_similarity_with_all_files(target_embedding); std::sort(similarities.begin(), similarities.end(), [](const auto &a, const auto &b) { return a.second > b.second; }); std::vector top_n_indices; @@ -127,7 +255,7 @@ std::pair, std::string> get_top_n_similar_files(const std::v std::vector top_labels; for (const auto &index : top_n_indices) { - top_labels.push_back(label_dict.at(index)); + top_labels.push_back(g_label_dict.at(index)); } std::map element_counts; for (const auto &label : top_labels) @@ -156,13 +284,8 @@ vector image_proc(string &kmodel_path, string &image_path, int debug_mode return result; } -std::pair, std::vector>> build_gallery( - std::string &kmodel_path, std::string &dataset_dir, int debug_mode -) { +int build_gallery(std::string &kmodel_path, std::string &dataset_dir, int debug_mode) { ScopedTiming st("build gallery", debug_mode); - std::map label_dict; - std::vector> vectors; - size_t idx = 0; GenEmbedding ge(kmodel_path, 0); // Open the directory using traditional method @@ -178,6 +301,9 @@ std::pair, std::vector>> build_ // Read the single label from labels.txt in each subdirectory std::string labels_file_path = category_dir_path + "/label.txt"; + if(!file_exists(labels_file_path)){ + continue; + } std::ifstream labels_file(labels_file_path); if (!labels_file.is_open()) { std::cerr << "Error: Could not open labels file for directory " << category_dir_path << std::endl; @@ -185,7 +311,8 @@ std::pair, std::vector>> build_ } std::string label_name; - if (std::getline(labels_file, label_name)) { + std::string shop_price; + if (std::getline(labels_file, label_name)&&std::getline(labels_file,shop_price)) { // Open and process images in the category directory DIR *image_dir; struct dirent *img_ent; @@ -196,6 +323,9 @@ std::pair, std::vector>> build_ continue; } std::string image_path = category_dir_path + "/" + image_name; + if(!file_exists(image_path)){ + continue; + } cv::Mat ori_img = cv::imread(image_path); int ori_w = ori_img.cols; int ori_h = ori_img.rows; @@ -203,26 +333,28 @@ std::pair, std::vector>> build_ ge.inference(); std::vector result; ge.post_process(result); - vectors.push_back(result); + g_embeddings.push_back(result); // Use the single label for all images in this category - label_dict[idx] = label_name; - idx++; + g_label_dict[g_img_idx] = label_name; + g_price_dict[g_img_idx] = std::stof(shop_price); + g_img_idx++; } closedir(image_dir); } } labels_file.close(); + g_max_classes_idx++; } closedir(dir); } else { std::cerr << "Error: Could not open directory " << dataset_dir << std::endl; } - return std::make_pair(label_dict, vectors); + return 0; } -void video_proc(string &kmodel_path, std::vector> &vectors, std::map &label_dict, size_t top_k, int debug_mode) +void video_proc(string &kmodel_path, size_t top_k, int debug_mode) { vivcap_start(); @@ -253,7 +385,16 @@ void video_proc(string &kmodel_path, std::vector> &vectors, s vector result; string weight_flag="flag/weight.txt"; + string select_flag="flag/select.txt"; + string import_flag="flag/import.txt"; + string clear_flag="flag/clear.txt"; bool rec_flag = false; + bool slc_flag=false; + bool add_class= false; + bool clr_flag=false; + int select_img_idx=0; + string new_class_floder_name=""; + while (!isp_stop) { ScopedTiming st("total time", debug_mode); @@ -278,12 +419,139 @@ void video_proc(string &kmodel_path, std::vector> &vectors, s kd_mpi_sys_munmap(vbvaddr, size); } - if (fileExists(weight_flag)){ + //如果采集标识文件存在,开始采集图片 + if(file_exists(select_flag)){ + if(slc_flag){ + + }else{ + Utils::dump_color_image("res/select.jpg",{SENSOR_WIDTH,SENSOR_HEIGHT}, reinterpret_cast(vaddr)); + std::ostringstream oss_s; + oss_s << select_img_idx; + std::string img_idx = oss_s.str(); + select_img_idx++; + if(!add_class){ + std::ostringstream oss_c; + oss_c << g_max_classes_idx; + std::string class_idx = oss_c.str(); + new_class_floder_name=g_dataset_dir+"/"+class_idx; + if (directoryExists(new_class_floder_name)) { + std::cout << "文件夹已存在" << std::endl; + } else { + if (createDirectory(new_class_floder_name)) { + std::cout << "文件夹创建成功" << std::endl; + add_class=true; + g_max_classes_idx++; + } else { + std::cerr << "无法创建文件夹" << std::endl; + } + } + }else{ + string source_path="res/select.jpg"; + string destination_path=new_class_floder_name+"/"+img_idx+".jpg"; + copyFile(source_path,destination_path); + } + slc_flag=true; + } + }else{ + if(slc_flag){ + slc_flag=false; + }else{ + + } + } + + //如果导入标识文件存在,开始添加新类别到embeddings + if(file_exists(import_flag)){ + if(file_exists("flag/goodinf.txt")) + { + string source_path="flag/goodinf.txt"; + string destination_path=new_class_floder_name+"/label.txt"; + copytxtFile(source_path,destination_path); + { + // Open the directory using traditional method + DIR *dir; + struct dirent *ent; + std::string category_dir_path = new_class_floder_name; + // Read the single label from labels.txt in each subdirectory + std::string labels_file_path = category_dir_path + "/label.txt"; + std::ifstream labels_file(labels_file_path); + if (!labels_file.is_open()) { + std::cerr << "Error: Could not open labels file for directory " << category_dir_path << std::endl; + continue; + } + + std::string label_name; + std::string shop_price; + if (std::getline(labels_file, label_name)&&std::getline(labels_file,shop_price)) { + // Open and process images in the category directory + DIR *image_dir; + struct dirent *img_ent; + if ((image_dir = opendir(category_dir_path.c_str())) != nullptr) { + while ((img_ent = readdir(image_dir)) != nullptr) { + std::string image_name = img_ent->d_name; + if (image_name == "." || image_name == ".." || image_name.substr(image_name.find_last_of(".") + 1) != "jpg") { + continue; + } + std::string image_path = category_dir_path + "/" + image_name; + cv::Mat ori_img = cv::imread(image_path); + int ori_w = ori_img.cols; + int ori_h = ori_img.rows; + ge.pre_process(ori_img); + ge.inference(); + std::vector result; + ge.post_process(result); + g_embeddings.push_back(result); + // Use the single label for all images in this category + g_label_dict[g_img_idx] = label_name; + g_price_dict[g_img_idx] = std::stof(shop_price); + g_img_idx++; + + } + closedir(image_dir); + } + } + labels_file.close(); + } + std::remove("flag/goodinf.txt"); + std::remove(import_flag.c_str()); + select_img_idx=0; + add_class=false; + new_class_floder_name=""; + + } + + } + + if(file_exists(clear_flag)){ + if(clr_flag){ + + }else{ + std::ostringstream oss_c; + oss_c << (g_max_classes_idx-1); + std::string class_idx = oss_c.str(); + string newest_class_path=g_dataset_dir+"/"+class_idx; + cout<(vaddr)); + Utils::dump_color_image("res/res.jpg",{SENSOR_WIDTH,SENSOR_HEIGHT}, reinterpret_cast(vaddr)); result.clear(); ge.pre_process(); ge.inference(); @@ -305,10 +573,10 @@ void video_proc(string &kmodel_path, std::vector> &vectors, s cv::Mat osd_frame(osd_height, osd_width, CV_8UC4, cv::Scalar(0, 0, 0, 0)); cv::Mat osd_frame_tmp; - if(fileExists(weight_flag) && rec_flag){ + if(file_exists(weight_flag) && rec_flag){ ScopedTiming st("embedding search", debug_mode); // Get the top k similar files - std::pair, std::string> indexis = get_top_n_similar_files(result, vectors, label_dict, top_k, debug_mode); + std::pair, std::string> indexis = get_top_n_similar_files(result, top_k, debug_mode); // Print the result std::cout << "Top " << top_k << " similar file indices:["; for (const auto &idx : indexis.first) @@ -316,10 +584,11 @@ void video_proc(string &kmodel_path, std::vector> &vectors, s std::cout << " " << idx; } std::cout << "] Recognition result: " << indexis.second << std::endl; - string text = indexis.second; - // string text=""; - save_result(text); - Utils::draw_rec_res(osd_frame, text, {osd_width, osd_height}, {SENSOR_WIDTH, SENSOR_HEIGHT}); + g_result = indexis.second; + g_weight=std::to_string(1); + g_price=std::to_string(1*g_price_dict.at(indexis.first[0])); + string text=g_result+"\n"+g_weight+"\n"+g_price; + save_result("res/result.txt",text); } { @@ -351,14 +620,10 @@ void video_proc(string &kmodel_path, std::vector> &vectors, s void image_recognition(string &kmodel_path, string &image_path, string &dataset_dir, int top_k, int debug_mode) { - std::pair, std::vector>> res = build_gallery(kmodel_path,dataset_dir,debug_mode); - // Read the vectors - std::vector> vectors = res.second; - // Generate the labels dictionary - std::map label_dict = res.first; + build_gallery(kmodel_path,dataset_dir,debug_mode); std::vector target_embedding = image_proc(kmodel_path, image_path, debug_mode); // Get the top k similar files - std::pair, std::string> result = get_top_n_similar_files(target_embedding, vectors, label_dict, top_k, debug_mode); + std::pair, std::string> result = get_top_n_similar_files(target_embedding, top_k, debug_mode); // Print the result std::cout << "Top " << top_k << " similar file indices:"; for (const auto &index : result.first) @@ -375,12 +640,8 @@ void video_recognition(char *argv[]) string dataset_dir=argv[3]; size_t top_k = std::stoi(argv[4]); int debug_mode = std::stoi(argv[5]); - std::pair, std::vector>> res = build_gallery(kmodel_path,dataset_dir,debug_mode); - // Read the vectors - std::vector> vectors = res.second; - // Generate the labels dictionary - std::map label_dict = res.first; - video_proc(kmodel_path, vectors, label_dict, top_k, debug_mode); + build_gallery(kmodel_path,dataset_dir,debug_mode); + video_proc(kmodel_path, top_k, debug_mode); } int main(int argc, char *argv[]) @@ -396,6 +657,7 @@ int main(int argc, char *argv[]) string dataset_dir=argv[3]; size_t top_k = std::stoi(argv[4]); int debug_mode = std::stoi(argv[5]); + g_dataset_dir=dataset_dir; // video if (strcmp(argv[2], "None") == 0) { @@ -411,7 +673,7 @@ int main(int argc, char *argv[]) // image else { - image_recognition(kmodel_path, image_path,dataset_dir, top_k, debug_mode); + image_recognition(kmodel_path, image_path, dataset_dir, top_k, debug_mode); } return 0; } diff --git a/src/reference/fancy_poc/ai_scale/src/ai_scale_client/client.cc b/src/reference/fancy_poc/ai_scale/src/ai_scale_client/client.cc index 73c4f9ea5..10cfa257c 100644 --- a/src/reference/fancy_poc/ai_scale/src/ai_scale_client/client.cc +++ b/src/reference/fancy_poc/ai_scale/src/ai_scale_client/client.cc @@ -1,3 +1,27 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #include #include #include @@ -6,61 +30,98 @@ #include #include #include +#include #include #include #include #include #include +#include +#include using namespace std; +const int BUFFER_SIZE = 4096; +const int COMMAND_SIZE = 1024; + // 新的函数用于发送响应消息 bool sendResponse(int socket, const char* response) { ssize_t bytes_sent = send(socket, response, strlen(response), 0); if (bytes_sent == -1) { - std::cerr << "发送响应失败" << std::endl; + cerr << "发送响应失败" << endl; + return false; + } + return true; +} + +bool isDirectory(const char* path) { + struct stat path_stat; + if (stat(path, &path_stat) != 0) { + return false; + } + return S_ISDIR(path_stat.st_mode); +} + +bool deleteDirectory(const char* path) { + DIR* dir = opendir(path); + if (!dir) { return false; } + + struct dirent* entry; + while ((entry = readdir(dir)) != nullptr) { + if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) { + char entryPath[PATH_MAX]; + snprintf(entryPath, sizeof(entryPath), "%s/%s", path, entry->d_name); + + if (isDirectory(entryPath)) { + deleteDirectory(entryPath); + } else { + std::remove(entryPath); + } + } + } + closedir(dir); + std::remove(path); return true; } -std::string read_result(const std::string& file_path) { - std::string result=""; - std::ifstream file(file_path); + +string readResult(const string& file_path) { + string result = ""; + ifstream file(file_path); if (file.is_open()) { - std::string line; - while (std::getline(file, line)) { + string line; + while (getline(file, line)) { result += line + '\n'; } file.close(); } else { - std::cerr << "无法打开文件:" << file_path << std::endl; + cerr << "无法打开文件:" << file_path << endl; } return result; } -int sendImagesToServer(int client_socket) { - // 打开 res.jpg 文件 - FILE* image_file = fopen("res/res.png", "rb"); - if (image_file == NULL) { +int sendFileToServer(int client_socket, const char* file_path) { + FILE* image_file = fopen(file_path, "rb"); + if (image_file == nullptr) { perror("无法打开图片文件"); return 2; } - // 获取文件大小 + fseek(image_file, 0, SEEK_END); long image_size = ftell(image_file); fseek(image_file, 0, SEEK_SET); - // 将文件大小发送到服务器 + if (send(client_socket, &image_size, sizeof(image_size), 0) == -1) { - std::cerr << "Error sending image size to server" << std::endl; - // close(client_socket); + cerr << "Error sending image size to server" << endl; + fclose(image_file); return -1; } - // 读取文件内容并发送给服务器 - // vector image_data = read_binary_file(image_file); - char buffer[4096]; + + char buffer[BUFFER_SIZE]; while (image_size > 0) { size_t read_size = fread(buffer, 1, sizeof(buffer), image_file); if (read_size <= 0) { @@ -77,133 +138,192 @@ int sendImagesToServer(int client_socket) { } image_size -= sent_size; } - // 关闭文件 + fclose(image_file); - if (image_size<=0){ + if (image_size <= 0) { return 0; - }else{ + } else { return 5; } } - void handleCommand(int client_socket, const char* command) { if (strcmp(command, "on") == 0) { - // 创建一个文件 - std::ofstream file("flag/weight.txt"); + ofstream file("flag/weight.txt"); if (file.is_open()) { file.close(); + cout << "已创建文件 flag/weight.txt" << endl; } - sendResponse(client_socket,"image"); + sendResponse(client_socket, "image"); int count=0; - while(1){ - if((access("res/res.png", F_OK) != -1)){ - int res=sendImagesToServer(client_socket); - if(res==0){ - break; - }else{ - continue; - } + while (access("res/res.jpg", F_OK) == -1) { + this_thread::sleep_for(chrono::seconds(1)); + count++; + if(count>200){ + break; } - std::this_thread::sleep_for(std::chrono::seconds(1)); - } - - }else if(strcmp(command, "get") == 0){ - sendResponse(client_socket,"result"); - while(1){ - if((access("res/result.txt", F_OK) != -1)){ - string result=read_result("res/result.txt"); - if(result==""){ - - }else{ - sendResponse(client_socket,result.c_str()); - break; - } - + } + + int res = sendFileToServer(client_socket, "res/res.jpg"); + if (res == 0) { + cout << "image图片发送成功" << endl; + } + } else if (strcmp(command, "get") == 0) { + sendResponse(client_socket, "result"); + + while (access("res/result.txt", F_OK) == -1) { + this_thread::sleep_for(chrono::seconds(1)); + } + + string result = readResult("res/result.txt"); + if (!result.empty()) { + sendResponse(client_socket, result.c_str()); + } + } else if (strcmp(command, "select") == 0) { + ofstream file("flag/select.txt"); + if (file.is_open()) { + file.close(); + cout << "已创建文件 flag/select.txt" << endl; + } + sendResponse(client_socket, "select"); + + int count=0; + while (access("res/select.jpg", F_OK) == -1) { + this_thread::sleep_for(chrono::seconds(1)); + count++; + if(count>200){ + break; } - std::this_thread::sleep_for(std::chrono::seconds(1)); } - }else if (strcmp(command, "down") == 0) { - // 删除文件 + int res = sendFileToServer(client_socket, "res/select.jpg"); + if (res == 0) { + cout << "select图片发送成功" << endl; + remove("./flag/select.txt"); + remove("./res/select.jpg"); + } + } else if (strcmp(command, "import") == 0) { + char buffer[BUFFER_SIZE]; + memset(buffer, 0, sizeof(buffer)); + int bytesRead = recv(client_socket, buffer, sizeof(buffer), 0); + if (bytesRead < 0) { + perror("Error in receiving data"); + exit(EXIT_FAILURE); + } + + string receivedString(buffer); + ofstream outputFile("flag/goodinf.txt"); + if (!outputFile) { + perror("Error in opening goodinf.txt"); + exit(EXIT_FAILURE); + } + outputFile << receivedString; + outputFile.close(); + + ofstream file("flag/import.txt"); + if (file.is_open()) { + file.close(); + cout << "已创建文件 flag/import.txt" << endl; + sendResponse(client_socket, "import"); + } + }else if (strcmp(command, "clear") == 0) { + ofstream file("flag/clear.txt"); + if (file.is_open()) { + file.close(); + cout << "已创建文件 flag/clear.txt" << endl; + + } + + while (access("flag/clear_c.txt", F_OK) == -1) { + this_thread::sleep_for(chrono::seconds(1)); + } + string folderpath=readResult("flag/clear_c.txt"); + if(deleteDirectory(folderpath.c_str())){ + remove("falg/clear.txt"); + remove("flag/clear_c.txt"); + } + else{ + + } + sendResponse(client_socket, "clear"); + } else if (strcmp(command, "down") == 0) { if (remove("flag/weight.txt") == 0) { - // std::cout << "已删除文件 flag/weight.txt" << std::endl; + cout << "已删除文件 flag/weight.txt" << endl; } else { - std::cerr << "无法删除文件" << std::endl; + cerr << "无法删除文件" << endl; } - if ((remove("res/res.png") == 0)) { - // std::cout << "成功删除 res/res.png文件" << std::endl; + if (remove("res/res.jpg") == 0) { + cout << "成功删除 res/res.jpg 文件" << endl; } else { - perror("无法删除 res/res.png文件"); + perror("无法删除 res/res.jpg 文件"); } - if ((remove("res/result.txt") == 0)) { - // std::cout << "成功删除 res/result.txt文件" << std::endl; + if (remove("res/result.txt") == 0) { + cout << "成功删除 res/result.txt 文件" << endl; sendResponse(client_socket, "stop"); } else { - perror("无法删除 res/result.txt文件"); + perror("无法删除 res/result.txt 文件"); } - }else if(strcmp(command, "close") == 0){ + } else if (strcmp(command, "close") == 0) { close(client_socket); exit(0); - - }else { - std::cerr << "未知命令: " << command << std::endl; - sendResponse(client_socket, "unknown"); // 发送未知命令消息 + } else { + cerr << "未知命令: " << command << endl; + sendResponse(client_socket, "unknown"); } } int main(int argc, char *argv[]) { if (argc != 3) { - std::cerr << "Usage: " << argv[0] << " " << std::endl; + cerr << "Usage: " << argv[0] << " " << endl; return EXIT_FAILURE; } - const char* server_ip = argv[1];// 服务器的IP地址 - int server_port = std::atoi(argv[2]);// 服务器的端口号 + const char* server_ip = argv[1]; + int server_port = atoi(argv[2]); - // 创建套接字 int client_socket = socket(AF_INET, SOCK_STREAM, 0); if (client_socket == -1) { perror("无法创建套接字"); exit(EXIT_FAILURE); } - // 设置服务器地址信息 struct sockaddr_in server_address; server_address.sin_family = AF_INET; server_address.sin_port = htons(server_port); if (inet_pton(AF_INET, server_ip, &(server_address.sin_addr)) <= 0) { - perror("无法设置服务器地址"); + perror("无法设置服务器地址"); close(client_socket); exit(EXIT_FAILURE); } - // 连接到服务器 if (connect(client_socket, (struct sockaddr*)&server_address, sizeof(server_address)) == -1) { perror("连接到服务器失败"); close(client_socket); exit(EXIT_FAILURE); } - // 连接成功,接收服务器命令 - char command[1024]; + char command[COMMAND_SIZE]; while (1) { ssize_t bytes_received = recv(client_socket, command, sizeof(command), 0); if (bytes_received <= 0) { - + // 处理接收错误 + cerr << "与服务器的连接已断开" << endl; + close(client_socket); + exit(EXIT_FAILURE); } else { command[bytes_received] = '\0'; - // std::cout << "收到命令:" << command << std::endl; - if(strcmp(command, "close") == 0){ + cout << "收到命令:" << command << endl; + if (strcmp(command, "close") == 0) { close(client_socket); exit(0); } - handleCommand(client_socket,command); + handleCommand(client_socket, command); } } - // 关闭套接字 close(client_socket); return 0; } + + diff --git a/src/reference/fancy_poc/ai_scale/src/download.sh b/src/reference/fancy_poc/ai_scale/src/download.sh index 147feae39..68a920fd1 100644 --- a/src/reference/fancy_poc/ai_scale/src/download.sh +++ b/src/reference/fancy_poc/ai_scale/src/download.sh @@ -1,9 +1,10 @@ +#######download.sh######## for file in AIScale.zip; do wget https://ai.b-bug.org/k230/downloads/fancy_poc/ai_scale/$file || wget https://kendryte-download.canaan-creative.com/k230/downloads/fancy_poc/ai_scale/$file; done -for file in onboard_v2.4.zip +for file in onboard_v2.5.zip do wget https://ai.b-bug.org/k230/downloads/fancy_poc/ai_scale/k230_board/$file || wget https://kendryte-download.canaan-creative.com/k230/downloads/fancy_poc/ai_scale/k230_board/$file; -done \ No newline at end of file +done diff --git a/src/reference/fancy_poc/ai_scale/src/utils/ai_scale_isp.sh b/src/reference/fancy_poc/ai_scale/src/utils/ai_scale_isp.sh index b2744f987..521afa4b0 100644 --- a/src/reference/fancy_poc/ai_scale/src/utils/ai_scale_isp.sh +++ b/src/reference/fancy_poc/ai_scale/src/utils/ai_scale_isp.sh @@ -1,2 +1,2 @@ set -x -./ai_scale.elf recognition.kmodel None gallery 5 1 \ No newline at end of file +./ai_scale.elf recognition.kmodel None gallery 5 1 diff --git a/src/reference/fancy_poc/ai_scale/src/utils/connect.sh b/src/reference/fancy_poc/ai_scale/src/utils/connect.sh index bb8cae645..bd761a0cf 100644 --- a/src/reference/fancy_poc/ai_scale/src/utils/connect.sh +++ b/src/reference/fancy_poc/ai_scale/src/utils/connect.sh @@ -1,4 +1,3 @@ - #!/bin/bash set -x diff --git a/src/reference/fancy_poc/finger_reader/src/download.sh b/src/reference/fancy_poc/finger_reader/src/download.sh index d30284471..dc3a3b55b 100644 --- a/src/reference/fancy_poc/finger_reader/src/download.sh +++ b/src/reference/fancy_poc/finger_reader/src/download.sh @@ -1,5 +1,5 @@ -for file in onboard_v2.4.zip +for file in onboard_v2.5.zip do wget https://ai.b-bug.org/k230/downloads/fancy_poc/finger_reader/k230_board/$file || wget https://kendryte-download.canaan-creative.com/k230/downloads/fancy_poc/finger_reader/k230_board/$file; done diff --git a/src/reference/fancy_poc/finger_reader/src/finger_reader_server/config.json b/src/reference/fancy_poc/finger_reader/src/finger_reader_server/config.json index adc2937a1..80b8b264a 100644 --- a/src/reference/fancy_poc/finger_reader/src/finger_reader_server/config.json +++ b/src/reference/fancy_poc/finger_reader/src/finger_reader_server/config.json @@ -1,5 +1,5 @@ { - "open_ai_api_key": "xxxxxxxxxxxxxxxxxxx", + "open_ai_api_key": "xxxxxxxxxxxxxxxxx", "model": "gpt-3.5-turbo-0613", "proxy": "", "speech_recognition": false, diff --git a/src/reference/fancy_poc/finger_reader/src/finger_reader_server/ocr.txt b/src/reference/fancy_poc/finger_reader/src/finger_reader_server/ocr.txt index d2ce0e3f9..41dec1575 100644 --- a/src/reference/fancy_poc/finger_reader/src/finger_reader_server/ocr.txt +++ b/src/reference/fancy_poc/finger_reader/src/finger_reader_server/ocr.txt @@ -1 +1 @@ -薪新的硅基文明而嘉楠已经成为这场探险的领跑者前路依然漫长请保持足够的技术自信与敬畏之心因为你们不仅是名嘉楠人更是名探索数字世界未来的探险家因为我们选择去月球 \ No newline at end of file +什么都没有 \ No newline at end of file diff --git a/src/reference/fancy_poc/finger_reader/src/finger_reader_server/text_to_speech/output_wav/zh_mono.wav b/src/reference/fancy_poc/finger_reader/src/finger_reader_server/text_to_speech/output_wav/zh_mono.wav index bd349bfc2..81a325a53 100644 Binary files a/src/reference/fancy_poc/finger_reader/src/finger_reader_server/text_to_speech/output_wav/zh_mono.wav and b/src/reference/fancy_poc/finger_reader/src/finger_reader_server/text_to_speech/output_wav/zh_mono.wav differ diff --git a/src/reference/fancy_poc/finger_reader/src/finger_reader_server/text_to_speech/output_wav/zh_stereo.wav b/src/reference/fancy_poc/finger_reader/src/finger_reader_server/text_to_speech/output_wav/zh_stereo.wav index 3055a3f87..761b57b3b 100644 Binary files a/src/reference/fancy_poc/finger_reader/src/finger_reader_server/text_to_speech/output_wav/zh_stereo.wav and b/src/reference/fancy_poc/finger_reader/src/finger_reader_server/text_to_speech/output_wav/zh_stereo.wav differ diff --git a/src/reference/fancy_poc/housekeeper/readme.md b/src/reference/fancy_poc/housekeeper/readme.md index a2d851a4b..d9dddec92 100644 --- a/src/reference/fancy_poc/housekeeper/readme.md +++ b/src/reference/fancy_poc/housekeeper/readme.md @@ -228,7 +228,7 @@ LLM模型可以给出计算IOU的正确代码,但是无法通过两个检测 ## 环境准备 #######download.sh######## - for file in onboard_v2.4.zip + for file in onboard_v2.5.zip do wget https://ai.b-bug.org/k230/downloads/fancy_poc/housekeeper/k230_board/$file || wget https://kendryte-download.canaan-creative.com/k230/downloads/fancy_poc/housekeeper/k230_board/$file; done diff --git a/src/reference/fancy_poc/housekeeper/src/download.sh b/src/reference/fancy_poc/housekeeper/src/download.sh index e3e56fe68..d11cff3fd 100644 --- a/src/reference/fancy_poc/housekeeper/src/download.sh +++ b/src/reference/fancy_poc/housekeeper/src/download.sh @@ -1,5 +1,5 @@ -for file in onboard_v2.4.zip +for file in onboard_v2.5.zip do wget https://ai.b-bug.org/k230/downloads/fancy_poc/housekeeper/k230_board/$file || wget https://kendryte-download.canaan-creative.com/k230/downloads/fancy_poc/housekeeper/k230_board/$file; done diff --git a/src/reference/fancy_poc/meta_hand/README.md b/src/reference/fancy_poc/meta_hand/README.md index 35027178d..4b785150f 100644 --- a/src/reference/fancy_poc/meta_hand/README.md +++ b/src/reference/fancy_poc/meta_hand/README.md @@ -22,7 +22,7 @@ Document version: V1.0 Release date: 2023-9-1 wget https://ai.b-bug.org/k230/downloads/fancy_poc/meta_hand/$file || wget https://kendryte-download.canaan-creative.com/k230/downloads/fancy_poc/meta_hand/$file; done - for file in onboard_v2.4.zip + for file in onboard_v2.5.zip do wget https://ai.b-bug.org/k230/downloads/fancy_poc/meta_hand/k230_board/$file || wget https://kendryte-download.canaan-creative.com/k230/downloads/fancy_poc/meta_hand/k230_board/$file; done diff --git a/src/reference/fancy_poc/meta_hand/src/download.sh b/src/reference/fancy_poc/meta_hand/src/download.sh index b0317781d..3d2d21d82 100644 --- a/src/reference/fancy_poc/meta_hand/src/download.sh +++ b/src/reference/fancy_poc/meta_hand/src/download.sh @@ -3,7 +3,7 @@ do wget https://ai.b-bug.org/k230/downloads/fancy_poc/meta_hand/$file || wget https://kendryte-download.canaan-creative.com/k230/downloads/fancy_poc/meta_hand/$file; done -for file in onboard_v2.4.zip +for file in onboard_v2.5.zip do wget https://ai.b-bug.org/k230/downloads/fancy_poc/meta_hand/k230_board/$file || wget https://kendryte-download.canaan-creative.com/k230/downloads/fancy_poc/meta_hand/k230_board/$file; done diff --git a/src/reference/fancy_poc/meta_human/README.md b/src/reference/fancy_poc/meta_human/README.md index 0598899b0..478795440 100644 --- a/src/reference/fancy_poc/meta_human/README.md +++ b/src/reference/fancy_poc/meta_human/README.md @@ -44,7 +44,7 @@ do wget https://ai.b-bug.org/k230/downloads/fancy_poc/meta_human/$file || wget https://kendryte-download.canaan-creative.com/k230/downloads/fancy_poc/meta_human/$file; done -for file in onboard_v2.4.zip +for file in onboard_v2.5.zip do wget https://ai.b-bug.org/k230/downloads/fancy_poc/meta_human/k230_board/$file || wget https://kendryte-download.canaan-creative.com/k230/downloads/fancy_poc/meta_human/k230_board/$file; done diff --git a/src/reference/fancy_poc/meta_human/src/download.sh b/src/reference/fancy_poc/meta_human/src/download.sh index 40445a8a1..5c734f9f7 100644 --- a/src/reference/fancy_poc/meta_human/src/download.sh +++ b/src/reference/fancy_poc/meta_human/src/download.sh @@ -5,7 +5,7 @@ do wget https://ai.b-bug.org/k230/downloads/fancy_poc/meta_human/$file || wget https://kendryte-download.canaan-creative.com/k230/downloads/fancy_poc/meta_human/$file; done -for file in onboard_v2.4.zip +for file in onboard_v2.5.zip do wget https://ai.b-bug.org/k230/downloads/fancy_poc/meta_human/k230_board/$file || wget https://kendryte-download.canaan-creative.com/k230/downloads/fancy_poc/meta_human/k230_board/$file; done diff --git a/src/reference/fancy_poc/meta_human/src/http/main.cc b/src/reference/fancy_poc/meta_human/src/http/main.cc index 78b234160..3b44db2b4 100644 --- a/src/reference/fancy_poc/meta_human/src/http/main.cc +++ b/src/reference/fancy_poc/meta_human/src/http/main.cc @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include "scoped_timing.hpp" @@ -16,7 +16,6 @@ using namespace std; std::string readBinInt(std::string path) { - ifstream file2(path, std::ios::binary); int len2 = 0; file2.read((char*)&len2, sizeof(len2)); @@ -66,11 +65,10 @@ bool createFolder(string folderPath) { int main(int argc, char *argv[]) { - cout << ">>>>> Start!! <<<<<" << endl; - std::string aaa,abb; - std::string bbb; - bool flag0, flag1; + std::string cur; + std::string next; + bool flag_cur, flag_next; int idx = 0; std::string ping = "ping"; @@ -128,7 +126,6 @@ int main(int argc, char *argv[]) std::string execute_folder = ping; std::string not_execute_folder = pong; - const char *server_ip = "192.168.1.2"; int server_port = 8080; int sock = socket(AF_INET, SOCK_STREAM, 0); @@ -146,7 +143,6 @@ int main(int argc, char *argv[]) isConnect = connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)); } - { while(isConnect < 0) { @@ -159,7 +155,6 @@ int main(int argc, char *argv[]) while(1) { - std::string execute_first_bin = execute_folder + "/" + std::to_string(0) + "_0.bin"; std::string not_execute_first_bin = not_execute_folder + "/" + std::to_string(0) + "_0.bin"; @@ -184,7 +179,6 @@ int main(int argc, char *argv[]) } } - { if(Is_File_Exist(not_execute_first_bin)) { @@ -205,22 +199,19 @@ int main(int argc, char *argv[]) idx = 0; } } - - aaa = execute_folder + "/" + std::to_string(idx); - bbb = execute_folder + "/" + std::to_string(idx+1); + cur = execute_folder + "/" + std::to_string(idx); + next = execute_folder + "/" + std::to_string(idx+1); - flag0 = Is_File_Exist( bbb + "_0.bin" ); - flag1 = Is_File_Exist( bbb + "_1.bin" ); + flag_cur = Is_File_Exist( next + "_0.bin" ); + flag_next = Is_File_Exist( next + "_1.bin" ); - if(flag1 && flag0) + if(flag_next && flag_cur) { - // std::cout << " >>>>>> " << execute_folder << " : " <<" std::to_string(idx)= " << std::to_string(idx) << " <<<<<<<" << std::endl; - // ScopedTiming st("trans time", 1); string out_bin_pth_file; dump_bin_.clear(); dump_bin_float.clear(); - out_bin_pth_file = aaa + "_0.bin"; + out_bin_pth_file = cur + "_0.bin"; { if(Is_File_Exist( out_bin_pth_file )) @@ -231,11 +222,10 @@ int main(int argc, char *argv[]) if(Is_File_Exist( out_bin_pth_file )) { - out_bin_pth_file = aaa + "_1.bin"; + out_bin_pth_file = cur + "_1.bin"; auto buff_float_1 = read_binary_file(out_bin_pth_file.c_str()); dump_bin_float.insert(dump_bin_float.end(), buff_float_1.begin(), buff_float_1.end()); } - } { @@ -258,15 +248,13 @@ int main(int argc, char *argv[]) sent_bytes += bytes_sent; } } - { - remove((aaa + "_0.bin").c_str()); - remove((aaa + "_1.bin").c_str()); + remove((cur + "_0.bin").c_str()); + remove((cur + "_1.bin").c_str()); } idx = idx + 1; - } else { diff --git a/src/reference/fancy_poc/meta_human/src/meta_human/main.cc b/src/reference/fancy_poc/meta_human/src/meta_human/main.cc index 58387655d..2038c83b7 100644 --- a/src/reference/fancy_poc/meta_human/src/meta_human/main.cc +++ b/src/reference/fancy_poc/meta_human/src/meta_human/main.cc @@ -36,28 +36,12 @@ #include "meta_human.h" - using std::cerr; using std::cout; using std::endl; std::atomic isp_stop(false); -bool isFolderExist(string folderPath) { - struct stat info; - if (stat(folderPath.c_str(), &info) != 0) { - return false; - } - return (info.st_mode & S_IFDIR); -} - -bool createFolder(string folderPath) { - if (mkdir(folderPath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) { - return false; - } - return true; -} - void print_usage(const char *name) { cout << "Usage: " << name << " " << endl @@ -105,8 +89,6 @@ void video_proc(char *argv[]) while (!isp_stop) { ScopedTiming st("total time", 1); - - { ScopedTiming st("read capture", atoi(argv[3])); // VICAP_CHN_ID_1 out rgb888p @@ -117,7 +99,6 @@ void video_proc(char *argv[]) continue; } } - { ScopedTiming st("isp copy", atoi(argv[3])); @@ -134,17 +115,14 @@ void video_proc(char *argv[]) idx++; if( idx == 2*num_storage ) - // std::this_thread::sleep_for(std::chrono::milliseconds(15) ); idx = 0; cv::Mat osd_frame(osd_height, osd_width, CV_8UC4, cv::Scalar(0, 0, 0, 0)); - { ScopedTiming st("osd copy", atoi(argv[3])); memcpy(pic_vaddr, osd_frame.data, osd_width * osd_height * 4); //显示通道插入帧 - kd_mpi_vo_chn_insert_frame(osd_id+3, &vf_info); //K_VO_OSD0 - // printf("kd_mpi_vo_chn_insert_frame success \n"); + kd_mpi_vo_chn_insert_frame(osd_id+3, &vf_info); ret = kd_mpi_vicap_dump_release(vicap_dev, VICAP_CHN_ID_1, &dump_info); if (ret) { @@ -156,7 +134,6 @@ void video_proc(char *argv[]) vo_osd_release_block(); vivcap_stop(); - // free memory ret = kd_mpi_sys_mmz_free(paddr, vaddr); if (ret) @@ -164,10 +141,8 @@ void video_proc(char *argv[]) std::cerr << "free failed: ret = " << ret << ", errno = " << strerror(errno) << std::endl; std::abort(); } - } - int main(int argc, char *argv[]) { std::cout << "case " << argv[0] << " built at " << __DATE__ << " " << __TIME__ << std::endl; @@ -177,29 +152,6 @@ int main(int argc, char *argv[]) return -1; } - std::string ping = "ping"; - std::string pong = "pong"; - - if (!isFolderExist(ping)) { - if (!createFolder(ping)) { - cout << "create 'ping' folder failed!!" << endl; - return 1; - } - cout << "create 'ping' folder success!!" << endl; - } else { - cout << "'ping' folder has existed!!" << endl; - } - - if (!isFolderExist(pong)) { - if (!createFolder(pong)) { - cout << "create 'ping' folder failed!!" << endl; - return 1; - } - cout << "create 'ping' folder success!!" << endl; - } else { - cout << "'ping' folder has existed!!" << endl; - } - if (strcmp(argv[2], "None") == 0) { std::thread thread_isp(video_proc, argv); @@ -219,9 +171,7 @@ int main(int argc, char *argv[]) Meta_Human mhuman(argv[1],atoi(argv[3])); mhuman.pre_process(ori_img); - mhuman.inference(); - mhuman.post_process({ori_w, ori_h},0,100); } diff --git a/src/reference/fancy_poc/meta_human/src/meta_human/meta_human.cc b/src/reference/fancy_poc/meta_human/src/meta_human/meta_human.cc index 03ef234a9..dee4897c4 100644 --- a/src/reference/fancy_poc/meta_human/src/meta_human/meta_human.cc +++ b/src/reference/fancy_poc/meta_human/src/meta_human/meta_human.cc @@ -24,17 +24,11 @@ */ #include "meta_human.h" -bool Is_File_Exist(const std::string& file_path) -{ - std::ifstream file(file_path.c_str()); - return file.good(); -} void writeBin0(std::string path, char *buf, int size) { std::ofstream outfile(path, std::ifstream::binary); outfile.write((char *)(buf), size); - // outfile.write((float *)(buf), size); outfile.close(); } @@ -50,7 +44,6 @@ void writeBinInt(std::string path, int num) std::string readBinInt(std::string path) { - ifstream file2(path, std::ios::binary); int len2 = 0; file2.read((char*)&len2, sizeof(len2)); @@ -64,7 +57,6 @@ std::string readBinInt(std::string path) return str2; } - // for image Meta_Human::Meta_Human(const char *kmodel_file,const int debug_mode):AIBase(kmodel_file,"Meta_Human", debug_mode) { @@ -89,15 +81,12 @@ Meta_Human::Meta_Human(const char *kmodel_file, FrameCHWSize isp_shape, uintptr ai2d_in_tensor_ = hrt::create(typecode_t::dt_uint8, in_shape, hrt::pool_shared).expect("create ai2d input tensor failed"); #endif - // ai2d_out_tensor ai2d_out_tensor_ = get_input_tensor(0); - // fixed padding resize param Utils::padding_resize(isp_shape_, {input_shapes_[0][3], input_shapes_[0][2]}, ai2d_builder_, ai2d_in_tensor_, ai2d_out_tensor_, cv::Scalar(104, 117, 123)); } Meta_Human::~Meta_Human() { - } // ai2d for image @@ -120,12 +109,8 @@ void Meta_Human::pre_process() auto buf = ai2d_in_tensor_.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_write).unwrap().buffer(); memcpy(reinterpret_cast(buf.data()), (void *)vaddr_, isp_size); hrt::sync(ai2d_in_tensor_, sync_op_t::sync_write_back, true).expect("sync write_back failed"); - // ai2d_builder_->invoke().expect("error occurred in ai2d running"); ai2d_builder_->invoke(ai2d_in_tensor_,ai2d_out_tensor_).expect("error occurred in ai2d running"); - // run ai2d #endif - // auto vaddr_out_buf = ai2d_out_tensor_.impl()->to_host().unwrap()->buffer().as_host().unwrap().map(map_access_::map_read).unwrap().buffer(); - // unsigned char *output = reinterpret_cast(vaddr_out_buf.data()); } void Meta_Human::inference() @@ -154,11 +139,7 @@ void Meta_Human::post_process(FrameSize frame_size,int idx,int num_storage) writeBin0( "pong/" + std::to_string(idx_) + "_0.bin",(char* )output_0, 1 * net_len/8 * net_len/8 * 1 * 4); writeBin0( "pong/" + std::to_string(idx_) + "_1.bin",(char *)output_1, 1 * net_len/8 * net_len/8 * 145 * 4); } - } - - - } diff --git a/src/reference/fancy_poc/meta_human/src/meta_human/meta_human.h b/src/reference/fancy_poc/meta_human/src/meta_human/meta_human.h index e4ca8f856..12a16c17a 100644 --- a/src/reference/fancy_poc/meta_human/src/meta_human/meta_human.h +++ b/src/reference/fancy_poc/meta_human/src/meta_human/meta_human.h @@ -32,9 +32,6 @@ #include "ai_base.h" - - - /** * @brief 人体Mesh模型捕捉 * 主要封装了对于每一帧图片,从预处理、运行到后处理给出结果的过程 @@ -51,7 +48,6 @@ class Meta_Human: public AIBase */ Meta_Human(const char *kmodel_file,const int debug_mode); - /** * for video * @brief Meta_Human 构造函数,加载kmodel,并初始化kmodel输入、输出、类阈值和NMS阈值 @@ -68,7 +64,6 @@ class Meta_Human: public AIBase * @brief Meta_Human析构函数 * @return None */ - ~Meta_Human(); /** @@ -92,8 +87,8 @@ class Meta_Human: public AIBase /** * @brief Meta_Human post_process 函数,对kmodel输出进行后处理操作 - * param frame_size 帧率 - * idx 记录打印序次 + * @param frame_size 帧率 + * @param idx 记录打印序次 * @return None */ void post_process(FrameSize frame_size,int idx,int num_storage); @@ -105,6 +100,5 @@ class Meta_Human: public AIBase runtime_tensor ai2d_out_tensor_; // ai2d输出tensor uintptr_t vaddr_; // isp的虚拟地址 FrameCHWSize isp_shape_; // isp对应的地址大小 - }; #endif diff --git a/src/reference/fancy_poc/multimodal_chat_robot/.idea/.gitignore b/src/reference/fancy_poc/multimodal_chat_robot/.idea/.gitignore new file mode 100644 index 000000000..26d33521a --- /dev/null +++ b/src/reference/fancy_poc/multimodal_chat_robot/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/src/reference/fancy_poc/multimodal_chat_robot/src/.idea/.gitignore b/src/reference/fancy_poc/multimodal_chat_robot/src/.idea/.gitignore new file mode 100644 index 000000000..26d33521a --- /dev/null +++ b/src/reference/fancy_poc/multimodal_chat_robot/src/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/src/reference/fancy_poc/multimodal_chat_robot/src/.idea/inspectionProfiles/Project_Default.xml b/src/reference/fancy_poc/multimodal_chat_robot/src/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 000000000..61b590853 --- /dev/null +++ b/src/reference/fancy_poc/multimodal_chat_robot/src/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,30 @@ + + + + \ No newline at end of file diff --git a/src/reference/fancy_poc/multimodal_chat_robot/src/.idea/inspectionProfiles/profiles_settings.xml b/src/reference/fancy_poc/multimodal_chat_robot/src/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 000000000..105ce2da2 --- /dev/null +++ b/src/reference/fancy_poc/multimodal_chat_robot/src/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/src/reference/fancy_poc/multimodal_chat_robot/src/.idea/misc.xml b/src/reference/fancy_poc/multimodal_chat_robot/src/.idea/misc.xml new file mode 100644 index 000000000..f6d3d8467 --- /dev/null +++ b/src/reference/fancy_poc/multimodal_chat_robot/src/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/reference/fancy_poc/multimodal_chat_robot/src/.idea/modules.xml b/src/reference/fancy_poc/multimodal_chat_robot/src/.idea/modules.xml new file mode 100644 index 000000000..f669a0e59 --- /dev/null +++ b/src/reference/fancy_poc/multimodal_chat_robot/src/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/reference/fancy_poc/multimodal_chat_robot/src/.idea/src.iml b/src/reference/fancy_poc/multimodal_chat_robot/src/.idea/src.iml new file mode 100644 index 000000000..8b8c39547 --- /dev/null +++ b/src/reference/fancy_poc/multimodal_chat_robot/src/.idea/src.iml @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/src/reference/fancy_poc/multimodal_chat_robot/src/.idea/vcs.xml b/src/reference/fancy_poc/multimodal_chat_robot/src/.idea/vcs.xml new file mode 100644 index 000000000..b2bdec2d7 --- /dev/null +++ b/src/reference/fancy_poc/multimodal_chat_robot/src/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/reference/fancy_poc/multimodal_chat_robot/src/multimodal_chat_robot_server/audio.wav b/src/reference/fancy_poc/multimodal_chat_robot/src/multimodal_chat_robot_server/audio.wav index 50f7387c5..6a9a140bd 100644 Binary files a/src/reference/fancy_poc/multimodal_chat_robot/src/multimodal_chat_robot_server/audio.wav and b/src/reference/fancy_poc/multimodal_chat_robot/src/multimodal_chat_robot_server/audio.wav differ diff --git a/src/reference/fancy_poc/multimodal_chat_robot/src/multimodal_chat_robot_server/bot/chat_gpt_bot_stream.py b/src/reference/fancy_poc/multimodal_chat_robot/src/multimodal_chat_robot_server/bot/chat_gpt_bot_stream.py index fcb396538..3788c9056 100644 --- a/src/reference/fancy_poc/multimodal_chat_robot/src/multimodal_chat_robot_server/bot/chat_gpt_bot_stream.py +++ b/src/reference/fancy_poc/multimodal_chat_robot/src/multimodal_chat_robot_server/bot/chat_gpt_bot_stream.py @@ -6,6 +6,8 @@ from utils import move_dict_with_role_to_penultimate import openai import time +import json + if conf().get('expires_in_seconds'): all_sessions = ExpiredDict(conf().get('expires_in_seconds')) else: @@ -108,8 +110,11 @@ def build_session_query(query, session_id): session = all_sessions.get(session_id, []) if len(session) == 0: system_prompt = conf().get("character_desc", "") - system_item = {'role': 'system', 'content': system_prompt} - session.append(system_item) + demos_or_presteps = open(conf().get("task_ana_file", ""), "r", encoding="utf-8").read() + messages = json.loads(demos_or_presteps) + messages.insert(0, {"role": "system", "content": system_prompt}) + for message in messages: + session.append(message) all_sessions[session_id] = session user_item = {'role': 'user', 'content': query} session.append(user_item) diff --git a/src/reference/fancy_poc/multimodal_chat_robot/src/multimodal_chat_robot_server/config.json b/src/reference/fancy_poc/multimodal_chat_robot/src/multimodal_chat_robot_server/config.json index fd30b2eea..d21295d83 100644 --- a/src/reference/fancy_poc/multimodal_chat_robot/src/multimodal_chat_robot_server/config.json +++ b/src/reference/fancy_poc/multimodal_chat_robot/src/multimodal_chat_robot_server/config.json @@ -1,7 +1,8 @@ { - "open_ai_api_key": "xxxxxxxxxxxxxxxxxxx", - "model": "gpt-3.5-turbo-16k-0613", + "open_ai_api_key": "xxxxxxxxxxxxxxxxxxxxxxxx", + "model": "gpt-3.5-turbo", "conversation_max_tokens": 16000, "expires_in_seconds": 3600, - "character_desc": "你是一个语言、绘画、音乐型AI机器人,你有绘画和创造音乐的能力,你可以通过生成指令来绘画任何图片。当user请你画画或者生成图片时,你只需要回答\"{i_g:绘画的主要内容的英文表达}\",图像生成程序会自动将其变为图片,因此User会将\"{i_g:绘画的主要内容的英文表达}\"当作一张图片。图片的英文表述需要从viewpoint、background、action、weather、light等摄影专业角度表示。当User对图片提出新的要求,你可以更新i_g:后面的内容满足User的要求。例如User说\"帮我画一只狗\",你需要回复\"{i_g:a dog, front view, lying down, looking at the camera, grassland background, rain, cool light}\"。\n当user请你生成音乐或歌曲时,你只需要回答\"{m_g:声音的主要内容的英文表达}\",声音生成程序会自动将其变为一段音频,因此User会将\"{m_g:声音的主要内容的英文表达}\"当作一段音乐或歌曲。音乐的英文表述需要从Melody, rhythm, instruments, timbre, dynamic change等音乐专业角度表示。当User对音乐或歌曲提出新的要求,你可以更新m_g:后面的内容满足User的要求。例如User说\"帮我创造一段悲伤的钢琴音乐\",你需要回复\"{m_g :piece of piano music, slow, bass-emphasized, smooth note connections, emotive tones, and soft dynamics}\"。\n当user没有生成声音或绘画的请求时,写诗不是绘画请求和生成音乐或歌曲请求,用轻松幽默的语气与用户聊天,并且不能出现{}符号,{}是调用图片生成程序或者声音生成程序的特殊符号。" + "character_desc": "你是一个语言、绘画、音乐型AI机器人,你有绘画和创造音乐的能力,你可以通过生成指令来绘画任何图片和制作音乐。\n当user请你生成音乐或歌曲时,你只需要回答\"{m_g:声音的主要内容的英文表达}\",声音生成程序会自动将其变为一段音频,因此User会将\"{m_g:声音的主要内容的英文表达}\"当作一段音乐或歌曲。音乐的英文表述需要从Melody, rhythm, instruments, timbre, dynamic change等音乐专业角度表示。当User对音乐或歌曲提出新的要求,你可以更新m_g:后面的内容满足User的要求。例如User说\"帮我创造一段悲伤的钢琴音乐\",你需要回复\"{m_g :piece of piano music, slow, bass-emphasized, smooth note connections, emotive tones, and soft dynamics}\"。当user请你画画或者生成图片时,你只需要回答\"{i_g:绘画的主要内容的英文表达}\",图像生成程序会自动将其变为图片,因此User会将\"{i_g:绘画的主要内容的英文表达}\"当作一张图片。图片的英文表述需要从viewpoint、background、action、weather、light等摄影专业角度表示。当User对图片提出新的要求,你可以更新i_g:后面的内容满足User的要求。例如User说\"帮我画一只狗\",你需要回复\"{i_g:a dog, front view, lying down, looking at the camera, grassland background, rain, cool light}\"。\n当user没有生成声音或绘画的请求时,写诗不是绘画请求和生成音乐或歌曲请求,用轻松幽默的语气与用户聊天,并且不能出现{}符号,{}是调用图片生成程序或者声音生成程序的特殊符号。", + "task_ana_file": "demo_parse_task.json" } diff --git a/src/reference/fancy_poc/multimodal_chat_robot/src/multimodal_chat_robot_server/demo_parse_task.json b/src/reference/fancy_poc/multimodal_chat_robot/src/multimodal_chat_robot_server/demo_parse_task.json new file mode 100644 index 000000000..894dec034 --- /dev/null +++ b/src/reference/fancy_poc/multimodal_chat_robot/src/multimodal_chat_robot_server/demo_parse_task.json @@ -0,0 +1,28 @@ +[ + { + "role": "user", + "content": "你好" + }, + { + "role": "assistant", + "content": "你好,请问有什么可以帮您" + }, + + { + "role":"user", + "content":"帮我生成一首钢琴曲。" + }, + { + "role": "assistant", + "content": "{m_g:piece of piano music, melodic, moderate tempo, with a mix of major and minor chords, expressive dynamics, and smooth transitions between notes. The melody is emotionally evocative, creating a sense of nostalgia and introspection.} \\n希望你会喜欢这首钢琴曲!'}" + }, + { + "role": "user", + "content": "帮我画一只浣熊在洗澡" + }, + { + "role": "assistant", + "content": "{i_g: A raccoon taking a bath, sitting in a small wooden tub filled with water. The raccoon is using its paws to scrub its fur, with water splashing around. The background is a cozy bathroom with tiles on the walls and a window letting in soft sunlight. The lighting is warm and the atmosphere is relaxed.}\\n希望你会喜欢这幅画!" + } + +] \ No newline at end of file diff --git a/src/reference/fancy_poc/multimodal_chat_robot/src/multimodal_chat_robot_server/image.jpg b/src/reference/fancy_poc/multimodal_chat_robot/src/multimodal_chat_robot_server/image.jpg index 5c5e3eb6b..45213de41 100644 Binary files a/src/reference/fancy_poc/multimodal_chat_robot/src/multimodal_chat_robot_server/image.jpg and b/src/reference/fancy_poc/multimodal_chat_robot/src/multimodal_chat_robot_server/image.jpg differ diff --git a/src/reference/fancy_poc/version b/src/reference/fancy_poc/version index 3a6a8d03e..89a6e74b5 100644 --- a/src/reference/fancy_poc/version +++ b/src/reference/fancy_poc/version @@ -1 +1 @@ -v1.1 +v1.2 diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index aae67a469..980ffb502 100755 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -45,15 +45,15 @@ RUN apt-get clean all && \ # local build flag RUN echo "False" > /tmp/.flag -RUN wget -P /tmp/ "https://ai.b-bug.org/k230/downloads/aitest/aitest-0.0.2.dev20230625-py3-none-any.whl" || echo "True" > /tmp/.flag +RUN wget -P /tmp/ "https://ai.b-bug.org/k230/downloads/aitest/aitest-0.0.3.dev20230717-py3-none-any.whl" || echo "True" > /tmp/.flag # config pip local source -RUN FLAG=$(cat /tmp/.flag) && if [ "$FLAG" = "False" ]; then echo \ +RUN echo \ '[global]\n\ timeout = 60\n\ index-url = https://pypi.tuna.tsinghua.edu.cn/simple\n\ extra-index-url = https://mirrors.aliyun.com/pypi/simple/ https://mirrors.cloud.tencent.com/pypi/simple\n\ - ' > /etc/pip.conf; cat /etc/pip.conf; else echo "Skip config pip source"; fi + ' > /etc/pip.conf; cat /etc/pip.conf # install pip software RUN python3 -m pip install -U pyyaml pycryptodome gmssl \ diff --git a/tools/ota/ota_upgrade.sh b/tools/ota/ota_upgrade.sh index c2756f811..b7a2e3de6 100755 --- a/tools/ota/ota_upgrade.sh +++ b/tools/ota/ota_upgrade.sh @@ -22,13 +22,14 @@ if [ $1 -eq 0 ]; then rm $data_dir/ota_package -rf elif [ $1 -eq 1 ]; then + echo "start unzip ota_package" cd $data_dir rm $data_dir/ota_package.bin -rf unzip $data_dir/ota_package.zip - if [ $? -ne 0 ]; then - echo "decompress ota_package.zip fail" - exit 1 - fi + # if [ $? -ne 0 ]; then + # echo "decompress ota_package.zip fail" + # exit 1 + # fi echo "decompress ota_package.zip success" rm $data_dir/ota_package.zip -rf @@ -63,35 +64,35 @@ elif [ $1 -eq 1 ]; then flash_erase /dev/mtd1 0 0 dd if=u-boot.img of=/dev/mtd1 fi - if [ -f fh_quick_boot.bin ]; then - echo "fh_quick_boot.bin" + if [ -f fn_ug_quick_boot.bin ]; then + echo "fn_ug_quick_boot.bin" flash_erase /dev/mtd2 0 0 - dd if=fh_quick_boot.bin of=/dev/mtd2 + dd if=fn_ug_quick_boot.bin of=/dev/mtd2 fi - if [ -f fh_face_data.bin ]; then + if [ -f fn_ug_face_data.bin ]; then echo "fh_face_data.bin" flash_erase /dev/mtd3 0 0 - dd if=fh_face_data.bin of=/dev/mtd3 + dd if=fn_ug_face_data.bin of=/dev/mtd3 fi - if [ -f fh_sensor_cfg.bin ]; then - echo "fh_sensor_cfg.bin" + if [ -f fn_ug_sensor_cfg.bin ]; then + echo "fn_ug_sensor_cfg.bin" flash_erase /dev/mtd4 0 0 - dd if=fh_sensor_cfg.bin of=/dev/mtd4 + dd if=fn_ug_sensor_cfg.bin of=/dev/mtd4 fi - if [ -f fh_speckle.bin ]; then - echo "fh_speckle.bin" + if [ -f fn_ug_speckle.bin ]; then + echo "fn_ug_speckle.bin" flash_erase /dev/mtd5 0 0 - dd if=fh_speckle.bin of=/dev/mtd5 + dd if=fn_ug_speckle.bin of=/dev/mtd5 fi if [ -f rtt_system.bin ]; then echo "rtt_system.bin" - flash_erase /dev/mtd6 0 0 - dd if=rtt_system.bin of=/dev/mtd6 - fi - if [ -f fh_fastboot_app.elf ]; then - echo "fh_fastboot_app.elf" flash_erase /dev/mtd7 0 0 - dd if=fh_fastboot_app.elf of=/dev/mtd7 + dd if=rtt_system.bin of=/dev/mtd7 + fi + if [ -f fn_ug_fastboot_app.elf ]; then + echo "ffn_ug_fastboot_app.elf" + flash_erase /dev/mtd6 0 0 + dd if=fn_ug_fastboot_app.elf of=/dev/mtd6 fi if [ -f linux_system.bin ]; then echo "linux_system.bin" diff --git a/tools/release_github.sh b/tools/release_github.sh index 60c0487d8..94bfec931 100755 --- a/tools/release_github.sh +++ b/tools/release_github.sh @@ -19,6 +19,8 @@ sensor|\ connector|\ lib|\ fft|\ +pm|\ +mediafreq|\ Makefile|\ rt-smart.mk|\ mpp.mk\ @@ -29,6 +31,7 @@ cipher|\ sensor|\ connector|\ fft|\ +pm|\ Makefile|\ rt-smart.mk|\ mpp.mk\ @@ -39,6 +42,7 @@ k_ioctl.h|\ k_sensor_ioctl.h|\ k_connector_ioctl.h|\ k_fft_ioctl.h|\ +k_pm_ioctl.h|\ )" delete_cdk_user_name_list="\